def play(self): """ Plays the game, alternating turns between the players. Moves are requested sequentially from each player in turn until there is a winner. The moves are checked for validity. Returns: int: the side of the winning player, or None if there was a draw """ if self.shuffle: random.shuffle(self.players()) player_cycle = cycle(self.players()) # Request moves from each player until there is a win or draw for player in player_cycle: # Uncomment to log board state each turn # if self.logger: # self.logger.debug(rules.board_str(self.board)) # Check for a win or draw winning_side = rules.winner(self.board) if winning_side is not None: winner = self.player(winning_side) if self.logger: self.logger.info("{2}\nGame over: {0} win ({1})".format( rules.side_name(winning_side), type(winner).__name__, rules.board_str(self.board))) # Return the side of the winning player return winning_side elif rules.board_full(self.board): # The board is full so the game concluded with a draw if self.logger: self.logger.info("{0}\nGame over: Draw".format( rules.board_str(self.board))) # Return None for a draw return None # Request a move from the player move = player.move(self.board.copy()) # Apply the move if it is valid if rules.valid_move(self.board, move): self.board[move] = player.side else: if self.logger: self.logger.fatal("Invalid move") raise ValueError("Not a valid move: {0}".format(move))
def move(self, board): print "\n{}".format(rules.board_str(board)) while True: try: move = tuple(map(int, raw_input("Cell (row, col): ").split(","))) except ValueError: continue if rules.valid_move(board, move): return move
def play(self): """ Plays the game, alternating turns between the players. Moves are requested sequentially from each player in turn until there is a winner. The moves are checked for validity. Returns: int: the side of the winning player, or None if there was a draw """ if self.shuffle: random.shuffle(self.players()) player_loop = cycle(self.players()) for player in player_loop: # if self.logger: # self.logger.debug(rules.board_str(self.board)) # Get the coordinates of the player's move move = player.move(self.board) # Make the move if it is valid if rules.valid_move(self.board, move): self.board[move] = player.side else: if self.logger: self.logger.fatal("Invalid move") raise ValueError("Not a valid move: {0}".format(move)) # Check for a win or draw if rules.winning_move(self.board, move): if self.logger: self.logger.info("{2}\nGame over: {0} win ({1})".format( rules.side_name(player.side), type(player).__name__, rules.board_str(self.board))) # Return winning player return player.side elif rules.draw(self.board): if self.logger: self.logger.info("{0}\nGame over: Draw".format( rules.board_str(self.board))) # Return None for draw return None
def move(self, board): # Print the current game board print "\n{}".format(rules.board_str(board)) # Request a move from the player, repeating if the input is not valid while True: try: num = int(raw_input("Cell (1-9): ")) if num not in range(1, 10): continue # Convert number 1-9 to x,y cell coordinates cell = (int((9 - num) / 3), (num - 1) % 3) except ValueError: continue if rules.valid_move(board, cell): return cell
def __str__(self): """Returns a string representation of the board state represented by this node.""" return rules.board_str(self.state)