Implement nim-noise support to improve mixed mode experience (bench 6295424)

This commit is contained in:
2025-12-01 13:18:20 +01:00
parent a08864afdb
commit c3222800c8
4 changed files with 63 additions and 10 deletions

View File

@@ -54,7 +54,8 @@ CUSTOM_FLAGS := -d:outputBuckets=$(OUTPUT_BUCKETS) \
-d:patchVersion=$(PATCH_VERSION) \
-d:evalFile=$(EVALFILE) \
-d:netID=$(NET_ID) \
-d:thpPageAlignment:$(THP_PAGE_ALIGNMENT)
-d:thpPageAlignment:$(THP_PAGE_ALIGNMENT) \
-d:esc_exit_editing
ifeq ($(MERGED_KINGS),1)
CUSTOM_FLAGS += -d:mergedKings=true

View File

@@ -110,11 +110,13 @@ is possible to specify the location of both Heimdall and Stockfish (run `python
## Configuration
Heimdall is a UCI engine, which means that it's not meant to be used as a standalone program (although you can do that, as it defaults
to a pretty-printed output unless the environment variable `NO_COLOR` is set or it detects that it's not attached to a TTY). To use it at
its best, you can add it to any number of chess GUIs like Arena, En Croissant or Cutechess. I strive to have Heimdall work flawlessly with
Heimdall implements the [UCI](https://en.wikipedia.org/wiki/Universal_Chess_Interface) protocol to communicate with chess GUIs and other programs.
To use it at its best, you can add it to any number of chess GUIs like Arena, En Croissant or Cutechess. I strive to have Heimdall work flawlessly with
any GUI (within reason), so please let me know if you find any issues!
If you prefer to use it from the command line, there is a fairly advanced user interface supporting colored output, command history, line editing
and much more, powered by [nim-noise](https://github.com/jangko/nim-noise) (for all keyboard bindings see [here](https://github.com/jangko/nim-noise?tab=readme-ov-file#key-binding))
Heimdall supports the following UCI options:
- `HClear`: Clears all history tables. This is done automatically at every new game, so you shouldn't need to do this normally

View File

@@ -20,3 +20,5 @@ requires "struct == 0.2.3"
requires "https://github.com/demotomohiro/pathX == 0.1"
requires "struct == 0.2.3"
requires "nimsimd == 1.2.13"
requires "noise >= 0.1.10"

View File

@@ -18,9 +18,11 @@ import heimdall/[board, search, movegen, transpositions, pieces as pcs, eval, nn
import heimdall/util/[perft, limits, tunables, scharnagl, help, wdl, eval_stats]
import heimdall/util/memory/aligned
import std/[os, math, times, random, atomics, options, terminal, strutils, strformat, sequtils, parseutils]
import std/[os, math, times, random, atomics, options, terminal, strutils, strformat, sequtils, parseutils, exitprocs]
from std/lenientops import `/`
import noise
randomize()
@@ -854,17 +856,63 @@ proc startUCISession* =
let isTTY = isatty(stdout)
if not isTTY or getEnv("NO_TUI").len() != 0:
session.isMixedMode = false
let noColor = getEnv("NO_COLOR").len() != 0
if not isTTY or getEnv("NO_COLOR").len() != 0:
if isTTY and not noColor:
enableTrueColors()
addExitProc(disableTrueColors)
addExitProc(proc () = stdout.resetAttributes())
if not isTTY or noColor:
session.searcher.setUCIMode(true)
else:
printLogo()
var noise = Noise.init()
let prompt = block:
if noColor:
Styler.init("cmd> ")
else:
Styler.init(fgYellow, "cmd> ")
noise.setPrompt(prompt)
while true:
try:
if session.isMixedMode and (not session.searcher.isSearching() or session.minimal):
stdout.write("cmd> ")
cmdStr = readLine(stdin).strip(leading=true, trailing=true, chars={'\t', ' '})
let smartPrompt = session.isMixedMode and (not session.searcher.isSearching() or session.minimal)
if smartPrompt:
var ok = noise.readLine()
if not ok:
raise newException(IOError, "")
if noise.getKeyType == ktEsc:
let exitPrompt = block:
if noColor:
Styler.init("Are you sure you want to exit (press enter to confirm)? [Y/n] ")
else:
Styler.init(fgGreen, "Are you sure you want to exit? (press enter to confirm)", resetStyle, styleDim, " [Y/n] ")
stdout.flushFile()
noise.setPrompt(exitPrompt)
ok = noise.readLine()
if not ok:
raise newException(IOError, "")
if noise.getLine().toLowerAscii() notin ["n", "no", "nope", "nyet", "nein", "non"]: # lul
quit(0)
noise.setPrompt(prompt)
continue
cmdStr = noise.getLine()
else:
cmdStr = readLine(stdin)
if smartPrompt:
noise.historyAdd(cmdStr)
cmdStr = cmdStr.strip(leading=true, trailing=true, chars={'\t', ' '})
if cmdStr.len() == 0:
if session.debug:
echo "info string received empty input, ignoring it"
@@ -1180,7 +1228,7 @@ proc startUCISession* =
echo &"Invalid hash table size '{cmd.value}'"
continue
newSize = size.uint64 div 1048576
echo &"Note: '{cmd.value}' parsed to {newSize} MiB"
echo &"Note: '{cmd.value}' interpreted to {newSize} MiB"
if newSize notin 1'u64..33554432'u64:
echo &"Erorr: selected hash table size is too big (n must be in 1 <= n <= 33554432 MiB)"
continue