【问题标题】:Java Minimax tic-tac-toe game not working as intendedJava Minimax tic-tac-toe 游戏未按预期工作
【发布时间】:2019-06-25 17:48:55
【问题描述】:

因此,我一直在研究创建一个简单的井字游戏,其中人类玩家与由极小极大算法运行的 AI 进行游戏。在过去的几天里,我一直在试图找出这两个错误,但我似乎一辈子都做不到。一方面,人工智能似乎有点可预测并且不是很好。其次,它似乎唯一可行的方法是如果人工智能先行,如果我让人类玩家先行,人工智能就会继续填补下一个可用位置。任何帮助将不胜感激。

这是我的代码:

import java.util.Scanner;
public class Game 
{

    static String player = "X";
    static String opponent = "O";
    int row;
    int col;
    public Game(int x, int y)
    {
        row = x;
        col = y;
    }
    public static void main(String[] args)
    {
        Scanner input = new Scanner(System.in);
        String [][] board = new String [3][3];
        fillBoard(board);
        while(true) //Infinite loop only for testing, will change back
        {
            getBestMove(board);
            printBoard(board);
            playerTurn(board, input);
            printBoard(board);
            //System.out.println("Best move: " + bestMove.row + " " + bestMove.col);
        }
        //input.close();
    }
    static int checkState(String [][] board) 
    { 

        for (int row = 0; row<3; row++) //Rows
        { 
            if (board[row][0] == board[row][1] && 
                board[row][1] == board[row][2]) 
            { 
                if (board[row][0]==player) 
                    return -10; 
                else if (board[row][0]==opponent) 
                    return +10; 
            } 
        } 


        for (int col = 0; col<3; col++) //Columns
        { 
            if (board[0][col]==board[1][col] && 
                board[1][col]==board[2][col]) 
            { 
                if (board[0][col]==player) 
                    return -10; 

                else if (board[0][col]==opponent) 
                    return +10; 
            } 
        } 


        if (board[0][0]==board[1][1] && board[1][1]==board[2][2]) //Diagonal
        { 
            if (board[0][0]==player) 
                return -10; 
            else if (board[0][0]==opponent) 
                return +10; 
        } 

        else if (board[0][2]==board[1][1] && board[1][1]==board[2][0]) //Diagonal
        { 
            if (board[0][2]==player) 
                return -10; 
            else if (board[0][2]==opponent) 
                return +10; 
        } 

        return 0; 
    } 

    public static void getBestMove(String[][] board)
    {
        int bestValue = -1000;
        Game bestMove = new Game(-1,-1);

        for(int i = 0; i < 3; i++)
        {
            for(int j = 0; j < 3; j++)
            {
                if(board[i][j] == "-")
                {
                    board[i][j] = player;
                    int currentValue = minimax(board, 0, false);
                    board[i][j] = "-";
                    if(currentValue > bestValue)
                    {
                        bestMove.row = i;
                        bestMove.col = j;
                        bestValue = currentValue;
                    }
                }


            }
        } 
        board[bestMove.row][bestMove.col]= opponent; 
    }
    public static int minimax(String [][] board, int depth, boolean isMaximizer)
    {
        if(checkState(board) != 0)
            return checkState(board);

        if(checkRemainingPlays(board) == false)
            return 0;

        if(isMaximizer)
        {
            int highest = -1000;
            for(int i = 0; i < 3; i++)
            {
                for(int j = 0; j < 3; j++)
                {
                    if(board[i][j] == "-")
                    {
                        board[i][j] = player;
                        highest = Math.max(highest,  minimax(board, depth + 1, !isMaximizer));
                        board[i][j] = "-";
                    }

                }
            }
            return highest;
        }
        else
        {
            int lowest = 1000;
            for(int i = 0; i < 3; i++)
            {
                for(int j = 0; j < 3; j++)
                {
                    if(board[i][j] == "-")
                    {
                        board[i][j] = opponent;
                        lowest = Math.min(lowest,  minimax(board, depth + 1, !isMaximizer));
                        board[i][j] = "-";
                    }
                }
            }
            return lowest;
        }
    }



    public static void playerTurn(String [][] board , Scanner input)
    {
        input = new Scanner(System.in);

        System.out.println("Player 1: ");


        System.out.println("Please enter the index of desired spot (I) ");
        int desiredIndexI = input.nextInt();
        System.out.println("Please enter the index of desired spot (J) ");
        int desiredIndexJ = input.nextInt();
        while(board[desiredIndexI][desiredIndexJ] != "-")
        {
            System.out.println("Please enter the index of desired spot (I) ");
            desiredIndexI = input.nextInt();
            System.out.println("Please enter the index of desired spot (J) ");
            desiredIndexJ = input.nextInt();
        }


        board[desiredIndexI][desiredIndexJ] = player;


    }

    public static boolean checkRemainingPlays(String [][] board)
    {
        for(int i = 0; i < board.length; i++) 
        {
            for(int j = 0; j < board[i].length; j++) 
            {
                if (board[i][j] == "-")
                    return true;
            }
        }
        return false;
    }

    public static void printBoard(String [][] board)
    {
        for(int i = 0; i < board.length; i++) 
        {
            if(i <= 2 && i > 0)
                System.out.println("----------");
            for(int j = 0; j < board[i].length; j++) 
            {
                if(j < 2)
                    System.out.print(board[i][j] + " | ");
                if(j == 2)
                    System.out.println(board[i][j]);
            }
        }
    }
    public static void fillBoard(String [][] board)
    {
        for(int i = 0; i < board.length; i++) 
        {
            for(int j = 0; j < board[i].length; j++) 
            {
                board[i][j] = "-";
            }
        }
    }
}

【问题讨论】:

  • 欢迎来到 Stack Overflow!请理解您的问题归结为“请帮助我解决我的复杂问题”。但我们不将此类请求视为有效问题(详见here)。在这里转储这么多代码,然后人们参与并开始执行您的调试工作是不现实的。
  • 话虽如此:为了调试类似的东西,只需从易于验证的场景开始,例如:让“AI”查看可以立即做出获胜动作的棋盘。如果失败,请调试该失败。然后,编写另一个测试,在下一步中有机会获胜。等等。它通常还有助于您准确地预测应该发生什么样的计算,然后将其与实际结果进行比较。但如前所述:这是一项繁重的工作,并且期望互联网上的志愿者为您解决您的有趣项目......是相当不现实的。
  • 看起来getBestMoveminimax 正试图为player 寻找行动。他们应该为opponent 寻找行动。
  • 顺便说一句,要正确格式化代码,请选择代码,然后按代码按钮。该按钮类似于 {},位于编辑窗格的顶部。
  • 欢迎来到 StackOverflow。请按照您创建此帐户时的建议阅读并遵循帮助文档中的发布指南。 Minimal, complete, verifiable example 适用于此。在您发布 MCVE 代码并准确说明问题之前,我们无法有效地帮助您。我们应该能够将您发布的代码粘贴到文本文件中并重现您指定的问题。 StackOverflow 不是设计、编码、研究或教程资源。 “不起作用”不是问题规范。

标签: java artificial-intelligence minimax game-theory


【解决方案1】:

首先,我想先从好消息说起。使用 minimax 算法解决井字游戏是人工智能初学者的一个很好的培训。问题并不容易,它很好地教导了人工智能规划是什么。使用 Java 实现游戏加上求解器也是一个不错的选择,因为该语言无处不在,支持面向对象编程,执行速度合理。

现在我想介绍关键方面。第一个问题是,人工智能相关问题与正常的计算任务有很大不同。如果源代码是关于将 AWT Java GUI 绘制到屏幕上,或者关于如何向类发送参数,我相信这个问题可以很容易地回答。在大多数情况下,AI 主题不会因为编程问题而失败,即如何使用某种编程语言,而是因为底层算法。

描述和解决人工智能问题的讨论空间不在编程领域,而是在古腾堡星系。这意味着,围绕人工智能玩井字游戏和 Minimax 算法,至少有 1000 篇论文、书籍和 powerpoint 演示文稿可用。新手的任务不是编写 Java 源代码,而是阅读和引用这些源代码。这有助于其他人了解问题并提供详细的反馈。

我知道,这个道德指导并没有回答最初的问题,但目的是解释为什么我按下了“将问题迁移到https://ai.stackexchange.com/”按钮。在这个论坛里,问题会很快得到答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-27
    • 1970-01-01
    • 2023-04-07
    • 2021-07-18
    • 1970-01-01
    • 2018-10-16
    • 1970-01-01
    相关资源
    最近更新 更多