-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtic_tac_toe_minimax.py
88 lines (74 loc) · 2.73 KB
/
tic_tac_toe_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
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
from tic_tac_toe_model import TicTacToeModel
import random
moves_cache = dict()
def get_next_move(player, model):
""" User facing function to get the next recommended
move by the minimax algorithm based on the given
model
Args:
player (int): the player whose moves are being evaluated
model (TicTacToeModel): the model to evaluate
Returns:
(int, int): the recommended move to make
"""
if model.board_size >= 5 and len(model) < model.board_size * 2 - 3:
return random.choice(list(model.remaining_moves))
highest_score = -2
highest_move = None
moves = model.remaining_moves.copy()
for move_option in moves:
model.make_move(move_option, player)
model.check_winner(move_option)
option_score = minimax(model, player, False, alpha=-2, beta=2)
model.undo_move()
if option_score > highest_score:
highest_score = option_score
highest_move = move_option
return highest_move
def minimax(model, our_player, maximizing, alpha, beta):
""" Minimax function to calculate the optimal
move to make
Args:
model (TicTacToeModel): the model to evaluate
our_player (int): the player whose role minimax is replacing
maximizing (bool): whether or not this is a mazimizing step
alpha (int): the current alpha
beta (beta): the current beta
Returns:
int: the best possible score for the given state of the model
"""
situation_str = str(model.board) + str(our_player) + \
str(maximizing) + str(alpha) + str(beta)
if situation_str in moves_cache:
return moves_cache[situation_str]
if model.winner is not None:
return 1 if model.winner == our_player else -1
elif model.filled():
return 0
highest_score = -2
highest_move = None
lowest_score = 2
lowest_move = None
moves = model.remaining_moves.copy()
for move_option in moves:
model.make_move(move_option, model.current_player)
model.check_winner(move_option)
option_score = minimax(model, our_player, not maximizing, alpha, beta)
if option_score > highest_score:
highest_score = option_score
highest_move = move_option
if option_score < lowest_score:
lowest_score = option_score
lowest_move = move_option
model.undo_move()
if maximizing:
alpha = max(highest_score, alpha)
if beta <= alpha:
break
else:
beta = min(lowest_score, beta)
if(beta <= alpha):
break
result = highest_score if maximizing else lowest_score
moves_cache[situation_str] = result
return result