-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathminimax.py
125 lines (94 loc) · 3.22 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
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
from board import Board
def evaluate(state):
node = Node(state)
score = 0
x = len(node.x_pos)
o = len(node.o_pos)
if o == 0: # winning
score += 1000
if x == 0: # losing
score -= 1000
score += 13*(x - o) # jumping
for x in node.x_pos: # how far down the board AI is
letter, number = node.to_index(node.to_letter_number(x))
if node.state[x] == "x":
score += 2*number
elif node.state[x] == "X":
score += 10
if x in node.unjumpable and node.state[x] == 'x': # edge piece
score += 5
for o in node.o_pos: # how far opponent is up the board
letter, number = node.to_index(node.to_letter_number(o))
if node.state[o] == "o":
score -= 2 * (7 - number)
elif node.state[o] == "O":
score -= 10
if o in node.unjumpable and node.state[o] == 'o': # edge piece
score -= 5
return score
def MiniMax(game, depth, isMaximissingPlayer):
bestBoard = game
if depth == 0:
return evaluate(game.state), bestBoard
possible_boards = list_possible_boards(game.state, isMaximissingPlayer)
if isMaximissingPlayer:
bestMove = -9999
for i in range(len(possible_boards)):
oldMove = bestMove
bestMove = max([
bestMove,
MiniMax(Node(possible_boards[i]), depth-1, False)[0]
])
if bestMove != oldMove:
bestBoard = Node(possible_boards[i])
else:
bestMove = 9999
for i in range(len(possible_boards)):
bestMove = min([bestMove, MiniMax(
Node(possible_boards[i]), depth-1, True)[0]])
return bestMove, bestBoard
class Node(Board):
def __init__(self, state):
self.state = state
self.unjumpable = [0, 1, 2, 3, 4, 11, 12, 19, 20, 27, 28, 29, 30, 31]
self.x_pos = []
self.o_pos = []
for i in range(len(self.state)):
if self.state[i].lower() == 'x':
self.x_pos.append(i)
elif self.state[i].lower() == 'o':
self.o_pos.append(i)
def print_board(b):
top = '\n a b c d e f g h\n'
for i in range(8):
top += ' ' + '-'*33 + '\n%s ' % (i+1)
for spot in b[i*4:i*4+4]:
if i % 2 == 0:
top += '| | %s ' % spot
else:
top += '| %s | ' % spot
top += '|\n'
top += ' ' + '-'*33 + '\n'
print top
def list_possible_boards(state, isMaximissingPlayer):
possible_boards = []
game = Node(state[:])
if isMaximissingPlayer:
spots = game.x_pos
else:
spots = game.o_pos
for spot in spots:
for direction in game.list_possible_indexes(game.to_letter_number(spot)):
possible = Node(game.state[:])
loc = game.to_letter_number(spot)
new_loc = game.to_letter_number(direction)
possible.move(loc, new_loc)
possible_boards.append(possible.state)
# for b in possible_boards:
# print_board(b)
return possible_boards
# b = Board()
# print b
# best = MiniMax(b, 3, True, b.state)
# print "best move ", best[0]
# print_board(best[1])