Esempio n. 1
0
    def _playout(self, color, board, move, pid=None):
        """
        終了までゲームを進めて勝敗を返す
        """
        remain = board.size * board.size - (board._black_score +
                                            board._white_score)

        if remain <= self.remain:
            playout_board = copy.deepcopy(board)  # 現在の盤面をコピー
            playout_board.put_disc(color, *move)  # 調べたい手を打つ

            # 勝敗が決まるまでゲームを進める
            next_color = 'white' if color == 'black' else 'black'  # 相手の色を調べる
            game = Game(self._black_player, self._white_player, playout_board,
                        NoneDisplay(), next_color)
            game.play()

            # 結果を返す
            win, ret = Game.BLACK_WIN if color == 'black' else Game.WHITE_WIN, -1

            if game.result.winlose == win:
                ret = 1  # 勝った場合
            elif game.result.winlose == Game.DRAW:
                ret = 0  # 引き分けた場合
        else:
            ret = 0  # 盤面サイズが大きい場合は残り手数が減るまでしばらくランダムに打つ

        return ret
Esempio n. 2
0
    def do_shallow_scan(matrix, player, avail_moves, get_all=False):
        """Make a shallow scan on the surface of matrix"""
        result_list = []

        for position in avail_moves:
            val = Game.predict_score(player, position, matrix)
            result_list.append([position, Utilities.calc_value(player, val)])

        if get_all:
            return result_list

        return Game.get_best_pair(result_list)
Esempio n. 3
0
    def switch_player(self):
        """Switch current player"""
        opponent = None

        if self.current_player == Player.PLAYER:
            opponent = Player.COMPUTER
        elif self.current_player == Player.COMPUTER:
            opponent = Player.PLAYER

        # Check if there's any available moves for the opponent
        if not Game.get_available_moves(opponent, self.matrix):

            # Check if both players have no moves
            if not Game.get_available_moves(self.current_player, self.matrix):
                self.stop_game()

                if self.player_score > self.computer_score:
                    dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.INFO,
                                               Gtk.ButtonsType.OK,
                                               "Well Done! You're good.")
                    dialog.format_secondary_text("You beat computer for " +
                                                 str(self.player_score -
                                                     self.computer_score) +
                                                 " points.")
                    dialog.run()
                    dialog.destroy()
                elif self.player_score < self.computer_score:
                    dialog = Gtk.MessageDialog(
                        self, 0, Gtk.MessageType.INFO, Gtk.ButtonsType.OK,
                        "Luck may not always be by your side")
                    dialog.format_secondary_text("Computer got over you by " +
                                                 str(self.computer_score -
                                                     self.player_score) +
                                                 " points.")
                    dialog.run()
                    dialog.destroy()
                else:
                    dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.INFO,
                                               Gtk.ButtonsType.OK,
                                               "I'm actually impressed!")
                    dialog.format_secondary_text(
                        "Wanna take another try? " +
                        "You just got a draw with computer.")
                    dialog.run()
                    dialog.destroy()
        else:
            self.current_player = opponent

        # If there's any valid moves for computer and the game still continues,
        # let it make the way
        if self.current_player == Player.COMPUTER \
                and self.game_state == GameStatus.PLAYING:
            self.make_move_ai()
Esempio n. 4
0
    def make_move_ai(self):
        """Makes move for AI

        :returns: none

        """
        avail_moves = Game.get_available_moves(self.current_player,
                                               self.matrix)
        pair = []

        if self.game_mode == GameMode.EASY:
            pair = Algorithm.do_shallow_scan(self.matrix, self.current_player,
                                             avail_moves)
        elif self.game_mode == GameMode.NORMAL:
            pair = Algorithm().do_minimax(self.depth - 1, self.matrix,
                                          self.current_player, avail_moves)
        else:  # GameMode.HARD
            pair = Algorithm().do_alpha_beta_pruning(self.depth - 1,
                                                     self.matrix,
                                                     self.current_player,
                                                     avail_moves)

        self.make_move(pair[0])

        self.switch_player()
Esempio n. 5
0
    def make_move(self, position):
        """TODO: Make move at the given position to given player

        :player: current player
        :position: list of [x, y]
        :screen: screen to draw
        :returns: True if move made

        """
        # Make the actual move and get the result
        score = Game.make_move(self.current_player, position, self.matrix)

        # Redraw screen
        self.screen.redraw()

        if score is False:  # Invalid move
            return False

        # Update score label
        if self.current_player == Player.PLAYER:
            self.player_score += (score + 1)
            self.computer_score -= score
        else:
            self.computer_score += (score + 1)
            self.player_score -= score

        # Move to next turn
        self.panel.update_turn_label()
        self.panel.set_score(self.player_score, self.computer_score)
Esempio n. 6
0
    def test_game_init(self):
        class Black(AbstractStrategy):
            def next_move(self, color, board):
                return (0, 0)

        class White(AbstractStrategy):
            def next_move(self, color, board):
                return (0, 0)

        black = Player('black', 'Black', Black())
        white = Player('white', 'White', White())
        game = Game(black, white)
        self.assertIsInstance(game.black_player.strategy, Black)
        self.assertIsInstance(game.white_player.strategy, White)
        self.assertIsInstance(game.board,
                              BitBoardMethods.CyBoard8_64bit.CythonBitBoard)
        self.assertEqual(game.players, [black, white])
        self.assertEqual(game.black_player, game.players[0])
        self.assertEqual(game.white_player, game.players[1])
        self.assertIsInstance(game.display, NoneDisplay)
        self.assertEqual(game.cancel, None)
        self.assertEqual(game.result, [])
Esempio n. 7
0
    def test_game(self):
        class TestDisplay:
            def progress(self, board, black_player, white_player):
                print('display.progress', '\n' + str(board), black_player,
                      white_player)

            def turn(self, player, legal_moves):
                print('display.turn', player, legal_moves)

            def move(self, player, legal_moves):
                print('display.move', player.move, legal_moves)

            def foul(self, player):
                print('display.foul', player)

            def win(self, player):
                print('display.win', player)

            def draw(self):
                print('display.draw')

        class TopLeft(AbstractStrategy):
            def next_move(self, color, board):
                return board.get_legal_moves(color)[0]

        class BottomRight(AbstractStrategy):
            def next_move(self, color, board):
                return board.get_legal_moves(color)[-1]

        class Foul(AbstractStrategy):
            def next_move(self, color, board):
                return (board.size // 2, board.size // 2)

        class TestCancel:
            class TestEvent:
                def is_set(self):
                    print('cancel-event is set')
                    return True

            event = TestEvent()

        p1 = Player('black', 'TopLeft', TopLeft())
        p2 = Player('white', 'BottomRight', BottomRight())
        p3 = Player('white', 'TopLeft', TopLeft())
        p4 = Player('black', 'Foul', Foul())
        p5 = Player('white', 'Foul', Foul())

        # init
        game1 = Game(p1, p2, Board(4), TestDisplay())
        self.assertIsInstance(game1.board, Board)
        self.assertIsInstance(game1.black_player.strategy, TopLeft)
        self.assertIsInstance(game1.white_player.strategy, BottomRight)
        self.assertEqual(game1.black_player, game1.players[0])
        self.assertEqual(game1.white_player, game1.players[1])
        self.assertEqual(game1.cancel, None)
        self.assertEqual(game1.result, [])

        game2 = Game(p1, p3, Board(4), TestDisplay())
        self.assertIsInstance(game2.board, Board)
        self.assertIsInstance(game2.black_player.strategy, TopLeft)
        self.assertIsInstance(game2.white_player.strategy, TopLeft)
        self.assertEqual(game2.black_player, game2.players[0])
        self.assertEqual(game2.white_player, game2.players[1])
        self.assertEqual(game2.cancel, None)
        self.assertEqual(game2.result, [])

        game3 = Game(p1, p2, Board(4), TestDisplay(), 'white', TestCancel())
        self.assertIsInstance(game3.board, Board)
        self.assertIsInstance(game3.black_player.strategy, TopLeft)
        self.assertIsInstance(game3.white_player.strategy, BottomRight)
        self.assertEqual(game3.black_player, game3.players[1])
        self.assertEqual(game3.white_player, game3.players[0])
        self.assertTrue(game3.cancel, TestCancel)
        self.assertEqual(game3.result, [])

        game4 = Game(p4, p2, Board(4), TestDisplay())
        self.assertIsInstance(game4.board, Board)
        self.assertIsInstance(game4.black_player.strategy, Foul)
        self.assertIsInstance(game4.white_player.strategy, BottomRight)
        self.assertEqual(game4.black_player, game4.players[0])
        self.assertEqual(game4.white_player, game4.players[1])
        self.assertEqual(game4.cancel, None)
        self.assertEqual(game4.result, [])

        game5 = Game(p1, p5, Board(4), TestDisplay())
        self.assertIsInstance(game5.board, Board)
        self.assertIsInstance(game5.black_player.strategy, TopLeft)
        self.assertIsInstance(game5.white_player.strategy, Foul)
        self.assertEqual(game5.black_player, game5.players[0])
        self.assertEqual(game5.white_player, game5.players[1])
        self.assertEqual(game5.cancel, None)
        self.assertEqual(game5.result, [])

        # play-black-win
        with captured_stdout() as stdout:
            game1.play()

            lines = stdout.getvalue().splitlines()
            output_ret = [
                'display.progress ',
                '   a b c d',
                ' 1□□□□',
                ' 2□●〇□',
                ' 3□〇●□',
                ' 4□□□□',
                ' 〇TopLeft ●BottomRight',
                'display.turn 〇TopLeft [(1, 0), (0, 1), (3, 2), (2, 3)]',
                'display.move (1, 0) [(1, 0), (0, 1), (3, 2), (2, 3)]',
                'display.progress ',
                '   a b c d',
                ' 1□〇□□',
                ' 2□〇〇□',
                ' 3□〇●□',
                ' 4□□□□',
                ' 〇TopLeft ●BottomRight',
                'display.turn ●BottomRight [(0, 0), (2, 0), (0, 2)]',
                'display.move (0, 2) [(0, 0), (2, 0), (0, 2)]',
                'display.progress ',
                '   a b c d',
                ' 1□〇□□',
                ' 2□〇〇□',
                ' 3●●●□',
                ' 4□□□□',
                ' 〇TopLeft ●BottomRight',
                'display.turn 〇TopLeft [(0, 3), (1, 3), (2, 3), (3, 3)]',
                'display.move (0, 3) [(0, 3), (1, 3), (2, 3), (3, 3)]',
                'display.progress ',
                '   a b c d',
                ' 1□〇□□',
                ' 2□〇〇□',
                ' 3●〇●□',
                ' 4〇□□□',
                ' 〇TopLeft ●BottomRight',
                'display.turn ●BottomRight [(0, 0), (2, 0)]',
                'display.move (2, 0) [(0, 0), (2, 0)]',
                'display.progress ',
                '   a b c d',
                ' 1□〇●□',
                ' 2□●●□',
                ' 3●〇●□',
                ' 4〇□□□',
                ' 〇TopLeft ●BottomRight',
                'display.turn 〇TopLeft [(3, 0), (0, 1), (3, 2)]',
                'display.move (3, 0) [(3, 0), (0, 1), (3, 2)]',
                'display.progress ',
                '   a b c d',
                ' 1□〇〇〇',
                ' 2□●〇□',
                ' 3●〇●□',
                ' 4〇□□□',
                ' 〇TopLeft ●BottomRight',
                'display.turn ●BottomRight [(3, 1), (1, 3)]',
                'display.move (1, 3) [(3, 1), (1, 3)]',
                'display.progress ',
                '   a b c d',
                ' 1□〇〇〇',
                ' 2□●〇□',
                ' 3●●●□',
                ' 4〇●□□',
                ' 〇TopLeft ●BottomRight',
                'display.turn 〇TopLeft [(0, 1), (2, 3)]',
                'display.move (0, 1) [(0, 1), (2, 3)]',
                'display.progress ',
                '   a b c d',
                ' 1□〇〇〇',
                ' 2〇〇〇□',
                ' 3〇●●□',
                ' 4〇●□□',
                ' 〇TopLeft ●BottomRight',
                'display.turn ●BottomRight [(0, 0)]',
                'display.move (0, 0) [(0, 0)]',
                'display.progress ',
                '   a b c d',
                ' 1●〇〇〇',
                ' 2〇●〇□',
                ' 3〇●●□',
                ' 4〇●□□',
                ' 〇TopLeft ●BottomRight',
                'display.turn 〇TopLeft [(3, 2), (2, 3)]',
                'display.move (3, 2) [(3, 2), (2, 3)]',
                'display.progress ',
                '   a b c d',
                ' 1●〇〇〇',
                ' 2〇●〇□',
                ' 3〇〇〇〇',
                ' 4〇●□□',
                ' 〇TopLeft ●BottomRight',
                'display.turn ●BottomRight [(3, 1), (3, 3)]',
                'display.move (3, 3) [(3, 1), (3, 3)]',
                'display.progress ',
                '   a b c d',
                ' 1●〇〇〇',
                ' 2〇●〇□',
                ' 3〇〇●〇',
                ' 4〇●□●',
                ' 〇TopLeft ●BottomRight',
                'display.turn 〇TopLeft [(2, 3)]',
                'display.move (2, 3) [(2, 3)]',
                'display.progress ',
                '   a b c d',
                ' 1●〇〇〇',
                ' 2〇●〇□',
                ' 3〇〇〇〇',
                ' 4〇〇〇●',
                ' 〇TopLeft ●BottomRight',
                'display.turn ●BottomRight [(3, 1)]',
                'display.move (3, 1) [(3, 1)]',
                'display.progress ',
                '   a b c d',
                ' 1●〇〇〇',
                ' 2〇●●●',
                ' 3〇〇〇●',
                ' 4〇〇〇●',
                ' 〇TopLeft ●BottomRight',
                'display.win 〇TopLeft',
            ]
            self.assertEqual(lines, output_ret)
            self.assertEqual(game1.result.winlose, Game.BLACK_WIN)
            self.assertEqual(game1.result.black_name, 'TopLeft')
            self.assertEqual(game1.result.white_name, 'BottomRight')
            self.assertEqual(game1.result.black_num, 10)
            self.assertEqual(game1.result.white_num, 6)

        # play-white-win
        with captured_stdout() as stdout:
            game2.play()

            lines = stdout.getvalue().splitlines()
            output_ret = [
                'display.progress ',
                '   a b c d',
                ' 1□□□□',
                ' 2□●〇□',
                ' 3□〇●□',
                ' 4□□□□',
                ' 〇TopLeft ●TopLeft',
                'display.turn 〇TopLeft [(1, 0), (0, 1), (3, 2), (2, 3)]',
                'display.move (1, 0) [(1, 0), (0, 1), (3, 2), (2, 3)]',
                'display.progress ',
                '   a b c d',
                ' 1□〇□□',
                ' 2□〇〇□',
                ' 3□〇●□',
                ' 4□□□□',
                ' 〇TopLeft ●TopLeft',
                'display.turn ●TopLeft [(0, 0), (2, 0), (0, 2)]',
                'display.move (0, 0) [(0, 0), (2, 0), (0, 2)]',
                'display.progress ',
                '   a b c d',
                ' 1●〇□□',
                ' 2□●〇□',
                ' 3□〇●□',
                ' 4□□□□',
                ' 〇TopLeft ●TopLeft',
                'display.turn 〇TopLeft [(0, 1), (3, 2), (2, 3)]',
                'display.move (0, 1) [(0, 1), (3, 2), (2, 3)]',
                'display.progress ',
                '   a b c d',
                ' 1●〇□□',
                ' 2〇〇〇□',
                ' 3□〇●□',
                ' 4□□□□',
                ' 〇TopLeft ●TopLeft',
                'display.turn ●TopLeft [(2, 0), (0, 2)]',
                'display.move (2, 0) [(2, 0), (0, 2)]',
                'display.progress ',
                '   a b c d',
                ' 1●●●□',
                ' 2〇〇●□',
                ' 3□〇●□',
                ' 4□□□□',
                ' 〇TopLeft ●TopLeft',
                'display.turn 〇TopLeft [(3, 0), (3, 1), (3, 2), (3, 3)]',
                'display.move (3, 0) [(3, 0), (3, 1), (3, 2), (3, 3)]',
                'display.progress ',
                '   a b c d',
                ' 1●●●〇',
                ' 2〇〇〇□',
                ' 3□〇●□',
                ' 4□□□□',
                ' 〇TopLeft ●TopLeft',
                'display.turn ●TopLeft [(0, 2), (3, 2), (1, 3)]',
                'display.move (0, 2) [(0, 2), (3, 2), (1, 3)]',
                'display.progress ',
                '   a b c d',
                ' 1●●●〇',
                ' 2●●〇□',
                ' 3●●●□',
                ' 4□□□□',
                ' 〇TopLeft ●TopLeft',
                'display.turn 〇TopLeft [(0, 3), (2, 3)]',
                'display.move (0, 3) [(0, 3), (2, 3)]',
                'display.progress ',
                '   a b c d',
                ' 1●●●〇',
                ' 2●●〇□',
                ' 3●〇●□',
                ' 4〇□□□',
                ' 〇TopLeft ●TopLeft',
                'display.turn ●TopLeft [(3, 1), (3, 2), (1, 3), (2, 3)]',
                'display.move (3, 1) [(3, 1), (3, 2), (1, 3), (2, 3)]',
                'display.progress ',
                '   a b c d',
                ' 1●●●〇',
                ' 2●●●●',
                ' 3●〇●□',
                ' 4〇□□□',
                ' 〇TopLeft ●TopLeft',
                'display.turn 〇TopLeft [(3, 2)]',
                'display.move (3, 2) [(3, 2)]',
                'display.progress ',
                '   a b c d',
                ' 1●●●〇',
                ' 2●●●〇',
                ' 3●〇〇〇',
                ' 4〇□□□',
                ' 〇TopLeft ●TopLeft',
                'display.turn ●TopLeft [(1, 3), (2, 3), (3, 3)]',
                'display.move (1, 3) [(1, 3), (2, 3), (3, 3)]',
                'display.progress ',
                '   a b c d',
                ' 1●●●〇',
                ' 2●●●〇',
                ' 3●●〇〇',
                ' 4〇●□□',
                ' 〇TopLeft ●TopLeft',
                'display.turn 〇TopLeft [(2, 3)]',
                'display.move (2, 3) [(2, 3)]',
                'display.progress ',
                '   a b c d',
                ' 1●●●〇',
                ' 2●●●〇',
                ' 3●●〇〇',
                ' 4〇〇〇□',
                ' 〇TopLeft ●TopLeft',
                'display.turn ●TopLeft [(3, 3)]',
                'display.move (3, 3) [(3, 3)]',
                'display.progress ',
                '   a b c d',
                ' 1●●●〇',
                ' 2●●●〇',
                ' 3●●●〇',
                ' 4〇〇〇●',
                ' 〇TopLeft ●TopLeft',
                'display.win ●TopLeft',
            ]
            self.assertEqual(lines, output_ret)
            self.assertEqual(game2.result.winlose, Game.WHITE_WIN)
            self.assertEqual(game2.result.black_name, 'TopLeft')
            self.assertEqual(game2.result.white_name, 'TopLeft')
            self.assertEqual(game2.result.black_num, 6)
            self.assertEqual(game2.result.white_num, 10)

        # play-cancel-draw
        with captured_stdout() as stdout:
            game3.play()

            lines = stdout.getvalue().splitlines()
            output_ret = [
                'display.progress ',
                '   a b c d',
                ' 1□□□□',
                ' 2□●〇□',
                ' 3□〇●□',
                ' 4□□□□',
                ' 〇TopLeft ●BottomRight',
                'cancel-event is set',
                'display.draw',
            ]
            self.assertEqual(lines, output_ret)
            self.assertEqual(game3.result.winlose, Game.DRAW)
            self.assertEqual(game3.result.black_name, 'TopLeft')
            self.assertEqual(game3.result.white_name, 'BottomRight')
            self.assertEqual(game3.result.black_num, 2)
            self.assertEqual(game3.result.white_num, 2)

        # play-black-foul
        with captured_stdout() as stdout:
            game4.play()

            lines = stdout.getvalue().splitlines()
            output_ret = [
                'display.progress ',
                '   a b c d',
                ' 1□□□□',
                ' 2□●〇□',
                ' 3□〇●□',
                ' 4□□□□',
                ' 〇Foul ●BottomRight',
                'display.turn 〇Foul [(1, 0), (0, 1), (3, 2), (2, 3)]',
                'display.move (2, 2) [(1, 0), (0, 1), (3, 2), (2, 3)]',
                'display.progress ',
                '   a b c d',
                ' 1□□□□',
                ' 2□●〇□',
                ' 3□〇〇□',
                ' 4□□□□',
                ' 〇Foul ●BottomRight',
                'display.foul 〇Foul',
                'display.win ●BottomRight',
            ]
            self.assertEqual(lines, output_ret)
            self.assertEqual(game4.result.winlose, Game.WHITE_WIN)
            self.assertEqual(game4.result.black_name, 'Foul')
            self.assertEqual(game4.result.white_name, 'BottomRight')
            self.assertEqual(game4.result.black_num, 3)
            self.assertEqual(game4.result.white_num, 1)

        # play-white-foul
        with captured_stdout() as stdout:
            game5.play()

            lines = stdout.getvalue().splitlines()
            output_ret = [
                'display.progress ',
                '   a b c d',
                ' 1□□□□',
                ' 2□●〇□',
                ' 3□〇●□',
                ' 4□□□□',
                ' 〇TopLeft ●Foul',
                'display.turn 〇TopLeft [(1, 0), (0, 1), (3, 2), (2, 3)]',
                'display.move (1, 0) [(1, 0), (0, 1), (3, 2), (2, 3)]',
                'display.progress ',
                '   a b c d',
                ' 1□〇□□',
                ' 2□〇〇□',
                ' 3□〇●□',
                ' 4□□□□',
                ' 〇TopLeft ●Foul',
                'display.turn ●Foul [(0, 0), (2, 0), (0, 2)]',
                'display.move (2, 2) [(0, 0), (2, 0), (0, 2)]',
                'display.progress ',
                '   a b c d',
                ' 1□〇□□',
                ' 2□〇〇□',
                ' 3□〇●□',
                ' 4□□□□',
                ' 〇TopLeft ●Foul',
                'display.foul ●Foul',
                'display.win 〇TopLeft',
            ]
            self.assertEqual(lines, output_ret)
            self.assertEqual(game5.result.winlose, Game.BLACK_WIN)
            self.assertEqual(game5.result.black_name, 'TopLeft')
            self.assertEqual(game5.result.white_name, 'Foul')
            self.assertEqual(game5.result.black_num, 4)
            self.assertEqual(game5.result.white_num, 1)
Esempio n. 8
0
    def do_alpha_beta_pruning(depth, matrix, player, avail_moves):
        """ Do minimax algorithm with alpha-beta pruning to reduce analysis
        time and improve AI level"""

        # Raise exception (unhandled case)
        if not avail_moves:
            raise Exception("Encountered Error!")

        result_list = []

        # Determine the opponent
        if player == Player.PLAYER:
            opponent = Player.COMPUTER
        else:
            opponent = Player.PLAYER

        #
        # Reached to the deepest part of the given tree
        #

        if depth == 0:
            # Calculate all of the node's values and return the one
            # with highest value
            for position in avail_moves:
                val = Game.predict_score(player, position, matrix)
                result_list.append(
                    [position, Utilities.calc_value(player, val)])

            return Game.get_best_pair(result_list)

        #
        # On the normal state of tree.
        #

        # Sort input
        avail_moves = Utilities.sort(avail_moves)

        # Start to check input for actions
        for position in avail_moves:
            # Corner field. Get it at all costs!
            if position in Field.ADVANTAGE:
                val = Game.predict_score(player, position, matrix)
                return [position, Utilities.calc_value(player, val)]

            # Disadvantage field. Handle with cares.
            if position in Field.DISADVANTAGE:
                # Get player's flips and score
                player_flips = Game.get_flip_traces(player, position, matrix)
                player_flips.append(position)
                matrix_virtual = Utilities.clone_matrix(matrix)
                player_val = Game.make_move(player, position, matrix_virtual)

                # Dig down 1 level
                # Get opponent's possible moves
                opponent_moves = Game.get_available_moves(
                    opponent, matrix_virtual)
                max_penalty = None

                # Check if any of player's flip is on the way of opponent
                for p in opponent_moves:
                    # Who cares if opponent doesn't wanna take border?
                    if p not in Field.BORDER:
                        continue

                    opponent_flips = Game.get_flip_traces(
                        opponent, p, matrix_virtual)

                    for f in player_flips:
                        if f in opponent_flips:
                            if max_penalty is None or \
                                    max_penalty < (len(opponent_flips) + 1):
                                max_penalty = len(opponent_flips) + 1

                if max_penalty is None:
                    # No danger thread. Take the advantage of border
                    if position in Field.BORDER_DISADVANTAGE:
                        return [
                            position,
                            Utilities.calc_value(player, player_val)
                        ]
                    else:
                        # Pass to next case (normal field)
                        pass
                else:
                    result_list.append([
                        position,
                        Utilities.calc_value(player, player_val - max_penalty)
                    ])

            # Normal field
            # Check if opponent has move on the virtual matrix
            matrix_virtual = Utilities.clone_matrix(matrix)
            val = Game.make_move(player, position, matrix_virtual)

            # Check for next turn
            opponent_moves = Game.get_available_moves(opponent, matrix_virtual)

            if not opponent_moves:
                # Check if the player has move on the virtual matrix
                player_moves = Game.get_available_moves(player, matrix_virtual)

                if not player_moves:
                    # Both has no move, reached to the end game.
                    player_val, computer_val = \
                        Utilities.calc_matrix_score(matrix_virtual)

                    # Set priority of end game with win flag on top
                    if computer_val > player_val:
                        return [position, 64]

                    if player_val > computer_val:
                        val = -64

                    result_list.append(
                        [position, Utilities.calc_value(player, val)])
                    continue

                result_list.append(
                    [position, Utilities.calc_value(player, 32)])
                continue

            # Opponent has move. Process normally.
            best_move = Algorithm.do_alpha_beta_pruning(
                depth - 1, matrix_virtual, opponent, opponent_moves)
            result_list.append([position, best_move[1]])

        return Game.get_best_pair(result_list)
Esempio n. 9
0
    def do_minimax(depth, matrix, player, avail_moves):
        """Do a plain minimax scan on the matrix for best position"""
        # Raise exception (unhandled case)
        if not avail_moves:
            raise Exception("Encountered Error!")

        result_list = []

        # Determine the opponent
        if player == Player.PLAYER:
            opponent = Player.COMPUTER
        else:
            opponent = Player.PLAYER

        #
        # Reached to the deepest part of the given tree
        #

        if depth == 0:
            # Calculate all of the node's values and return the one
            # with highest value
            for position in avail_moves:
                val = Game.predict_score(player, position, matrix)
                result_list.append(
                    [position, Utilities.calc_value(player, val)])

            return Game.get_best_pair(result_list)

        for position in avail_moves:
            matrix_virtual = Utilities.clone_matrix(matrix)
            val = Game.make_move(player, position, matrix_virtual)

            # Check for next turn
            opponent_moves = Game.get_available_moves(opponent, matrix_virtual)

            if not opponent_moves:
                # Check if the player has move on the virtual matrix
                player_moves = Game.get_available_moves(player, matrix_virtual)

                if not player_moves:
                    # Both has no move, reached to the end game.
                    player_val, computer_val = \
                        Utilities.calc_matrix_score(matrix_virtual)

                    # Set priority of end game with win flag on top
                    if computer_val > player_val:
                        return [position, 64]

                    if player_val > computer_val:
                        val = -64

                    result_list.append(
                        [position, Utilities.calc_value(player, val)])
                    continue

                # Opponent has no moves at this point
                # One extra move for current player
                best_move = Algorithm.do_minimax(depth - 1, matrix_virtual,
                                                 opponent, opponent_moves)
                result_list.append([position, best_move[1]])

            # Opponent has move. Process normally.
            best_move = Algorithm.do_minimax(depth - 1, matrix_virtual,
                                             opponent, opponent_moves)
            result_list.append([position, best_move[1]])

        return Game.get_best_pair(result_list)
Esempio n. 10
0
from reversi.game import Game
from reversi.players import Player_Human, Player_Weighted

if __name__ == "__main__":
    g = Game(playerB=Player_Human(), playerW=Player_Weighted())
    g.play()