various fixes - #1
Open
dcolazin wants to merge 2 commits into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
In this PR I collected several fixes required for my usage on Linux.
Bug 1 — No
bestmoveoutput when there is no mate solutionProblem: The UCI protocol requires that every
gocommand be answered with exactly onebestmoveline. When chest reportedNo Solution,extract_bestmove()printed nothing, hanging the GUI.Root cause: The
bestmovebuffer stayed empty because the move-parsing loop was guarded byif (mate > 0)and the final print was conditional onbestmove[0]being non-null.Resolution:
parse_refu_move()helper that extracts the first legal move from chest'srefu(refutation) lines — the moves that refute the mate attempt are valid legal moves.check_no_solution()triggers, the code now scans all lines for arefuentry and uses the first refutation move as thebestmove.bestmovewas found (either from the solution or from a refutation) it is printed; otherwise the code emitsbestmove 0000(the UCI null-move), guaranteeing a response in all cases.bestmove 0000is emitted immediately.Bug 2 —
backendsetoption truncates the last character of the pathProblem: Setting the backend path via
setoption name backend value ./dchestcorrupted the path. Two separate defects combined to eat characters:v += 7skipped one character too many (should have beenv += 6), and an unconditionaldchest[strlen(dchest) - 1] = '\0'stripped a valid trailing character under the incorrect assumption that a"quote was present.Resolution:
setoptionhandling block was rewritten into a unified parser that accepts both the full UCI form (setoption name <key> value <val>) and a short form (setoption <key> <val>).valuekeyword offset is now correct (exactly 6 characters consumed after detection)."is removed only if one is actually present, and a leading"is removed only if one is present. Unquoted values (the normal UCI case) pass through untouched.Bug 3 —
position startposis not handledProblem: The adapter only handled
position fen .... When a GUI sentposition startposorposition startpos moves ..., the internal FEN buffer was left empty, producing garbage output from chest.Resolution:
START_FENconstant (rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1).!strncmp(line, "position startpos", 17)) setscurrent_fentoSTART_FENbefore the existingposition fenhandler, so the standard starting position is used.Bug 4 —
parse_chest_moveproduces malformed UCI movesProblem: The original parser naively stripped the first uppercase letter and kept every remaining alphanumeric character. This mangled captures (
Qxg6→xg6), promotions (e8=Q→e8Q), and castling (O-O→O). The only formats that happened to work were the spaced/colon-separated notations (Ra1 - a8,Rf6 : f7).Resolution:
The function was completely rewritten with a multi-step pipeline:
-,:), and check/mate suffixes (+,#) removed.Oor0, theO-count determines kingside (OO→e1g1) or queenside (OOO→e1c1).O) is skipped.=is found, the following piece letter is captured and lowercased as a UCI promotion suffix.xorXcharacters are removed.Bug 5 —
gowithoutdepthis not handledProblem: Only
go depth Nwas recognised. Any othergovariant (go movetime 1000,go wtime 5000 btime 5000, barego) was silently ignored, hanging the GUI.Resolution:
go.depthsubstring; if found, the depth value is extracted as before.3is used.write_chest_input()andrun_chest()are called, so the engine always responds.Bug 6 — Dead variable
bestmoveinmain()Problem: A
char bestmove[32]local inmain()was never used (the real best-move logic lives inextract_bestmove()). It generated a compiler warning under-Wall -Wextra.Resolution: The declaration was removed.
Bug 7 — Fragile
fpos_tfile positioningProblem: The original two-pass approach used
fpos_t/fgetpos/fsetposto save and restore the file stream position. This was fragile:fpos_tis an opaque type, the initial= 0initializer caused a compilation error on glibc (see Bug 8 below), andfsetposwas called unconditionally — potentially on an uninitializedsetPointwhen no mate solution was found.Resolution:
lines_buf) usingstrdup().fpos_t/fgetpos/fsetposusage.extract_bestmove().Bug 8 — Compilation error: invalid
fpos_tinitializerProblem:
fpos_t setPoint = 0;failed to compile withgcc -O2becausefpos_tis an opaque type (a struct under glibc with large-file support) and cannot be initialized with an integer literal.Resolution: As part of the Bug 7 refactor, the
fpos_tvariable and all associated calls were removed entirely, resolving the compilation error at its source.Bug 9 — Unchecked
system()return valueProblem:
system(cmd)discarded its return value, triggering awarn_unused_resultwarning on glibc and making it impossible to detect a failed backend launch.Resolution: The return value is now checked; on failure a
Warning: failed to run chest commandmessage is printed tostderr.Additional Improvement —
stdinredirection fordchestChange: The
run_chest()command was changed from"%s %s > %s"to"%s %s < /dev/null > %s".Rationale: Redirecting
stdinfrom/dev/nullpreventsdchestfrom accidentally reading from the UCI adapter's input stream, which could consume UCI protocol commands intended forchest_uci.Additional Improvement — Selfmate / helpmate score negation
Change: When
job_typeiss(selfmate) orh(helpmate), thescore matevalue reported in theinfoline is negated.Rationale: In these problem types the side to move is the one being mated, not delivering mate. Without negation, GUIs like ChessX would display a selfmate solution as if it were a direct mate. A negative mate score correctly communicates "the side to move will be mated in N."
Additional Improvement — Default
job_typeChange:
job_typewas changed from an empty string ("") to"o"(orthodox).Rationale: Ensures a sane default when no
setoption name jobcommand has been received, sodchestoperates in standard direct-mate mode out of the box.