How to make Minimax Alpha Beta algorithm play itself?

Jordan Oguns :

I've developed a working chess engine with minimax and alpha-beta, however I want to test my algorithm by playing itself, computer vs computer. I have tried everything to no avail. Just wondering how I would go about this?

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");
        }

    }

This is the initial call to the algorithm when the file is ran.

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);


                    }
                }
            }
        }
    }

This is where the algorithm is called every time the mouse is released. Not sure how to code to where it plays itself with the white pieces instead of me.

second :

I would normally seperate the Player from the Game, and the Game would request the interaction from the Player object. The Player object would either be a Human (so the needed input is delegated to some UI) or an AI so it would be delegated to some implementation which decides which move is best.

I would recommend using an object for the ABChess Game instead of static methods.

So with a bit of refactoring and seperating the UI from the logic as well, it could look like this:

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 ...
    }
}

Once that is done simulating games becomes easy. You just need to initiate the ChessGame with the proper players and call the simulate method. At that point you could also decide to skip the UI presentation completly (so the learning will be much faster).

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=145445&siteId=1