stockfish for godot
| -rw-r--r-- | addons/stockfish.gd/package.json | 2 | ||||
| -rw-r--r-- | addons/stockfish.gd/stockfish_wrapper.gd | 62 |
2 files changed, 59 insertions, 5 deletions
diff --git a/addons/stockfish.gd/package.json b/addons/stockfish.gd/package.json index 44bc690..75d12a8 100644 --- a/addons/stockfish.gd/package.json +++ b/addons/stockfish.gd/package.json @@ -1,6 +1,6 @@ { "name": "@bendn/stockfish.gd", - "version": "2.0.0", + "version": "2.1.2", "description": "godot stockfish", "main": "stockfish_loader.gd", "scripts": { diff --git a/addons/stockfish.gd/stockfish_wrapper.gd b/addons/stockfish.gd/stockfish_wrapper.gd index 0c94096..5591495 100644 --- a/addons/stockfish.gd/stockfish_wrapper.gd +++ b/addons/stockfish.gd/stockfish_wrapper.gd @@ -1,4 +1,3 @@ - class_name Stockfish extends Reference @@ -12,6 +11,7 @@ signal engine_ready signal line_recieved signal load_failed signal bestmove +signal info func send_line(cmd: String) -> void: if not engine_ready: @@ -28,7 +28,8 @@ func _init() -> void: connect("line_recieved", self, "_line_recieved") connect("engine_ready", self, "_engine_ready") -func dbg_prints(a1 := "", a2 := "") -> void: + +func dbg_prints(a1 = "", a2 = "") -> void: if OS.is_debug_build(): prints(a1, a2) @@ -54,12 +55,16 @@ func _position(): func _line_recieved(line: String) -> void: if line.begins_with("info "): - dbg_prints("(stockfish)", line) + emit_signal("info", parse_info(line.split(" ", true, 1)[1])) elif searching_bestmove and line.begins_with("bestmove "): searching_bestmove = false parse_bestmove(line.split(" ", true, 1)[1]) - elif (sent_isready) && (line == "readyok" || line.begins_with("Stockfish [commit: ")): + elif ( + (sent_isready) + && (line == "readyok" || (OS.has_feature("JavaScript") && line.begins_with("Stockfish [commit: "))) + ): sent_isready = false + print("ENGINE READY") emit_signal("engine_ready") else: push_error("unexpected output: %s" % line) @@ -73,6 +78,55 @@ func parse_bestmove(args: String) -> void: return emit_signal("bestmove", null) + +# given a string like +# depth 18 seldepth 21 multipv 1 score cp 74 nodes 351592 nps 267167 hashfull 147 tbhits 0 time 1316 pv e2e4 c7c5 g1f3 d7d6 d2d4 c5d4 f3d4 g8f6 b1c3 e7e5 d4b3 c8e6 c1g5 f8e7 f1b5 b8c6 g5f6 e7f6 +# it will produce a dictionary: +# ```json +# { +# "depth": 18, +# "seldepth": 21, +# "multipv": 1, +# "score": { "cp": 74 }, +# "nodes": 351592, +# "nps": 267167, +# "hashfull": 147, +# "tbhits": 0, +# "time":1.316, +# "pv": ["e2e4", "c7c5", "g1f3", "d7d6", "d2d4", "c5d4", "f3d4", "g8f6", "b1c3", "e7e5", "d4b3", "c8e6", "c1g5", "f8e7", "f1b5", "b8c6", "g5f6", "e7f6"] +# } +# ``` +func parse_info(args: String) -> Dictionary: + var tokens := Array(args.split(" ")) + var info := {} + + while !tokens.empty(): + var parameter: String = tokens.pop_front() + + if parameter == "string": + info["string"] = " ".join(tokens) + break + elif parameter in ["depth", "seldepth", "nodes", "multipv", "currmovenumber", "hashfull", "nps", "tbhits"]: + info[parameter] = int(tokens.pop_front()) # type: ignore + elif parameter == "time": + info["time"] = int(tokens.pop_front()) / 1000.0 + elif parameter == "score": + # cp 74 -> + # kind: cp + # value: 74 + var kind: String = tokens.pop_front() + var value := int(tokens.pop_front()) + if kind == "cp": + info["score"] = {cp = value} + elif kind == "mate": + info["score"] = {mate = value} + elif parameter == "currmove": + info["currmove"] = game.__move_to_san(game.__move_from_uci(tokens.pop_front())) + elif parameter == "pv": + var pv: PoolStringArray = tokens.slice(0, len(tokens)) + info["pv"] = pv + return info + func go(depth: int = 15) -> void: if searching_bestmove: push_error("already searching. did you mean `stop()`?") |