-
Notifications
You must be signed in to change notification settings - Fork 0
/
gomoku.py
165 lines (147 loc) · 5.56 KB
/
gomoku.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
from boardstate import *
class Gomoku():
global testing
testing = TESTVAL
def __init__(self):
self.current_state = BoardState()
self.initial = self.current_state
def display(self, boardstate):
"Print out the board in a readable way."
print(" ",end='')
for i in range (SIZE):
print (str(i)," ",end='')
print()
for i in range(SIZE):
for j in range(SIZE):
if boardstate._board[i][j] == Piece.EMPTY:
print('[ ]',' ',end='')
else:
piece = 'X' if boardstate._board[i][j] == Piece.X else 'O'
print('[',piece,']',' ',end='')
print(i)
print("----------------------------------------------------------------")
def legal_moves(self, boardstate):
"Return a list of legal moves for player."
def check_legal_move(move):
"A legal move must involve an empty position."
if boardstate._board[move[0]][move[1]] == Piece.EMPTY:
return True
else:
return None
moves = []
for move in boardstate.search_region:
if check_legal_move((move[0], move[1])):
moves.append(move)
return moves
def add_made_move(self, move, boardstate):
"""Add the new move to the made moves list"""
boardstate.made_moves.add(move)
boardstate.new_move = move
def generate_search_region(self, boardstate):
"""generate the region to be searched, involves one layer further from all the existing pieces"""
for move in boardstate.made_moves:
row, col = move
if row > 0:
boardstate.search_region.add((row - 1, col))
if col > 0:
boardstate.search_region.add((row, col - 1))
if row > 0 and col > 0:
boardstate.search_region.add((row - 1, col - 1))
if row > 0 and col < SIZE - 1:
boardstate.search_region.add((row - 1, col + 1))
if row < SIZE - 1:
boardstate.search_region.add((row + 1, col))
if col < SIZE - 1:
boardstate.search_region.add((row, col + 1))
if row < SIZE -1 and col < SIZE - 1:
boardstate.search_region.add((row + 1, col + 1))
if row < SIZE - 1 and col > 0:
boardstate.search_region.add((row + 1, col - 1))
def make_move(self, move, boardstate):
"Return a new BoardState reflecting move made from given board state."
if (not boardstate._board[move[0]][move[1]] == Piece.EMPTY):
print("Occupied spot, please choose another position")
move = get_user_input()
newBoard = boardstate.make_move(move)
return newBoard
def calculate_utility(self, boardstate):
"""Calculate the utility of this state"""
return boardstate.default_utility()
def utility(self, boardstate, player):
"This is where your utility function gets called."
return player.calculate_utility(boardstate)
def terminal_test(self, boardstate):
"Return True if this is a final state for the game, check if anyone has 5 in a row by checking around the latest move"
initial_row = boardstate.new_move[0]
initial_col = boardstate.new_move[1]
board = boardstate._board
initial_piece = board[initial_row][initial_col]
# check horizontally
row = initial_row
col = initial_col
count = 0
# --->
while (col < SIZE and board[row][col] == initial_piece):
count+=1
col+=1
# <---
col = initial_col - 1
while (col >= 0 and board[row][col] == initial_piece):
count+=1
col-=1
# check vertically
row = initial_row
col = initial_col
count = 0
# down
while (row < SIZE and board[row][col] == initial_piece):
count+=1
row+=1
# up
row = initial_row - 1
while (row >= 0 and board[row][col] == initial_piece):
count+=1
row-=1
# check diagonally /
row = initial_row
col = initial_col
count = 0
# --->
while (row >=0 and col < SIZE and board[row][col] == initial_piece):
count+=1
row-=1
col+=1
# <---
row = initial_row + 1
col = initial_col - 1
while (col >= 0 and row >= 0 and row < SIZE and board[row][col] == initial_piece):
count+=1
row+=1
col-=1
# check diagonally \
row = initial_row
col = initial_col
count = 0
# --->
while (row < SIZE and col < SIZE and board[row][col] == initial_piece):
count+=1
row+=1
col+=1
# <---
row = initial_row - 1
col = initial_col - 1
while (col >= 0 and row >= 0 and board[row][col] == initial_piece):
count+=1
row-=1
col-=1
if count == 5:
return initial_piece
else:
return Piece.EMPTY
def to_move(self, boardstate):
"Return the player whose move it is in this state."
return boardstate.to_move
def successors(self, boardstate):
"Return a list of legal (move, boardstate) pairs."
successor_list = [(move, self.make_move(move, boardstate)) for move in self.legal_moves(boardstate)]
return successor_list