133 lines
4.9 KiB
Python
133 lines
4.9 KiB
Python
|
|
|
|
class Gomoku:
|
|
def __init__(self, data):
|
|
self.pieces = [' ◍ ', ' ○ ']
|
|
self.game_id = data['id']
|
|
self.p1 = data['p1']
|
|
self.p2 = data['p2']
|
|
self.board = data['board']
|
|
self.turn_number = data['turn_number']
|
|
self.winner = data['winner']
|
|
self.current_player = data['current_ps_turn']
|
|
self.piece = self.pieces[data['piece_index']]
|
|
self.instructions = 'Instructions:\nOn your turn play a piece on any unoccupied space.\nThe goal is to get five of your pieces in a row,\ndiagonally or orthagonally.'
|
|
self.directions = [[1,0],[1,-1],[0,-1],[-1,-1]]
|
|
self.game_name = '\nGomoku\n'
|
|
|
|
|
|
def print_challenge_text(self):
|
|
print(self.game_name)
|
|
if self.winner:
|
|
print('{} vs. {}: {} won!'.format(self.p1, self.p2, self.winner))
|
|
else:
|
|
print('{} vs. {}: {}\'s turn {}'.format(self.p1, self.p2, self.current_player, self.piece))
|
|
|
|
|
|
def print_board(self):
|
|
print('\n\n 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15')
|
|
for i, x in enumerate(self.board):
|
|
output_row = str(i + 1) + ''.join(x)
|
|
print('{}{}'.format(' ' if i + 1 < 10 else '', output_row))
|
|
print('')
|
|
|
|
|
|
def validate_input(self, r,c, board):
|
|
if r < 0 or r > 14 or c < 0 or c > 14:
|
|
return False
|
|
|
|
if self.board[r][c] != ' · ':
|
|
return False
|
|
return True
|
|
|
|
|
|
def check_win_state(self, point, piece, board):
|
|
ends = [
|
|
self.walk_to_ends(point, 0, piece, board),
|
|
self.walk_to_ends(point, 1, piece, board),
|
|
self.walk_to_ends(point, 2, piece, board),
|
|
self.walk_to_ends(point, 3, piece, board)
|
|
]
|
|
|
|
game_over = False
|
|
|
|
for x in range(4):
|
|
if self.count_to_five(ends[x], x, piece, board):
|
|
game_over = True
|
|
break
|
|
|
|
return game_over
|
|
|
|
|
|
def count_to_five(self, start, direction, piece, board, count=1):
|
|
look_toward = [self.directions[direction][0] * -1, self.directions[direction][1] * -1]
|
|
new_point = [start[0] + look_toward[0], start[1] + look_toward[1]]
|
|
|
|
if count == 5:
|
|
return True
|
|
|
|
if new_point[0] < 0 or new_point[0] > 14 or new_point[1] < 0 or new_point[1] > 14 or board[new_point[0]][new_point[1]] != self.piece:
|
|
return False
|
|
|
|
return self.count_to_five(new_point, direction, piece, board, count + 1)
|
|
|
|
|
|
|
|
def walk_to_ends(self, point, direction, piece, board):
|
|
look_toward = self.directions[direction]
|
|
new_point = [point[0] + look_toward[0], point[1] + look_toward[1]]
|
|
if new_point[0] < 0 or new_point[0] > 14 or new_point[1] < 0 or new_point[1] > 14 or board[new_point[0]][new_point[1]] != self.piece:
|
|
return point
|
|
return self.walk_to_ends(new_point, direction, piece, board)
|
|
|
|
|
|
def get_input(self):
|
|
print('Enter your move as row-column (ex. 4-10)\n\nOr (q)uit, (f)orfeit, (i)nstructions.')
|
|
|
|
while True:
|
|
move = input('> ')
|
|
if move in ['q', 'quit', 'exit']:
|
|
return False
|
|
elif move in ['f', 'forfeit']:
|
|
while True:
|
|
verify = input('Are you sure (y/n)? ')
|
|
if verify in ['y', 'yes']:
|
|
self.winner = self.p1 if self.p2 == self.current_player else self.p2
|
|
res = {'winner': self.winner, 'board': self.board, 'move': False, 'message': '{} forfeit, {} wins!'.format(self.current_player, self.winner)}
|
|
return res
|
|
elif verify in ['n', 'no']:
|
|
print('Forfeit canceled')
|
|
return False
|
|
elif move in ['i', 'instructions']:
|
|
print(self.instructions)
|
|
continue
|
|
else:
|
|
move = move.split('-')
|
|
if not len(move) == 2:
|
|
print('Invalid entry!')
|
|
continue
|
|
try:
|
|
row = int(move[0]) - 1
|
|
col = int(move[1]) - 1
|
|
except ValueError:
|
|
print('Invalid entry!')
|
|
continue
|
|
|
|
if not self.validate_input(row, col, self.board):
|
|
print('Invalid entry!')
|
|
continue
|
|
|
|
self.board[row][col] = self.piece
|
|
|
|
res = {'winner': self.winner, 'board': self.board, 'move': True}
|
|
|
|
if self.check_win_state([row, col], self.piece, self.board):
|
|
res['winner'] = self.current_player
|
|
res['message'] = '{} won the match!'.format(self.current_player)
|
|
elif self.turn_number > 225:
|
|
res['winner'] = 'tie'
|
|
res['message'] = 'There is no winner. Tie game.'
|
|
else:
|
|
res['message'] = 'Your move has been placed.'
|
|
return res
|