def __init__(self, strategy_A, strategy_B, strategy_A_name="", strategy_B_name="", x_first=True): self.strategy_A = strategy_A self.strategy_B = strategy_B self.strategy_A_name = (strategy_A.__name__ if not strategy_A_name else strategy_A_name) self.strategy_B_name = (strategy_B.__name__ if not strategy_B_name else strategy_B_name) self.x_first = x_first self.board = Board(x_first=self.x_first) self.history = []
def set_boards(self): # comment denotes who goes next self.board1 = Board(['x', 'o', 2, 'x', 'x', 'o', 6, 7, 'o']) #x self.board3 = Board([0, 1, 2, 3, 'x', 5, 6, 7, 8]) #o self.board4 = Board(['x', 1, 2, 3, 'x', 5, 'o', 7, 8]) #o self.board5 = Board(['x', 1, 2, 3, 'x', 5, 'o', 'x', 'o']) #o self.board6 = Board(['o', 'x', 'x', 'x', 'x', 'o', 'o', 'o', 8]) #x self.board7 = Board(['o', 'x', 'x', 'x', 'x', 'o', 'o', 'o', 'x']) #no one self.board8 = Board() #x # These boards are acceptable to the player who goes next self.good_boards = [self.board1, self.board3, self.board4, self.board5, self.board6, self.board8] self.board9 = Board(['x', 'x', 2, 'o', 'x', 5, 6, 7, 'o']) self.board10 = Board(['o', 'o', 2, 'x', 'x', 'x', 6, 7, 8])
def __init__(self, strategy_A, strategy_B, strategy_A_name="", strategy_B_name="", x_first=True): self.strategy_A = strategy_A self.strategy_B = strategy_B self.strategy_A_name = (strategy_A.__name__ if not strategy_A_name else strategy_A_name) self.strategy_B_name = (strategy_B.__name__ if not strategy_B_name else strategy_B_name) self.x_first = x_first self.board = Board(x_first = self.x_first) self.history = []
def construct_board(board_str): ''' Constructs a tic-tac-toe board from a string representing the board. :param board_str: length 9 string, each character being in -, x or o> :returns: board.Board object ''' board_initializer = range(9) for index, value in enumerate(board_str): if value in ('x', 'o'): board_initializer[index] = value return Board(board_initializer)
def setUp(self): self.empty = Board() self.empty_o = Board(x_first=False) self.test1 = Board(["o", 1, 2, 3, "x", 5, "x", 7, 8]) self.full = Board(['x', 'o', 'x', 'o', 'x', 'o', 'x', 'o', 'x'])
def test_OnUnfinishedGameBoardReturnsTheStringNone(self): board = Board([0, 'x', 'o', 3, 'x', 5, 'o', 7, 8]) self.assertResultReturnsStringNone(board)
def test_normalUse2(self): result = construct_board('x--------') init_board = range(9) init_board[0] = 'x' expected = Board(init_board) self.assertEqual(expected, result)
def test_DoesNotMutateBoard(self): board = Board(['o', 1, 2, 3, 'x', 5, 6, 7, 8]) board.next_boards() new_board = Board(['o', 1, 2, 3, 'x', 5, 6, 7, 8]) self.assertEqual(board, new_board)
def test_OnFullBoardReturnsNoBoards(self): board = Board(['o', 'x', 'x', 'x', 'x', 'o', 'o', 'o', 'x']) result = board.next_boards() self.assertEqual(result, [])
def test_OnSemiPopulatedBoardAssignsPlayToIndex(self): board = Board([0, "x", "o", 3, "x", 5, "o", 7, 8]) board.place(7, 'x') self.assertEqual(board, Board([0, 'x', 'o', 3, 'x', 5, 'o', 'x', 8]))
def test_OnBoardWithTieReturnsStringTie(self): board = Board(["x", "x", "o", "o", "o", "x", "x", "o", "x"]) result = board.result() self.assertEqual(result, 'Tie')
def test_OnXFirstWithEqualXOReturnsStringx(self): self.assertNextPlayEquals(Board(['x', 'o', 2, 3, 4, 5, 6, 7, 8]), 'x')
def test_OnXFirstWithOneXReturnsStringo(self): self.assertNextPlayEquals(Board([0, 1, 2, 3, 'x', 5, 6, 7, 8]), 'o')
def test_OnEmptyBoardDefaultOverridenReturnsStringo(self): self.assertNextPlayEquals(Board(x_first=False), 'o')
def test_OnEmptyBoardReturnsStringx(self): self.assertNextPlayEquals(Board(), 'x')
def test_OnEmptyBoardAssignsPlayToIndex(self): board = Board() board.place(8, 'x') self.assertEqual(board, Board([0, 1, 2, 3, 4, 5, 6, 7, 'x']))
def test_OnBoardWonByXOnRowReturnsStringx(self): board = Board(["x", "x", "x", 3, "o", 5, "o", "o", 8]) self.assertResultReturnsPlay(board, 'x')
def set_boards(self): self.board1 = Board() self.board2 = Board([0, "x", "o", 3, "x", 5, "o", 7, 8])
def testOnOFirstWithOneOReturnsStringx(self): self.assertNextPlayEquals( Board(['o', 1, 2, 3, 4, 5, 6, 7, 8], x_first=False), 'x')
def testOnOFirstWithEqualXOReturnsStringo(self): self.assertNextPlayEquals( Board(['o', 'x', 2, 3, 4, 5, 6, 7, 8], x_first=False), 'o')
def test_OnEmptyBoardReturns9Boards(self): board = Board() result = board.next_boards() self.assertEqual(len(result), 9)
def testOnFullBoardReturnsNone(self): self.assertNextPlayEquals( Board(['x', 'o', 'o', 'x', 'x', 'o', 'x', 'o', 'x']), None)
def test_OnBoardWithTwoOptionsReturnsListOfBothResultingBoards(self): board = Board([0, 1, 'x', 'o', 'x', 'o', 'x', 'o', 'x']) result = board.next_boards() expected1 = Board(['o', 1, 'x', 'o', 'x', 'o', 'x', 'o', 'x']) expected2 = Board([0, 'o', 'x', 'o', 'x', 'o', 'x', 'o', 'x']) self.assertEqual(sorted([expected1, expected2]), sorted(result))
def test_normalUse1(self): result = construct_board('---------') expected = Board() self.assertEqual(result, expected)
class Game(object): ''' Instances of this class represent a game of tic-tac-toe. *Constructor Arguments: strategy_A (function): the strategy that goes first strategy_B (function): the strategy that goes second strategy_A_name (str; default=the function's name): the name given to the first strategy strategy_B_name (str; default=the function's name): the name given to the second strategy x_first (bool; default=True): determines whether 'x' goes first ''' # Instance attribute history can be used # to examine the history of the game. It is a list of the form # [board, (strategy, play), board, (strategy, play) ....board] # self.winner accesses the name of the winning strategy or # "No one" if there was a tie. It is not set until the game # has ended. def __init__(self, strategy_A, strategy_B, strategy_A_name="", strategy_B_name="", x_first=True): self.strategy_A = strategy_A self.strategy_B = strategy_B self.strategy_A_name = (strategy_A.__name__ if not strategy_A_name else strategy_A_name) self.strategy_B_name = (strategy_B.__name__ if not strategy_B_name else strategy_B_name) self.x_first = x_first self.board = Board(x_first=self.x_first) self.history = [] def play_game(self, display=False): ''' Plays a game of tic-tac-toe between the instance's two strategies. Sets self.result to "Tie", "x" or "o". Sets self.winner to the name of one of the strategy or to "No one" if the game is a tie. *Arguments: display(bool; default=False): if True, the board and each play are printed during the game *Raises: ValueError if the game is over ''' if self.result != 'None': raise ValueError, "Game has already been played" current = self.strategy_A up_next = self.strategy_B if self.x_first: names = {'x': self.strategy_A_name, 'o': self.strategy_B_name} else: names = {'o': self.strategy_A_name, 'x': self.strategy_B_name} while self.result == 'None': self.history.append(copy.deepcopy(self.board)) if display: print self.board print "\n" play = current(self.board) self.board.place(*play) self.history.append((names[play[1]], play)) if display: name = names[play[1]] print "%s plays %s at %i.\n" % (name, play[1], play[0]) current, up_next = up_next, current self.history.append(copy.deepcopy(self.board)) result = self.result if result == "Tie": self.winner = "No one" else: self.winner = names[result] if display: print self.board print "\n" if result == "Tie": print "It's a tie!\n" else: print self.winner + " wins!\n" def display_history(self): ''' Displays the sequence of boards and moves played thus far. ''' for item in self.history: if isinstance(item, Board): print item print "\n" else: print "%s plays %s at %i.\n" % (item[0], item[1][1], item[1][0]) @property def result(self): ''' Gets the result of the game: 'x' or 'o' or 'Tie'. If the game is not over, 'None'. ''' return self.board.result()
class Game(object): ''' Instances of this class represent a game of tic-tac-toe. *Constructor Arguments: strategy_A (function): the strategy that goes first strategy_B (function): the strategy that goes second strategy_A_name (str; default=the function's name): the name given to the first strategy strategy_B_name (str; default=the function's name): the name given to the second strategy x_first (bool; default=True): determines whether 'x' goes first ''' # Instance attribute history can be used # to examine the history of the game. It is a list of the form # [board, (strategy, play), board, (strategy, play) ....board] # self.winner accesses the name of the winning strategy or # "No one" if there was a tie. It is not set until the game # has ended. def __init__(self, strategy_A, strategy_B, strategy_A_name="", strategy_B_name="", x_first=True): self.strategy_A = strategy_A self.strategy_B = strategy_B self.strategy_A_name = (strategy_A.__name__ if not strategy_A_name else strategy_A_name) self.strategy_B_name = (strategy_B.__name__ if not strategy_B_name else strategy_B_name) self.x_first = x_first self.board = Board(x_first = self.x_first) self.history = [] def play_game(self, display=False): ''' Plays a game of tic-tac-toe between the instance's two strategies. Sets self.result to "Tie", "x" or "o". Sets self.winner to the name of one of the strategy or to "No one" if the game is a tie. *Arguments: display(bool; default=False): if True, the board and each play are printed during the game *Raises: ValueError if the game is over ''' if self.result != 'None': raise ValueError, "Game has already been played" current = self.strategy_A up_next = self.strategy_B if self.x_first: names = {'x' : self.strategy_A_name, 'o' : self.strategy_B_name} else: names = {'o': self.strategy_A_name, 'x' : self.strategy_B_name} while self.result == 'None': self.history.append(copy.deepcopy(self.board)) if display: print self.board print "\n" play = current(self.board) self.board.place(*play) self.history.append((names[play[1]], play)) if display: name = names[play[1]] print "%s plays %s at %i.\n"%(name, play[1], play[0]) current, up_next = up_next, current self.history.append(copy.deepcopy(self.board)) result = self.result if result == "Tie": self.winner = "No one" else: self.winner = names[result] if display: print self.board print "\n" if result == "Tie": print "It's a tie!\n" else: print self.winner + " wins!\n" def display_history(self): ''' Displays the sequence of boards and moves played thus far. ''' for item in self.history: if isinstance(item, Board): print item print "\n" else: print "%s plays %s at %i.\n"%(item[0], item[1][1], item[1][0]) @property def result(self): ''' Gets the result of the game: 'x' or 'o' or 'Tie'. If the game is not over, 'None'. ''' return self.board.result()
def test_OnEmptyBoardReturnsTheStringNone(self): board = Board() self.assertResultReturnsStringNone(board)
def test_OnBoardWonByOOnDiagonalReturnsStringo(self): board = Board(['x', "x", "o", 3, "o", 5, "o", "x", 8]) self.assertResultReturnsPlay(board, 'o')
def test_IterableBoardArgumentConvertedToList(self): arg = (0, 1, 2, 3, 4, 5, 6, 'o', 'x') board = Board(arg) self.assertEqual(board.board, [0, 1, 2, 3, 4, 5, 6, 'o', 'x'])
def setUp(self): self.board1 = Board(['o', 'x', 2, 'x', 'x', 'o', 6, 'o', 8]) self.board2 = Board(['x', 'o', 'o', 'x', 'x', 'o', 'o', 'x', 'x']) self.board3 = Board(['x', 'o', 'o', 'x', 'x', 'o', 'o', 'x', 'x'])