added probabilistic stockfish simulation to engine
This commit is contained in:
46
engine.py
46
engine.py
@@ -1,6 +1,9 @@
|
|||||||
import chess
|
import chess
|
||||||
import chess.engine
|
import chess.engine
|
||||||
import random
|
import random
|
||||||
|
import eval
|
||||||
|
import numpy as np
|
||||||
|
from stockfish import Stockfish
|
||||||
|
|
||||||
|
|
||||||
def pick_move(board: chess.Board) -> chess.Move | None:
|
def pick_move(board: chess.Board) -> chess.Move | None:
|
||||||
@@ -32,3 +35,46 @@ def simulate_game(board: chess.Board, move: chess.Move, depth: int):
|
|||||||
board.push(r.move)
|
board.push(r.move)
|
||||||
|
|
||||||
engine.quit()
|
engine.quit()
|
||||||
|
|
||||||
|
|
||||||
|
def simulate_stockfish_prob(board: chess.Board, move: chess.Move, games: int = 10, depth: int = 10) -> (float, float):
|
||||||
|
"""
|
||||||
|
Simulate a game using
|
||||||
|
:param board: chess board
|
||||||
|
:param move: chosen move
|
||||||
|
:param games: number of games that should be simulated after playing the move
|
||||||
|
:param depth: simulation depth per game
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
board.push(move)
|
||||||
|
copied_board = board.copy()
|
||||||
|
scores = []
|
||||||
|
|
||||||
|
stockfish = Stockfish("./stockfish/stockfish-ubuntu-x86-64-avx2", depth=2, parameters={"Threads": 8, "Hash": 2048})
|
||||||
|
stockfish.set_elo_rating(1200)
|
||||||
|
stockfish.set_fen_position(board.fen())
|
||||||
|
|
||||||
|
def reset_game():
|
||||||
|
nonlocal scores, copied_board, board
|
||||||
|
score = eval.score_stockfish(copied_board).white().score(mate_score=100_000)
|
||||||
|
scores.append(score)
|
||||||
|
copied_board = board.copy()
|
||||||
|
stockfish.set_fen_position(board.fen())
|
||||||
|
|
||||||
|
for _ in range(games):
|
||||||
|
for d in range(depth):
|
||||||
|
if copied_board.is_game_over() or d == depth - 1:
|
||||||
|
reset_game()
|
||||||
|
break
|
||||||
|
|
||||||
|
if d == depth - 1:
|
||||||
|
reset_game()
|
||||||
|
|
||||||
|
top_moves = stockfish.get_top_moves(3)
|
||||||
|
chosen_move = random.choice(top_moves)['Move']
|
||||||
|
stockfish.make_moves_from_current_position([chosen_move])
|
||||||
|
copied_board.push(chess.Move.from_uci(chosen_move))
|
||||||
|
|
||||||
|
print(scores)
|
||||||
|
# TODO: return distribution here?
|
||||||
|
return np.array(scores).mean(), np.array(scores).std()
|
||||||
|
|||||||
16
main.py
16
main.py
@@ -29,6 +29,21 @@ def test_stockfish():
|
|||||||
analyze_results(sorted_moves)
|
analyze_results(sorted_moves)
|
||||||
|
|
||||||
|
|
||||||
|
def test_stockfish_prob():
|
||||||
|
fools_mate = "rnbqkbnr/pppp1ppp/4p3/8/5PP1/8/PPPPP2P/RNBQKBNR b KQkq f3 0 2"
|
||||||
|
board = chess.Board(fools_mate)
|
||||||
|
moves = {}
|
||||||
|
untried_moves = list(board.legal_moves)
|
||||||
|
for move in untried_moves:
|
||||||
|
mean, std = engine.simulate_stockfish_prob(board, move, 10, 4)
|
||||||
|
moves[move] = (mean, std)
|
||||||
|
board = chess.Board(fools_mate)
|
||||||
|
|
||||||
|
sorted_moves = dict(sorted(moves.items(), key=lambda x: x[0].uci()))
|
||||||
|
for m, s in sorted_moves.items():
|
||||||
|
print(f"move '{m.uci()}' (prob_stockfish): mean={s[0]}, std={s[1]}")
|
||||||
|
|
||||||
|
|
||||||
def analyze_results(moves: dict):
|
def analyze_results(moves: dict):
|
||||||
for m, b in moves.items():
|
for m, b in moves.items():
|
||||||
manual_score = eval.score_manual(b)
|
manual_score = eval.score_manual(b)
|
||||||
@@ -39,6 +54,7 @@ def analyze_results(moves: dict):
|
|||||||
def main():
|
def main():
|
||||||
test_mcts()
|
test_mcts()
|
||||||
test_stockfish()
|
test_stockfish()
|
||||||
|
test_stockfish_prob()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
chess==1.10.0
|
chess==1.10.0
|
||||||
numpy==1.26.3
|
numpy==1.26.3
|
||||||
|
stockfish==3.28.0
|
||||||
Reference in New Issue
Block a user