示例#1
0
    def test_has_tile_to_flip(self):
        game = Othello()
        game.initialize_board()

        # Test when the board is in the initial state
        # Test two moves for player 1 (black tile) in all flipping directions
        self.assertTrue(game.has_tile_to_flip((2, 3), (+1, 0)))
        no_flip_dirs = [(-1, -1), (-1, +1), (0, -1), (0, +1),
                        (+1, -1), (-1, 0), (+1, +1)]
        for direction in no_flip_dirs:
            self.assertFalse(game.has_tile_to_flip((2, 3), direction))
        
        self.assertTrue(game.has_tile_to_flip((3, 2), (0, +1)))
        no_flip_dirs = [(-1, -1), (-1, +1), (0, -1), (+1, 0), 
                        (+1, -1), (-1, 0), (+1, +1)]
        for direction in no_flip_dirs:
            self.assertFalse(game.has_tile_to_flip((3, 2), direction))
        
        # Let player 1 make a legal move
        game.move = (2, 3)
        game.make_move()
        
        # Test two moves for player 2 (white tile)
        game.current_player = 1

        self.assertTrue(game.has_tile_to_flip((2, 4), (+1, 0)))
        no_flip_dirs = [(-1, -1), (-1, +1), (0, -1), (0, +1), 
                        (+1, -1), (-1, 0), (+1, +1)]
        for direction in no_flip_dirs:
            self.assertFalse(game.has_tile_to_flip((2, 4), direction))
        
        self.assertTrue(game.has_tile_to_flip((2, 2), (+1, +1)))
        no_flip_dirs =  [(-1, -1), (-1, 0), (-1, +1), (0, -1),
                         (0, +1), (+1, -1), (+1, 0)]
        for direction in no_flip_dirs:
            self.assertFalse(game.has_tile_to_flip((2, 2), direction))

        # Test when player 1 has tiles to flip but player 2 does not
        game.board = [[2, 0, 2, 2, 2, 2, 2, 2], 
                      [2, 2, 2, 2, 1, 1, 1, 1],
                      [2, 1, 2, 1, 1, 1, 1, 1], 
                      [1, 1, 1, 1, 1, 1, 1, 1],
                      [2, 2, 1, 1, 1, 2, 2, 1], 
                      [0, 2, 1, 1, 2, 2, 2, 1], 
                      [1, 2, 1, 2, 2, 2, 2, 1], 
                      [1, 2, 2, 2, 2, 2, 0, 1]]

        game.current_player = 0
        flip_dirs = {(0, 1) : [(+1, 0), (+1, +1)], 
                     (5, 0) : [(-1, 0), (0, +1), (-1, +1)],
                     (7, 6) : [(-1, 0), (0, -1), (-1, -1)]}
        for move in flip_dirs:
            for direction in flip_dirs[move]:
                self.assertTrue(game.has_tile_to_flip(move, direction))

        game.current_player = 1
        for direction in MOVE_DIRS:
            self.assertFalse(game.has_tile_to_flip((0, 1), direction))
            self.assertFalse(game.has_tile_to_flip((5, 0), direction))
            self.assertFalse(game.has_tile_to_flip((7, 6), direction))
示例#2
0
def mobility(board):
    # defined number of possible moves : black - white
    g1 = Othello()
    g1.board = board
    g1.current_player = BLACK
    score_black = len(g1.find_all_valid_moves())
    g1.current_player = WHITE
    score_white = len(g1.find_all_valid_moves())
    return score_black - score_white
示例#3
0
    def test_make_random_move(self):
        game = Othello()
        game.initialize_board()

        # Test when the board is in the initial state
        game.make_random_move()
        legal_moves = [(2, 3), (3, 2), (5, 4), (4, 5)]
        self.assertIn(game.move, legal_moves)

        # Test after player 1 makes a legal move
        game = Othello()
        game.initialize_board()
        game.move = (2, 3)
        game.make_move()
        
        # Test making random moves for player 2 (white tile)
        game.current_player = 1
        game.make_random_move()
        legal_moves = [(2, 4), (2, 2), (4, 2)]
        self.assertIn(game.move, legal_moves)

        # Test when player 1 has legal moves but player 2 has no legal moves
        # Try making random moves for both players
        game.current_player = 0
        game.board = [[2, 0, 2, 2, 2, 2, 2, 2], 
                      [2, 2, 2, 2, 1, 1, 1, 1],
                      [2, 1, 2, 1, 1, 1, 1, 1], 
                      [1, 1, 1, 1, 1, 1, 1, 1],
                      [2, 2, 1, 1, 1, 2, 2, 1], 
                      [0, 2, 1, 1, 2, 2, 2, 1], 
                      [1, 2, 1, 2, 2, 2, 2, 1], 
                      [1, 2, 2, 2, 2, 2, 0, 1]]
        game.make_random_move()
        legal_moves = [(0, 1), (5, 0), (7, 6)]
        self.assertIn(game.move, legal_moves)

        game.current_player = 1
        game.move = ()
        game.make_random_move()
        self.assertEqual(game.move, ()) 

        # Test when the board is full (both players have no legal moves)
        game.board = [[2, 1, 2, 2, 2, 2, 2, 2], [2, 1, 1, 2, 1, 1, 1, 1],
                      [2, 1, 2, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1],
                      [1, 1, 1, 1, 1, 2, 1, 1], [1, 1, 1, 1, 1, 2, 1, 1], 
                      [1, 2, 1, 2, 2, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1]]
        game.move = ()
        game.make_random_move()
        self.assertEqual(game.move, ()) 

        game.current_player = 0
        game.move = ()
        game.make_random_move()
        self.assertEqual(game.move, ()) 
示例#4
0
    def test_is_legal_move(self):
        game = Othello()
        game.initialize_board()

        # Test illegal moves before making any legal moves
        illegal_moves = [(), (3, 3), (3, 4), (4, 3), (4, 4), (-1, 0), 
                         (8, 2), (-5, 9), (0, 0), (3, 1), (2, 2), (5, 3)]

        for move in illegal_moves:
            self.assertFalse(game.is_legal_move(move))

        # Test legal moves for player 1 (black tile)
        legal_moves = [(2, 3), (3, 2), (5, 4), (4, 5)]
        for move in legal_moves:
            self.assertTrue(game.is_legal_move(move)) 
        
        # Let player 1 make a legal move
        game.move = (2, 3)
        game.make_move()
        
        # Test legal/illegal moves for player 2 (white tile)
        game.current_player = 1
        legal_moves = [(2, 4), (2, 2), (4, 2)]
        for move in legal_moves:
            self.assertTrue(game.is_legal_move(move))
        illegal_moves = [(3, 2), (5, 3), (5, 4), (4, 5), (3, 5), (6, 1)]
        for move in illegal_moves:
            self.assertFalse(game.is_legal_move(move))
示例#5
0
def minimax(board,
            depth,
            player,
            alpha=-np.inf,
            beta=np.inf,
            eval_func='pos_score',
            king_version=False):
    if depth == 0:
        if eval_func == 'pos_score':
            return pos_score_sum(board)
        elif eval_func == 'mobi':
            return mobility(board)
        elif eval_func == 'pos_mobi':
            return pos_plus_mobi(board)
        elif eval_func == 'king_pos_score':  # this is for King Othello
            return king_pos_score_sum(board)
    if not king_version:
        game = Othello()
    else:
        game = KingOthello()
    game.board = board
    game.current_player = player
    possible_moves = game.find_all_valid_moves()

    if possible_moves:
        if player == BLACK:  # maximizing player
            max_eval = -np.inf
            for move in possible_moves:
                game_copy = deepcopy(game)
                game_copy.take_move(move[0], move[1])
                eval = minimax(game_copy.board, depth - 1, opposite(player),
                               alpha, beta)
                max_eval = max(max_eval, eval)
                alpha = max(alpha, eval)
                if beta <= alpha:
                    break
            return max_eval

        else:  # WHITE, minimizing player
            min_eval = np.inf
            for move in possible_moves:
                game_copy = deepcopy(game)
                game_copy.take_move(move[0], move[1])
                eval = minimax(game_copy.board, depth - 1, opposite(player),
                               alpha, beta)
                min_eval = min(min_eval, eval)
                beta = min(beta, eval)
                if beta <= alpha:
                    break
            return min_eval

    else:  # no possible move for current player
        game.switch_turn()
        possible_moves = game.find_all_valid_moves(
        )  # check whether opponent has moves
        if possible_moves:
            return minimax(game.board, depth - 1, opposite(player), alpha,
                           beta)  # hand over to opponent, nothing changed
        else:  # the opponent has no moves either, game over
            return pos_score_sum(game.board)
示例#6
0
    def test_make_move(self):
        game = Othello()
        game.initialize_board()

        # Test making illegal moves before making any legal moves
        illegal_moves = [(), (3, 3), (3, 4), (4, 3), (4, 4), (-1, 0), 
                         (8, 2), (-5, 9), (0, 0), (3, 1), (2, 2), (5, 3)]
        for move in illegal_moves:
            game.move = move
            game.make_move()
            self.assertEqual(game.board, INITIAL_BOARD)
            self.assertEqual(game.num_tiles, [2, 2])

        # Test making legal moves for different players
        game.move = (2, 3)
        game.make_move()
        self.assertEqual(game.board[2][3], 1)
        self.assertEqual(game.board[3][3], 1)
        self.assertEqual(game.board[4][3], 1)

        game.current_player = 1
        game.move = (2, 2)
        game.make_move()
        self.assertEqual(game.board[2][2], 2)
        self.assertEqual(game.board[3][3], 2)
        self.assertEqual(game.board[4][4], 2)

        game.current_player = 0
        game.move = (4, 5)
        game.make_move()
        self.assertEqual(game.board[4][3], 1)
        self.assertEqual(game.board[4][4], 1)
        self.assertEqual(game.board[4][5], 1)

        # Test making illegal moves after making some legal moves
        game.current_player = 1
        game.move = (5, 4)
        game.make_move()
        self.assertEqual(game.board[5][4], 0)
        game.move = (5, 2)
        game.make_move()
        self.assertEqual(game.board[5][2], 0)
        game.move = (6, 0)
        game.make_move()
        self.assertEqual(game.board[6][0], 0)
示例#7
0
    def test_get_legal_moves(self):
        game = Othello()
        game.initialize_board()

        # Test legal moves for player 1 (black tile)
        legal_moves = [(2, 3), (3, 2), (4, 5), (5, 4)]
        self.assertEqual(game.get_legal_moves(), legal_moves)

        # Let player 1 make a legal move
        game.move = (2, 3)
        game.make_move()
        
        # Test legal moves for player 2 (white tile)
        game.current_player = 1
        legal_moves = [(2, 2), (2, 4), (4, 2)]
        self.assertEqual(game.get_legal_moves(), legal_moves)

        # Test when player 1 has legal moves but player 2 has no legal moves
        game.current_player = 0
        game.board = [[2, 0, 2, 2, 2, 2, 2, 2], 
                      [2, 2, 2, 2, 1, 1, 1, 1],
                      [2, 1, 2, 1, 1, 1, 1, 1], 
                      [1, 1, 1, 1, 1, 1, 1, 1],
                      [2, 2, 1, 1, 1, 2, 2, 1], 
                      [0, 2, 1, 1, 2, 2, 2, 1], 
                      [1, 2, 1, 2, 2, 2, 2, 1], 
                      [1, 2, 2, 2, 2, 2, 0, 1]]
        legal_moves = [(0, 1), (5, 0), (7, 6)]
        self.assertEqual(game.get_legal_moves(), legal_moves)

        game.current_player = 1
        self.assertEqual(game.get_legal_moves(), [])

        # Test when the board is full (both players have no legal moves)
        game.board = [[2, 1, 2, 2, 2, 2, 2, 2], [2, 1, 1, 2, 1, 1, 1, 1],
                      [2, 1, 2, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1],
                      [1, 1, 1, 1, 1, 2, 1, 1], [1, 1, 1, 1, 1, 2, 1, 1], 
                      [1, 2, 1, 2, 2, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1]]
        self.assertEqual(game.get_legal_moves(), [])
        game.current_player = 0
        self.assertEqual(game.get_legal_moves(), [])
示例#8
0
    def test_eq(self):
        game1 = Othello(4)
        game2 = Othello(4)
        game3 = Othello(8)

        self.assertTrue(game1 == game2)
        self.assertFalse(game1 == game3)
        self.assertFalse(game2 == game3)

        game1.board[0][0] = 1
        self.assertFalse(game1 == game2)

        game2.board[0][0] = 1
        self.assertTrue(game1 == game2)

        game1.current_player = 1
        self.assertFalse(game1 == game2)

        game2.current_player = 1
        self.assertTrue(game1 == game2)

        game2.current_player = 2
        self.assertFalse(game1 == game2)
示例#9
0
    def test_has_legal_move(self):
        game = Othello()
        game.initialize_board()

        # Test when the board is in the initial state
        self.assertTrue(game.has_legal_move())

        # Test when player 1 (black tile) has legal moves
        game.board = [[2, 0, 0, 1, 0, 0, 0, 2], [2, 1, 1, 1, 0, 0, 2, 0],
                      [2, 1, 2, 1, 2, 2, 2, 2], [1, 1, 1, 1, 1, 2, 1, 0],
                      [2, 2, 2, 1, 2, 1, 2, 0], [0, 2, 1, 1, 1, 2, 1, 2], 
                      [1, 1, 2, 0, 1, 2, 1, 1], [1, 0, 0, 2, 1, 0, 0, 1]]
        self.assertTrue(game.has_legal_move())

        # Test when player 2 (white tile) has legal moves
        game.current_player = 1
        game.board = [[2, 0, 0, 1, 1, 1, 1, 2], [2, 1, 1, 2, 0, 0, 1, 1],
                      [2, 1, 2, 1, 2, 2, 1, 2], [1, 1, 1, 1, 1, 1, 2, 0],
                      [2, 2, 1, 1, 1, 2, 2, 0], [0, 2, 1, 1, 2, 2, 1, 2], 
                      [1, 1, 1, 2, 2, 2, 2, 1], [1, 0, 1, 1, 1, 2, 0, 1]]
        self.assertTrue(game.has_legal_move())

        # Test when player 2 (white tile) has no legal moves
        game.board = [[2, 0, 2, 2, 2, 2, 2, 2], [2, 2, 2, 2, 1, 1, 1, 1],
                      [2, 1, 2, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1],
                      [2, 2, 1, 1, 1, 2, 2, 1], [0, 2, 1, 1, 2, 2, 2, 1], 
                      [1, 2, 1, 2, 2, 2, 2, 1], [1, 2, 2, 2, 2, 2, 0, 1]]
        self.assertFalse(game.has_legal_move())

        # Test when the board is full (both players have no legal moves)
        game.board = [[2, 1, 2, 2, 2, 2, 2, 2], [2, 1, 1, 2, 1, 1, 1, 1],
                      [2, 1, 2, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1],
                      [1, 1, 1, 1, 1, 2, 1, 1], [1, 1, 1, 1, 1, 2, 1, 1], 
                      [1, 2, 1, 2, 2, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1]]
        self.assertFalse(game.has_legal_move())
        game.current_player = 0
        self.assertFalse(game.has_legal_move())
示例#10
0
    def test_flip_tiles(self):
        game = Othello()
        game.initialize_board()

        # Let player 1 make a legal move
        game.move = (2, 3)
        game.board[2][3] = 1
        game.num_tiles[0] += 1
        
        # Test fliping tiles for player 1 (black tile)
        game.flip_tiles()
        expected_board = copy.deepcopy(INITIAL_BOARD)
        expected_board[2][3] = expected_board[3][3] = 1
        self.assertEqual(game.board, expected_board)
        self.assertEqual(game.num_tiles, [4, 1])

        # Test fliping tiles for player 2 (black tile)
        game.current_player = 1
        game.move = (2, 2)
        game.board[2][2] = 2
        game.num_tiles[1] += 1

        game.flip_tiles()
        expected_board[2][2] = expected_board[3][3] = 2
        self.assertEqual(game.board, expected_board)
        self.assertEqual(game.num_tiles, [3, 3])

        # Test when player 1 has tiles to flip but player 2 does not
        game.board = [[2, 0, 2, 2, 2, 2, 2, 2], 
                      [2, 2, 2, 2, 1, 1, 1, 1],
                      [2, 1, 2, 1, 1, 1, 1, 1], 
                      [1, 1, 1, 1, 1, 1, 1, 1],
                      [2, 2, 1, 1, 1, 2, 2, 1], 
                      [0, 2, 1, 1, 2, 2, 2, 1], 
                      [1, 2, 1, 2, 2, 2, 2, 1], 
                      [1, 2, 2, 2, 2, 2, 0, 1]]
        game.num_tiles = [30, 31]

        game.current_player = 0
        game.move = (0, 1)
        game.board[0][1] = 1
        game.num_tiles[0] += 1

        game.flip_tiles()
        expected_board = [[2, 1, 2, 2, 2, 2, 2, 2], 
                          [2, 1, 1, 2, 1, 1, 1, 1],
                          [2, 1, 2, 1, 1, 1, 1, 1], 
                          [1, 1, 1, 1, 1, 1, 1, 1],
                          [2, 2, 1, 1, 1, 2, 2, 1], 
                          [0, 2, 1, 1, 2, 2, 2, 1], 
                          [1, 2, 1, 2, 2, 2, 2, 1], 
                          [1, 2, 2, 2, 2, 2, 0, 1]]
        self.assertEqual(game.board, expected_board)
        self.assertEqual(game.num_tiles, [33, 29])

        game.current_player = 1
        moves = [(5, 0), (7, 6)]
        for move in moves:
            game.move = move
            game.flip_tiles()
            self.assertEqual(game.board, expected_board)
            self.assertEqual(game.num_tiles, [33, 29])