【问题标题】:How to make Minimax Alpha Beta algorithm play itself?如何让 Minimax Alpha Beta 算法发挥自己的作用?
【发布时间】:2019-08-19 15:06:32
【问题描述】:

我已经开发了一个具有 minimax 和 alpha-beta 的有效国际象棋引擎,但是我想通过自己玩计算机与计算机来测试我的算法。我已经尝试了一切都无济于事。只是想知道我会怎么做?

public class Main {  

static JTextArea textField;

    public static void main(String[] args) {


        while ( 'K' != ABChess.board[ABChess.kingLocationUU/8][ABChess.kingLocationUU%8]) {ABChess.kingLocationUU++;}
        while ( 'k' != ABChess.board[ABChess.kingLocationLL/8][ABChess.kingLocationLL%8]) {ABChess.kingLocationLL++;}

        Asset.init("/images/ChessPiecess.png");

        ABChess.updateKingLocations();
        //print();  

        JPanel depthPanel = depthPanel();
        JPanel optionPanel = optionPanel();
        JPanel logPanel = logPanel();

        JPanel menuPanel = new JPanel();
        menuPanel.setPreferredSize(new Dimension(140, 100));
        menuPanel.setLayout(new BoxLayout(menuPanel, BoxLayout.Y_AXIS));
        menuPanel.add(depthPanel);
        menuPanel.add(optionPanel);
        menuPanel.add(logPanel);


        GUInterface gui = new GUInterface();

        JPanel panel = new JPanel(new BorderLayout());
        panel.add(gui);
        panel.add(menuPanel, BorderLayout.EAST);

        JFrame frame = new JFrame(ABChess.title);

        frame.setSize(ABChess.width, ABChess.height);
        frame.add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(true);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);        

        System.out.println(ABChess.possibleMoves());
        ABChess.playerChoice = JOptionPane.showOptionDialog(null, "Who wants to make the first move?", "Who moves first?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, ABChess.options, ABChess.options[0]);

        if (ABChess.playerChoice == 0){
            ABChess.flipBoard();
            long startTime=System.currentTimeMillis();
            Move autoMove = AlphaBeta.alphaBeta(ABChess.gameDepth, 1000000, -1000000, new Move(), 0);
            long endTime=System.currentTimeMillis();
            ABChess.makeMove(autoMove);
            ABChess.flipBoard();
            System.out.println("COMPUTER'S MOVE TOOK "+((endTime-startTime)/1000.0)+" SECONDS");                        
            ABChess.printBoard();
            frame.repaint();
            displayMessage("Took "+((endTime-startTime)/1000.0)+" seconds");
        }

    }

这是运行文件时对算法的初始调用。

public void mousePressed(MouseEvent event) {
        if ( event.getX() < 8*sizeOfSquare && event.getY() < 8*sizeOfSquare) {
            mouseX = event.getX();
            mouseY = event.getY();
            repaint();
        }
    }


    public void mouseReleased(MouseEvent event) {
        if  (event.getX() < 8*sizeOfSquare && event.getY() < 8*sizeOfSquare) {
            newMouseX = event.getX();
            newMouseY = event.getY();
            if (event.getButton() == MouseEvent.BUTTON1) {
                // Regular move
                Move legalMovesMove = new Move(mouseY/sizeOfSquare, mouseX/sizeOfSquare, newMouseY/sizeOfSquare, newMouseX/sizeOfSquare, Test6.board[newMouseY/sizeOfSquare][newMouseX/sizeOfSquare]);

                java.util.List<Move> legalMoves = ABChess.possibleMoves();
                for(Move m : legalMoves) {
                    if (m.equals(legalMovesMove)) {
                        ABChess.makeMove(legalMovesMove);
                        ABChess.flipBoard();
                        long startTime=System.currentTimeMillis();
                        Move autoMove = AlphaBeta.alphaBeta(ABChess.gameDepth, 1000000, -1000000, new Move(), 0);
                        long endTime=System.currentTimeMillis();
                        ABChess.makeMove(autoMove);
                        ABChess.flipBoard();
                        System.out.println("COMPUTER'S MOVE TOOK "+((endTime-startTime)/1000.0)+" SECONDS");                        
                        ABChess.printBoard();
                        repaint();

                    }
                }

                checkMate = ABChess.kingSafe();

                if(checkMate == false){
                   int yes = JOptionPane.showOptionDialog(null, "Do you want to make the first move?", "Who moves first?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, JOptionPane.YES_OPTION);

                   if (yes == JOptionPane.YES_OPTION){
                       ABChess.resetGame();
                        repaint();

                   } else if (yes == JOptionPane.NO_OPTION){
                              System.exit(0);  
                   }
                }

                legalMoves = ABChess.possibleMoves();

                if (legalMoves.size() == 0) {
                    ABChess.playAgain = JOptionPane.showOptionDialog(null, "Stalemate! Wanna play again?", "Draw!", JOptionPane.YES_NO_OPTION,
                            JOptionPane.QUESTION_MESSAGE, null, ABChess.choice, ABChess.choice[1]);

                    if (ABChess.playAgain == 0) {
                        System.out.println("Yes I will");
                        ABChess.resetGame();
                        repaint();
                    } else {
                        System.exit(0);


                    }
                }
            }
        }
    }

这是每次释放鼠标时调用算法的地方。不知道如何编码到它与白色棋子而不是我一起玩的地方。

【问题讨论】:

    标签: java artificial-intelligence chess minimax alpha-beta-pruning


    【解决方案1】:

    我通常会将 Player 与 Game 分开,而 Game 会请求来自 Player 对象的交互。 Player 对象可以是人类(因此所需的输入被委托给某些 UI)或 AI,因此它将被委托给某些实现,从而决定哪个动作是最佳的。

    我建议对 ABChess 游戏使用对象而不是静态方法。

    因此,通过一些重构并将 UI 与逻辑分离,它可能看起来像这样:

    interface Player {
        Move decide(List<Move> legalMoves);
    }
    
    class ChessGame {
    
        ABChess game;
    
        Player player1;
        Player player2;
        UIInterface ui;
    
        ChessGame(Player player1, Player player2, UIInterface ui) {
            this.player1 = player1;
            this.player2 = player2;
            this.ui = ui;
    
            game = ...
        }
    
        public void simulate() {
    
            // ... initial ui ...
    
            boolean player1Turn = true;
    
            do {
                Move move = null;
    
                if (player1Turn) {
                    move = player1.decide(game.possibleMoves());
                } else {
                    move = player2.decide(game.possibleMoves());
                }
    
                game.makeMove(move);
                // ... update ui ...
    
                player1Turn = !player1Turn;
    
            // check if somebody has won ...
            } while (game.isRunning());
    
            // ... update ui with the game result ...
        }
    }
    

    一旦完成,模拟游戏就变得容易了。您只需要使用适当的播放器启动ChessGame 并调用模拟方法。此时,您还可以决定完全跳过 UI 演示(这样学习会更快)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多