def is_valid_board(board): """ Check if the board is valid. The board is considered valid if the sum of all values in the board, sum, is such that -1 <= sum <= 1, the only values in the board are config.COMPUTER, config.HUMAN, and config.NO_PLAYER, and the length of the board is 9. @param board: the board state you want to check. @return: True if the board is considered valid, False if not. """ valid = len(board) == 9 valid &= -1 <= sum(board) <= 1 valid &= reduce(lambda x, y: x and y, [utils.is_valid_player(p) for p in board]) return valid
def make_move(board, index, p): """ Checks to see that the move is valid. @param board: the board state you want to check. @param index: the index of the board array where you want to make the move for p. @param p: the game_player making the move. p=1 or p=-1 @return: Returns a board representing the new board state if index is a valid move. If p is not a valid value for a game_player, it will raise an exception. If the resulting board is invalid (say you have 3 X moves and 1 O move) it will also throw an exception. """ if not utils.is_valid_player(p) or p == config.NO_PLAYER: raise Exception("Input p must = {0} or {1}. p = {3}".format(config.HUMAN, config.COMPUTER, p)) result = copy.deepcopy(board) result[index] = p if not is_valid_board(result): raise Exception("Move for {0} at {1} is invalid.".format(p, index)) return result