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