-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
player.py
92 lines (74 loc) · 2.94 KB
/
player.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import sys
import time
import threading
import subprocess
from enum import Enum, auto
class PlayerType(Enum):
HUMAN = auto()
ENGINE = auto()
class Player:
"""
A class for the player in a game, it stores all the configuration for the
player, including settings for an engine, the color it is using, etc.
"""
def __init__ (self, type, mm_depth, q_depth, time_limit):
self.type = type
self.color = None
self.nodes_searched = 0
self.mm_depth = mm_depth
self.q_depth = q_depth
self.time_limit = time_limit
def assign_color(self, color):
"""
Assuming the given color input is valid.
"""
self.color = color
def spinner(self):
while not task_done:
for symbol in ['/', '|', '\\', '-']:
sys.stdout.write('\rsilkfish is thinking ' + symbol)
sys.stdout.flush()
time.sleep(0.2)
def run_engine(self, command):
global output
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
output = result.stdout
def get_move(self, board):
"""
Returns:
chess.Move: A move to be made given the board.
"""
if self.type == PlayerType.HUMAN:
while True:
user_input = input("Enter your move in SAN format (e.g. Nf3): ")
# Try to parse the input move
try:
move = board.parse_san(user_input) # Parse Standard Algebraic Notation (SAN)
except ValueError:
print("Invalid move format. Please try again.")
continue
# Check if the move is legal
if move in board.legal_moves:
return move
else:
print("Illegal move. Please try again.")
elif self.type == PlayerType.ENGINE:
command = ['./silkfish', '-md', str(self.mm_depth), '-qd', str(self.q_depth), '-t', str(self.time_limit), '-fen', board.fen()]
global task_done, output
task_done = False
output = None
spinner_thread = threading.Thread(target=self.spinner)
spinner_thread.start()
run_engine_thread = threading.Thread(target=self.run_engine, args=(command,))
run_engine_thread.start()
run_engine_thread.join()
task_done = True
spinner_thread.join()
sys.stdout.write('\r' + ' ' * 10 + '\r')
sys.stdout.flush()
best_move = output.strip().split('\n')[-1]
print(f"silkfish with minimax depth {self.mm_depth} Q depth {self.q_depth} time limit {self.time_limit}s makes move: {best_move}")
move = board.parse_san(best_move)
return move
else:
raise ValueError("Error: Player type invalid.")