def main(): print("-- Tic Tac Toe --\n") parser = argparse.ArgumentParser() parser.add_argument( "--size", help="size of the one side of the board", type=int) parser.add_argument( "--ai", help="which player for ai, -1 for no ai", type=int, default=1) args = parser.parse_args() ai = args.ai size = args.size model = None if size: model = TicTacToeModel(size) else: model = TicTacToeModel() while True: print(model) current_player = model.current_player next_move = get_next_move(current_player, model, ai) try: model.make_move(next_move, current_player) except ValueError as err: print(err) print("Try again!") continue if model.check_winner(next_move): print(model) print("Player {player} won!".format(player=current_player)) break if model.filled(): print(model) print("Game over: Tie!") break
class TicTacToeModelTestCases(unittest.TestCase): def setUp(self): self.empty_board = TicTacToeModel() self.mid_game_board = TicTacToeModel() self.mid_game_board.make_move((0, 0), 0) self.mid_game_board.make_move((0, 1), 1) self.mid_game_board.make_move((0, 2), 0) self.mid_game_board.make_move((2, 1), 1) self.mid_game_board.make_move((1, 1), 0) def test_default_size(self): self.assertEqual(self.empty_board.board_size, 3) def test_empty_board(self): self.assertEqual(len(self.empty_board), 0) self.assertEqual( self.empty_board.board, [[None, None, None], [None, None, None], [None, None, None]]) self.assertEqual(self.empty_board.remaining_moves, {(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)}) def test_make_move_x_out_of_range(self): with self.assertRaises(ValueError): self.empty_board.make_move((3, 1), 0) with self.assertRaises(ValueError): self.empty_board.make_move((-1, 1), 0) def test_make_move_y_out_of_range(self): with self.assertRaises(ValueError): self.empty_board.make_move((1, 3), 0) with self.assertRaises(ValueError): self.empty_board.make_move((1, -1), 0) def test_make_move_invalid_player(self): with self.assertRaises(ValueError): self.empty_board.make_move((1, 2), -1) with self.assertRaises(ValueError): self.empty_board.make_move((1, 2), 2) def test_make_move_invalid_move(self): with self.assertRaises(ValueError): self.empty_board.make_move((0, 0), 1) def test_make_move_spot_taken(self): with self.assertRaises(ValueError): self.mid_game_board.make_move((0, 0), 1) with self.assertRaises(ValueError): self.mid_game_board.make_move((0, 1), 1) def test_make_move_wrong_player(self): with self.assertRaises(ValueError): self.empty_board.make_move((1, 2), 1) with self.assertRaises(ValueError): self.mid_game_board.make_move((2, 2), 0) def test_make_move_empty_board(self): self.empty_board.make_move((1, 1), 0) self.assertEqual(len(self.empty_board), 1) self.assertEqual( self.empty_board.board, [[None, None, None], [None, 0, None], [None, None, None]]) self.assertEqual(self.empty_board.remaining_moves, {(0, 0), (0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1), (2, 2)}) self.empty_board.make_move((0, 0), 1) self.assertEqual(len(self.empty_board), 2) self.assertEqual( self.empty_board.board, [[1, None, None], [None, 0, None], [None, None, None]]) self.assertEqual(self.empty_board.remaining_moves, {(0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1), (2, 2)}) def test_make_move_mid_game_board(self): self.mid_game_board.make_move((2, 2), 1) self.assertEqual(len(self.mid_game_board), 6) self.assertEqual(self.mid_game_board.board, [[0, 1, 0], [None, 0, None], [None, 1, 1]]) self.assertEqual(self.mid_game_board.remaining_moves, {(1, 0), (1, 2), (2, 0)}) self.mid_game_board.make_move((2, 0), 0) self.assertEqual(len(self.mid_game_board), 7) self.assertEqual(self.mid_game_board.board, [[0, 1, 0], [None, 0, None], [0, 1, 1]]) self.assertEqual(self.mid_game_board.remaining_moves, {(1, 0), (1, 2)}) def test_check_winner_empty_spot(self): with self.assertRaises(ValueError): self.mid_game_board.check_winner((1, 2)) def test_check_winner_x_out_of_range(self): with self.assertRaises(ValueError): self.empty_board.check_winner((3, 0)) with self.assertRaises(ValueError): self.empty_board.check_winner((-1, 0)) def test_check_winner_y_out_of_range(self): with self.assertRaises(ValueError): self.empty_board.check_winner((0, 3)) with self.assertRaises(ValueError): self.empty_board.check_winner((0, -1)) def test_check_winner_empty_board(self): self.assertFalse(self.empty_board.check_winner((0, 0))) def test_check_winner_no_winner(self): self.assertFalse(self.mid_game_board.check_winner((0, 0))) self.assertFalse(self.mid_game_board.check_winner((0, 1))) self.assertFalse(self.mid_game_board.check_winner((0, 2))) self.assertFalse(self.mid_game_board.check_winner((1, 1))) self.assertFalse(self.mid_game_board.check_winner((2, 1))) def test_check_winner_column_0(self): winning_board = TicTacToeModel() winning_board.current_player = 0 winning_board.num_moves = 8 winning_board.board = [[1, None, 0], [1, 0, 0], [1, 0, 1]] self.assertTrue(winning_board.check_winner((0, 0))) self.assertTrue(winning_board.check_winner((1, 0))) self.assertTrue(winning_board.check_winner((2, 0))) def test_check_winner_column_1(self): winning_board = TicTacToeModel() winning_board.current_player = 1 winning_board.num_moves = 5 winning_board.board = [[1, 0, 1], [None, 0, None], [None, 0, None]] self.assertTrue(winning_board.check_winner((0, 1))) self.assertTrue(winning_board.check_winner((1, 1))) self.assertTrue(winning_board.check_winner((2, 1))) def test_check_winner_column_2(self): winning_board = TicTacToeModel() winning_board.current_player = 0 winning_board.num_moves = 6 winning_board.board = [[0, 0, 1], [None, 0, 1], [None, None, 1]] self.assertTrue(winning_board.check_winner((0, 2))) self.assertTrue(winning_board.check_winner((1, 2))) self.assertTrue(winning_board.check_winner((2, 2))) def test_check_winner_row_0(self): winning_board = TicTacToeModel() winning_board.current_player = 1 winning_board.num_moves = 7 winning_board.board = [[0, 0, 0], [None, 1, 1], [1, None, 0]] self.assertTrue(winning_board.check_winner((0, 0))) self.assertTrue(winning_board.check_winner((0, 1))) self.assertTrue(winning_board.check_winner((0, 2))) def test_check_winner_row_1(self): winning_board = TicTacToeModel() winning_board.current_player = 1 winning_board.num_moves = 7 winning_board.board = [[0, None, 0], [1, 1, 1], [1, 0, 0]] self.assertTrue(winning_board.check_winner((1, 0))) self.assertTrue(winning_board.check_winner((1, 1))) self.assertTrue(winning_board.check_winner((1, 2))) def test_check_winner_row_2(self): winning_board = TicTacToeModel() winning_board.current_player = 1 winning_board.num_moves = 7 winning_board.board = [[None, None, None], [1, 1, None], [0, 0, 0]] self.assertTrue(winning_board.check_winner((2, 0))) self.assertTrue(winning_board.check_winner((2, 1))) self.assertTrue(winning_board.check_winner((2, 2))) def test_check_winner_left_right_diag(self): winning_board = TicTacToeModel() winning_board.current_player = 0 winning_board.num_moves = 6 winning_board.board = [[1, None, None], [0, 1, None], [0, 0, 1]] self.assertTrue(winning_board.check_winner((0, 0))) self.assertTrue(winning_board.check_winner((1, 1))) self.assertTrue(winning_board.check_winner((2, 2))) def test_check_winner_right_left_diag(self): winning_board = TicTacToeModel() winning_board.current_player = 0 winning_board.num_moves = 6 winning_board.board = [[0, None, 0], [1, 0, 1], [0, None, 1]] self.assertTrue(winning_board.check_winner((0, 2))) self.assertTrue(winning_board.check_winner((1, 1))) self.assertTrue(winning_board.check_winner((2, 0))) def test_check_winner_empty_board_size_5(self): not_winning_board = TicTacToeModel() self.assertFalse(not_winning_board.check_winner((0, 0))) def test_check_no_winner_size_5(self): not_winning_board = TicTacToeModel(5) not_winning_board.current_player = 0 not_winning_board.num_moves = 16 not_winning_board.board = [[1, None, 1, 0, 1], [1, 0, 0, None, None], [1, 0, 0, None, None], [1, 0, 0, None, None], [0, 1, 1, None, None]] self.assertFalse(not_winning_board.check_winner((0, 0))) self.assertFalse(not_winning_board.check_winner((1, 0))) self.assertFalse(not_winning_board.check_winner((4, 0))) self.assertFalse(not_winning_board.check_winner((2, 2))) self.assertFalse(not_winning_board.check_winner((4, 2))) def test_check_winner_column_0_size_5(self): winning_board = TicTacToeModel(5) winning_board.current_player = 0 winning_board.num_moves = 10 winning_board.board = [[1, 0, 0, None, None], [1, 0, None, None, None], [1, 0, None, None, None], [1, 0, None, None, None], [1, None, None, None, None]] self.assertTrue(winning_board.check_winner((0, 0))) self.assertTrue(winning_board.check_winner((1, 0))) self.assertTrue(winning_board.check_winner((2, 0))) self.assertTrue(winning_board.check_winner((3, 0))) self.assertTrue(winning_board.check_winner((4, 0))) def test_check_winner_column_1_size_5(self): winning_board = TicTacToeModel(5) winning_board.current_player = 1 winning_board.num_moves = 9 winning_board.board = [[1, 0, None, None, None], [1, 0, None, None, None], [1, 0, None, None, None], [1, 0, None, None, None], [None, 0, None, None, None]] self.assertTrue(winning_board.check_winner((0, 1))) self.assertTrue(winning_board.check_winner((1, 1))) self.assertTrue(winning_board.check_winner((2, 1))) self.assertTrue(winning_board.check_winner((3, 1))) self.assertTrue(winning_board.check_winner((4, 1))) def test_check_winner_column_2_size_5(self): winning_board = TicTacToeModel(5) winning_board.current_player = 0 winning_board.num_moves = 9 winning_board.board = [[0, 0, 1, None, None], [0, 0, 1, None, 1], [0, 0, 1, 1, None], [0, None, 1, None, None], [None, None, 1, None, None]] self.assertTrue(winning_board.check_winner((0, 2))) self.assertTrue(winning_board.check_winner((1, 2))) self.assertTrue(winning_board.check_winner((2, 2))) self.assertTrue(winning_board.check_winner((3, 2))) self.assertTrue(winning_board.check_winner((4, 2))) def test_check_winner_column_3_size_5(self): winning_board = TicTacToeModel(5) winning_board.current_player = 1 winning_board.num_moves = 19 winning_board.board = [[1, 0, 1, 0, None], [1, 0, 1, 0, None], [1, 0, 1, 0, None], [1, 0, 1, 0, None], [0, 1, None, 0, None]] self.assertTrue(winning_board.check_winner((0, 3))) self.assertTrue(winning_board.check_winner((1, 3))) self.assertTrue(winning_board.check_winner((2, 3))) self.assertTrue(winning_board.check_winner((3, 3))) self.assertTrue(winning_board.check_winner((4, 3))) def test_check_winner_column_4_size_5(self): winning_board = TicTacToeModel(5) winning_board.current_player = 0 winning_board.num_moves = 10 winning_board.board = [[None, 0, 0, None, 1], [None, 0, None, None, 1], [None, 0, None, None, 1], [None, 0, None, None, 1], [None, None, None, None, 1]] self.assertTrue(winning_board.check_winner((0, 4))) self.assertTrue(winning_board.check_winner((1, 4))) self.assertTrue(winning_board.check_winner((2, 4))) self.assertTrue(winning_board.check_winner((3, 4))) self.assertTrue(winning_board.check_winner((4, 4))) def test_check_winner_row_0_size_5(self): winning_board = TicTacToeModel(5) winning_board.current_player = 0 winning_board.num_moves = 10 winning_board.board = [[1, 1, 1, 1, 1], [None, 0, 0, None, None], [None, 0, 0, None, None], [None, 0, None, None, None], [None, None, None, None, None]] self.assertTrue(winning_board.check_winner((0, 0))) self.assertTrue(winning_board.check_winner((0, 1))) self.assertTrue(winning_board.check_winner((0, 2))) self.assertTrue(winning_board.check_winner((0, 3))) self.assertTrue(winning_board.check_winner((0, 4))) def test_check_winner_row_1_size_5(self): winning_board = TicTacToeModel(5) winning_board.current_player = 0 winning_board.num_moves = 10 winning_board.board = [[None, 0, 0, None, None], [1, 1, 1, 1, 1], [None, 0, 0, None, None], [None, 0, None, None, None], [None, None, None, None, None]] self.assertTrue(winning_board.check_winner((1, 0))) self.assertTrue(winning_board.check_winner((1, 1))) self.assertTrue(winning_board.check_winner((1, 2))) self.assertTrue(winning_board.check_winner((1, 3))) self.assertTrue(winning_board.check_winner((1, 4))) def test_check_winner_row_2_size_5(self): winning_board = TicTacToeModel(5) winning_board.current_player = 0 winning_board.num_moves = 10 winning_board.board = [[None, 0, 0, None, None], [None, 0, 0, None, None], [1, 1, 1, 1, 1], [None, 0, None, None, None], [None, None, None, None, None]] self.assertTrue(winning_board.check_winner((2, 0))) self.assertTrue(winning_board.check_winner((2, 1))) self.assertTrue(winning_board.check_winner((2, 2))) self.assertTrue(winning_board.check_winner((2, 3))) self.assertTrue(winning_board.check_winner((2, 4))) def test_check_winner_row_3_size_5(self): winning_board = TicTacToeModel(5) winning_board.current_player = 0 winning_board.num_moves = 10 winning_board.board = [[None, 0, 0, None, None], [None, 0, 0, None, None], [None, 0, None, None, None], [1, 1, 1, 1, 1], [None, None, None, None, None]] self.assertTrue(winning_board.check_winner((3, 0))) self.assertTrue(winning_board.check_winner((3, 1))) self.assertTrue(winning_board.check_winner((3, 2))) self.assertTrue(winning_board.check_winner((3, 3))) self.assertTrue(winning_board.check_winner((3, 4))) def test_check_winner_row_4_size_5(self): winning_board = TicTacToeModel(5) winning_board.current_player = 0 winning_board.num_moves = 10 winning_board.board = [[None, 0, 0, None, None], [None, 0, 0, None, None], [None, 0, None, None, None], [None, None, None, None, None], [1, 1, 1, 1, 1]] self.assertTrue(winning_board.check_winner((4, 0))) self.assertTrue(winning_board.check_winner((4, 1))) self.assertTrue(winning_board.check_winner((4, 2))) self.assertTrue(winning_board.check_winner((4, 3))) self.assertTrue(winning_board.check_winner((4, 4))) def test_check_winner_left_right_diag_size_5(self): winning_board = TicTacToeModel(5) winning_board.current_player = 1 winning_board.num_moves = 15 winning_board.board = [[0, 0, 1, None, 1], [None, 0, None, None, 1], [1, 0, 0, None, 1], [1, 0, None, 0, 1], [None, None, None, None, 0]] self.assertTrue(winning_board.check_winner((0, 0))) self.assertTrue(winning_board.check_winner((1, 1))) self.assertTrue(winning_board.check_winner((2, 2))) self.assertTrue(winning_board.check_winner((3, 3))) self.assertTrue(winning_board.check_winner((4, 4))) def test_check_winner_right_left_diag_size_5(self): winning_board = TicTacToeModel(5) winning_board.current_player = 1 winning_board.num_moves = 18 winning_board.board = [[0, 0, 0, None, 1], [0, 0, 0, 1, 1], [0, 0, 1, None, 1], [0, 1, None, None, 1], [1, None, None, None, 1]] self.assertTrue(winning_board.check_winner((4, 0))) self.assertTrue(winning_board.check_winner((3, 1))) self.assertTrue(winning_board.check_winner((2, 2))) self.assertTrue(winning_board.check_winner((1, 3))) self.assertTrue(winning_board.check_winner((0, 4))) def test_check_filled(self): self.assertFalse(self.empty_board.filled()) self.empty_board.make_move((0, 0), 0) self.assertFalse(self.empty_board.filled()) self.empty_board.make_move((1, 0), 1) self.assertFalse(self.empty_board.filled()) self.empty_board.make_move((2, 0), 0) self.assertFalse(self.empty_board.filled()) self.empty_board.make_move((0, 2), 1) self.assertFalse(self.empty_board.filled()) self.empty_board.make_move((0, 1), 0) self.assertFalse(self.empty_board.filled()) self.empty_board.make_move((2, 1), 1) self.assertFalse(self.empty_board.filled()) self.empty_board.make_move((1, 1), 0) self.assertFalse(self.empty_board.filled()) self.empty_board.make_move((2, 2), 1) self.assertFalse(self.empty_board.filled()) self.empty_board.make_move((1, 2), 0) self.assertTrue(self.empty_board.filled()) self.assertEqual(self.empty_board.remaining_moves, set()) def test_copy(self): copy = self.mid_game_board.copy() self.assertEqual(len(copy), 5) self.assertEqual(copy.current_player, 1) self.assertEqual(copy.board, self.mid_game_board.board) self.assertEqual(copy.remaining_moves, {(1, 0), (1, 2), (2, 0), (2, 2)}) copy_board_before = copy.board.copy() self.mid_game_board.make_move((1, 0), 1) self.assertEqual(len(copy), 5) self.assertEqual(copy.current_player, 1) self.assertEqual(copy.board, copy_board_before) self.assertEqual(copy.remaining_moves, {(1, 0), (1, 2), (2, 0), (2, 2)}) def test_undo_move_no_move(self): with self.assertRaises(ValueError): self.empty_board.undo_move() def test_undo_move_mid_game(self): self.assertEqual(self.mid_game_board.moves[4], (1, 1)) self.mid_game_board.undo_move() self.assertEqual(self.mid_game_board.moves[3], (2, 1)) self.assertEqual(len(self.mid_game_board), 4) self.assertEqual(self.mid_game_board.remaining_moves, {(1, 0), (1, 2), (2, 0), (2, 2), (1, 1)}) self.assertEqual(self.mid_game_board.current_player, 0)