-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathminimax.py
53 lines (50 loc) · 2.02 KB
/
minimax.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
from typing import Optional
from evaluation_function import evaluation_function
from valid_moves import valid_move
from utils import execute_move
from utils import is_game_finished
from config import INFINITY
def child(board: list[str], move: str) -> list[str]:
new_board = board.copy()
execute_move(new_board, move)
return new_board
def generate_possible_moves(board: list[str], to_move: str) -> set[str]:
pieces = "KQRNBP" if to_move == 'white' else "kqrnbp"
possible_moves: set[str] = set()
for piece in board:
if piece in pieces:
for position in range(16):
if valid_move(board, f"{piece}{position}"):
possible_moves.add(f"{piece}{position}")
return possible_moves
def minimax(board: list[str], depth: int, alpha: int, beta: int,
to_move: str) -> tuple[int, Optional[str]]:
if depth == 0 or is_game_finished(board):
result = evaluation_function(board, depth), None
else:
best_move = None
if to_move == 'white':
max_eval = -INFINITY
for move in generate_possible_moves(board, to_move):
new_board = child(board, move)
evaluation, _ = minimax(new_board, depth - 1, alpha, beta, 'black')
if evaluation > max_eval:
max_eval = evaluation
best_move = move
alpha = max(alpha, evaluation)
if beta <= alpha:
break
result = max_eval, best_move
else:
min_eval = INFINITY
for move in generate_possible_moves(board, to_move):
new_board = child(board, move)
evaluation, _ = minimax(new_board, depth - 1, alpha, beta, 'white')
if evaluation < min_eval:
min_eval = evaluation
best_move = move
beta = min(beta, evaluation)
if beta <= alpha:
break
result = min_eval, best_move
return result