使用MiniMax返回移动

时间:2015-01-05 23:00:31

标签: java recursion tic-tac-toe minimax

我的代码正常运行,程序运行完美!原来问题还涉及计算机在需要时不返回0。感谢所有帮助过的人。如果有人需要任何帮助,请查看下面的代码。

import java.util.Scanner;

    public class TicTacToeSolver{
        public static void main(String[] args){
            Scanner input=new Scanner(System.in);

            char[] board={0,0,0,0,0,0,0,0,0};
            int player=1,move;

            System.out.println("Tic-Tac-Toe:");
            while (true){
                PrintBoard(board);   
                if (player==1){
                    System.out.print("Enter move: ");
                    move=input.nextInt();
                    if (ValidMove(board,move)==true){
                        board[move-1]='X';
                        player=-1;
                    }   
                }
                else{
                    board[MiniMax(board,player,0,9)[1]]='O';
                    player=1;
                }
                if(CheckWin(board)!=0){
                    PrintBoard(board);
                    System.out.println("You lost!");
                    System.exit(0);
                }
                else if (CheckDraw(board)==true){
                    PrintBoard(board);
                    System.out.println("Draw!");
                    System.exit(0);
                }
            }
        }
        public static boolean ValidMove(char[]board,int move){
            if(move>=1 && move<=9){
                if (board[move-1]==0){
                    return true;
                }
            }
            return false;
        }
        public static int CheckWin(char[] board){
            if (board[0]=='X' && board[1]=='X' && board[2]=='X'||//Horizontal.
                    board[3]=='X' && board[4]=='X' && board[5]=='X' ||
                    board[6]=='X' && board[7]=='X' && board[8]=='X' ||
                    board[0]=='X' && board[4]=='X' && board[8]=='X' ||//Diagonal.
                    board[2]=='X' && board[4]=='X' && board[6]=='X' ||
                    board[0]=='X' && board[3]=='X' && board[6]=='X' ||//Vertical.
                    board[1]=='X' && board[4]=='X' && board[7]=='X' ||
                    board[2]=='X' && board[5]=='X' && board[8]=='X'){
                return -1;
            }
            else if (board[0]=='O' && board[1]=='O' && board[2]=='O'||//Horizontal.
                    board[3]=='O' && board[4]=='O' && board[5]=='O' ||
                    board[6]=='O' && board[7]=='O' && board[8]=='O' ||
                    board[0]=='O' && board[4]=='O' && board[8]=='O' ||//Diagonal.
                    board[2]=='O' && board[4]=='O' && board[6]=='O' ||
                    board[0]=='O' && board[3]=='O' && board[6]=='O' ||//Vertical.
                    board[1]=='O' && board[4]=='O' && board[7]=='O' ||
                    board[2]=='O' && board[5]=='O' && board[8]=='O'){
                return 1;
            }
            return 0;
        }
        public static boolean CheckDraw(char[] board){
            int total=0;
            for (int i=0;i<9;i++){
                if (board[i]!=0){
                    total+=1;
                }
            }
            if (total==9){
                return true;
            }
            return false;
        }
        public static void PrintBoard(char[] board){   
            System.out.println("------------------------------");
            System.out.println(board[0]+"|"+board[1]+"|"+board[2]);
            System.out.println("-+-+-");
            System.out.println(board[3]+"|"+board[4]+"|"+board[5]);
            System.out.println("-+-+-");
            System.out.println(board[6]+"|"+board[7]+"|"+board[8]); 
            System.out.println("\n");
        }
        public static int[] MiniMax(char[] board,int player,int depth, int maxDepth){
            int bestScore,bestMove=-1,score;

            if (CheckWin(board)!=0||depth==maxDepth){
                return new int[] {CheckWin(board),bestMove};
            }
            if (CheckDraw(board)==true){
                return new int[] {0,bestMove};
            }   
            if (player==-1){
                bestScore=-9999;
            }
            else{
                bestScore=9999;
            }
            for (int i=0;i<9;i++){
                if (board[i]==0){
                    if (player==-1){
                        board[i]='O';
                        score=MiniMax(board,player*-1,depth+1,maxDepth)[0];
                        board[i]=0;

                        if (score>bestScore){
                            bestScore=score;
                            bestMove=i;
                        }
                    }
                    else{
                        board[i]='X';
                        score=MiniMax(board,player*-1,depth+1,maxDepth)[0];
                        board[i]=0;

                        if(score<bestScore){
                            bestScore=score;
                            bestMove=i;
                        }
                    }
                }
            }
            return new int[] {bestScore,bestMove};
        }
    }

2 个答案:

答案 0 :(得分:0)

我想我已经在其他地方回答了这个问题,所以必须有一些人在做这个任务!在第一级以下,您应该只检查以下级别是否返回任何获胜动作。您不需要使用任何值。示例代码:

public List<Location> bestMoves() {
    List<Location> winningMoves = possibleMoves().stream()
            .filter(move -> apply(move).isWinFor(nextPlayer))
            .collect(Collectors.toList());
    if (!winningMoves.isEmpty())
        return winningMoves;
    else
        return possibleMoves().stream()
                .filter(move -> apply(move).bestMoves().isEmpty())
                .collect(Collectors.toList());
}

答案 1 :(得分:0)

您可以通过包含两者的对象返回移动和分数。

public class TicTacToeSolver{
    private static class Move {
        int move;
        int score;
        Move( int m, int s ) {
           move = m;
           score = s;
        }
    }
    ...
 }

您可以像这样返回此对象:

 return new Move( bestScore, bestMove );

在minimax()中,你可以得到这样的分数:

Move candidateMove = MiniMax(board,player*-1,depth+1,maxDepth);
int score = candidateMove.score;

在顶层,你可以得到最好的举动:

 Move bestMove = MiniMax(board,player,0,9);
 int move = bestMove.move;