Java Minimax игра в крестики-нолики не работает, как задумано - PullRequest
0 голосов
/ 25 июня 2019

Итак, я пытался создать простую игру в крестики-нолики, в которой игрок-человек играет против 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] = "-";
            }
        }
    }
}

1 Ответ

0 голосов
/ 03 июля 2019

Сначала я хотел бы начать с хороших новостей.Решение Tic Tac Toe с минимаксным алгоритмом - отличная тренировка для начинающих в искусственном интеллекте.Проблема не в том, что легко, а в том, что такое планирование ИИ.Использование Java для реализации игры и решателя также является хорошим выбором, потому что язык работает везде, поддерживает объектно-ориентированное программирование и достаточно быстр для выполнения.

Теперь я хотел бы представить критические аспекты.Первая проблема заключается в том, что проблемы, связанные с ИИ, сильно отличаются от обычных вычислительных задач.Если исходный код предназначен для рисования графического интерфейса пользователя AWT на экране или для отправки параметра в класс, я уверен, что на этот вопрос можно легко ответить.В большинстве случаев темы ИИ не терпят неудачу из-за проблем программирования, которые означают, как использовать определенный язык программирования, но из-за основного алгоритма.

Дискуссионная область, в которой проблемы ИИ описаны и решены, нев области программирования, но в галактике Гутенберга.Это означает, что в игровом процессе TicTacToe с использованием искусственного интеллекта и алгоритма Minimax доступно как минимум 1000 статей, книг и презентаций в Powerpoint.Задача для новичка не в том, чтобы написать исходный код Java, а в том, чтобы прочитать и процитировать эти источники.Это помогает другим понять проблему и предоставить подробный отзыв.

Я знаю, что эта моральная инструкция не отвечает на первоначальный вопрос, но цель состояла в том, чтобы объяснить, почему я нажал кнопку «перенести вопрос в *»1007 *https://ai.stackexchange.com/”. На этом форуме вопрос быстро получит ответ.

...