确定计算机决定在Tic Tac Toe中移动

时间:2015-01-04 18:14:24

标签: java

我的tic tac toe游戏完成了90%,但是无法弄清楚如何确定计算机生成的移动。我尝试了很多事情,没有成功。

我现在的代码现在确定了计算机的随机移动,但是仍然可以覆盖用户输入的移动并且是一个小小的错误。

我在代码中标记了我需要帮助的具体位置。

//12/14/2014
//The purpose of this program is to play a tic tac toe game against the computer
//The TicTacToe class.

import java.awt.*;
import java.io.*;
import java.util.*;

public class TicTacToe
{
    static boolean GameOver = false ;

    public static char DrawBoard (char [] [] Board)        //DrawBoard Method
    {

        char DrawBoard = '-' ;

        System.out.println("-------------");

        for (int row = 0 ; row < 3 ; row = row + 1) 
        {
            System.out.print ("| ") ;
            for (int column = 0 ; column < 3 ; column = column + 1) 
            {
                System.out.print (Board [row] [column] + " | ") ;
                DrawBoard = Board [row] [column] ;
            }
            System.out.println () ;
            System.out.println ("-------------") ;
        }
        return (DrawBoard) ;
    }



    public static void Winner (char [] [] Board)        //Winner Method
    {
        if (Board [0] [0] == 'X' && Board [0] [1] == 'X' && Board [0] [2] == 'X')
        {
            System.out.println ("You have won! Congratulations.") ;
            GameOver = true ;
        }

        if (Board [1] [0] == 'X' && Board [1] [1] == 'X' && Board [1] [2] == 'X')
        {
            System.out.println ("You have won! Congratulations.") ;
            GameOver = true ;
        }

        if (Board [2] [0] == 'X' && Board [2] [1] == 'X' && Board [2] [2] == 'X')
        {
            System.out.println ("You have won! Congratulations.") ;
            GameOver = true ;
        }

        if (Board [0] [0] == 'X' && Board [1] [0] == 'X' && Board [2] [0] == 'X')
        {
            System.out.println ("You have won! Congratulations.") ;
            GameOver = true ;
        }

        if (Board [0] [1] == 'X' && Board [1] [1] == 'X' && Board [2] [1] == 'X')
        {
            System.out.println ("You have won! Congratulations.") ;
            GameOver = true ;
        }

        if (Board [0] [2] == 'X' && Board [1] [2] == 'X' && Board [2] [2] == 'X')
        {
            System.out.println ("You have won! Congratulations.") ;
            GameOver = true ;
        }

        if (Board [0] [0] == 'X' && Board [1] [1] == 'X' && Board [2] [2] == 'X')
        {
            System.out.println ("You have won! Congratulations.") ;
            GameOver = true ;
        }

        if (Board [0] [2] == 'X' && Board [1] [1] == 'X' && Board [2] [0] == 'X')
        {
            System.out.println ("You have won! Congratulations.") ;
            GameOver = true ;
        }
    }



    public static void Loser (char [] [] Board)        //Loser Method
    {
        if (Board [0] [0] == 'O' && Board [0] [1] == 'O' && Board [0] [2] == 'O')
        {
            System.out.println ("You have lost! Better luck next time.") ;
            GameOver = true ;
        }

        if (Board [1] [0] == 'O' && Board [1] [1] == 'O' && Board [1] [2] == 'O')
        {
            System.out.println ("You have lost! Better luck next time.") ;
            GameOver = true ;
        }

        if (Board [2] [0] == 'O' && Board [2] [1] == 'O' && Board [2] [2] == 'O')
        {
            System.out.println ("You have lost! Better luck next time.") ;
            GameOver = true ;
        }

        if (Board [0] [0] == 'O' && Board [1] [0] == 'O' && Board [2] [0] == 'O')
        {
            System.out.println ("You have lost! Better luck next time.") ;
            GameOver = true ;
        }

        if (Board [0] [1] == 'O' && Board [1] [1] == 'O' && Board [2] [1] == 'O')
        {
            System.out.println ("You have lost! Better luck next time.") ;
            GameOver = true ;
        }

        if (Board [0] [2] == 'O' && Board [1] [2] == 'O' && Board [2] [2] == 'O')
        {
            System.out.println ("You have lost! Better luck next time.") ;
            GameOver = true ;
        }

        if (Board [0] [0] == 'O' && Board [1] [1] == 'O' && Board [2] [2] == 'O')
        {
            System.out.println ("You have lost! Better luck next time.") ;
            GameOver = true ;
        }

        if (Board [0] [2] == 'O' && Board [1] [1] == 'O' && Board [2] [0] == 'O')
        {
            System.out.println ("You have lost! Better luck next time.") ;
            GameOver = true ;
        }
    }

     public static void Tie (char [] [] Board)        //Tie Method
     {
             for (int row = 0; row < 3; row = row + 1) 
        {
            for (int column = 0; column < 3; column = column + 1) 
            {
                if (Board [row] [column] == 'X' && Board [row] [column] == 'O') 
                {
                    System.out.println ("It is a tie. Cats game!") ;
                    GameOver = true ;
                }
            }  
        }
     }


    public static void main (String[] args)
    {
    //Variable declaration
    Scanner kbReader = new Scanner(System.in);
    char [] [] Board = new char [3] [3] ;
    String MenuInput ;
    int BoardOutput ;
    int UserSpotChoice ;
    int ComputerSpotChoice = 0;
    int UserTurn = 1 ;
    int Winner = 0 ;
    Board [0] [0] = '-' ;
    Board [0] [1] = '-' ;
    Board [0] [2] = '-' ;
    Board [1] [0] = '-' ;
    Board [1] [1] = '-' ;
    Board [1] [2] = '-' ;
    Board [2] [0] = '-' ;
    Board [2] [1] = '-' ;
    Board [2] [2] = '-' ;

    //Welcome
    System.out.println ("Welcome to Alex Montague's Tic Tac Toe game!.") ;
    System.out.println ("") ;
    System.out.println ("If you wish to play, type 'Play'") ; 
    System.out.println ("If you wish to read the instructions, type 'Instructions'") ;
    System.out.println ("If you wish to exit, type 'Exit'") ;
    MenuInput = kbReader.next () ;

    //do
    //{
    if (MenuInput.equals ("Play") || MenuInput.equals ("play")) 
    {
        while (!GameOver)
        {
        System.out.println ("\f") ;
        System.out.println (" Tic Tac Toe") ;
        BoardOutput = DrawBoard (Board) ;
        System.out.println (" 1 2 3") ;
        System.out.println (" 4 5 6") ;
        System.out.println (" 7 8 9") ;
        System.out.println ("Please enter the number you would like to move your spot to") ;
        UserSpotChoice = kbReader.nextInt () ;

        if (UserSpotChoice == 1) Board [0] [0] = 'X' ;
        if (UserSpotChoice == 2) Board [0] [1] = 'X' ;
        if (UserSpotChoice == 3) Board [0] [2] = 'X' ;
        if (UserSpotChoice == 4) Board [1] [0] = 'X' ;
        if (UserSpotChoice == 5) Board [1] [1] = 'X' ;
        if (UserSpotChoice == 6) Board [1] [2] = 'X' ;
        if (UserSpotChoice == 7) Board [2] [0] = 'X' ;
        if (UserSpotChoice == 8) Board [2] [1] = 'X' ;
        if (UserSpotChoice == 9) Board [2] [2] = 'X' ;

   //RIGHT HERE IS WHERE I NEED HELP WITH ``````````````````````````````````````````````     

        for (int row = 0; row < 3; row = row + 1) 
        {
            for (int column = 0; column < 3; column = column + 1) 
            {
                if (Board [row] [column] == '-') 
                {
                    ComputerSpotChoice = (int) (Math.random() * 8 ) + 1 ;
                }  
            }
        }


        if (ComputerSpotChoice == 1) Board [0] [0] = 'O' ;
        if (ComputerSpotChoice == 2) Board [0] [1] = 'O' ;
        if (ComputerSpotChoice == 3) Board [0] [2] = 'O' ;
        if (ComputerSpotChoice == 4) Board [1] [0] = 'O' ;
        if (ComputerSpotChoice == 5) Board [1] [1] = 'O' ;
        if (ComputerSpotChoice == 6) Board [1] [2] = 'O' ;
        if (ComputerSpotChoice == 7) Board [2] [0] = 'O' ;
        if (ComputerSpotChoice == 8) Board [2] [1] = 'O' ;
        if (ComputerSpotChoice == 9) Board [2] [2] = 'O' ;

        Winner (Board) ;
        Loser (Board) ;
        Tie (Board) ;

        if (GameOver) System.exit (0) ;
        }
    }

 //TILL HERE ``````````````````````````````````````````````````````````````````````````

    else if (MenuInput.equals ("Instructions") || MenuInput.equals ("instructions")) 
    {
        System.out.println ("\f") ;
        System.out.println ("You will be playing the game of Tic Tac Toe against the computer.") ;
        System.out.println ("The object of this game is to get three of your own x's or o's in a line.") ;    
        System.out.println ("You take turns placing the x's and o's and whoever gets three in a row first wins.") ;
        System.out.println ("Good Luck!") ;
        System.out.println ("") ;
        System.out.println ("If you wish to play, type 'Play'") ;
        System.out.println ("If you wish to exit, type 'Exit'") ;
        MenuInput = kbReader.next () ;
    }

    else if (MenuInput.equals ("Exit") || MenuInput.equals ("exit")) 
    {
        System.out.println ("Thank you for using Alex Montague's Tic Tac Toe game!") ;
        System.exit (0) ;
    }

    else 
    {
        System.out.println ("Sorry, that is not a valid choice.") ;
        System.out.println ("If you wish to play, type 'Play'") ; 
        System.out.println ("If you wish to read the instructions, type 'Instructions'") ;
        System.out.println ("If you wish to exit, type 'Exit'") ;
        MenuInput = kbReader.next () ;
    }
    //}
    //while (!MenuInput.equals ("Instructions") || !MenuInput.equals ("instructions") || !MenuInput.equals ("Play") || !MenuInput.equals ("play") || !MenuInput.equals ("Exit") || !MenuInput.equals ("exit")) ;

    } // main method

} // TicTacToe class

1 个答案:

答案 0 :(得分:2)

在实施AI之前,我想提出一些改进建议。这些将使您的代码更易于阅读,并将帮助您实现AI算法(这可能涉及递归和回溯)。

  1. 实现Board类来封装板的状态(而不是使用char [] [])。
  2. 实施Move类以封装可能的棋盘移动
  3. 实施Location类以封装移动的位置
  4. 将您的获胜者/失败者方法重新命名为董事会成员
  5. 实施董事会方法以应用移动并返回可能的移动
  6. 一旦你完成了,你的AI的一般形式应该是(在伪代码中):

    public Move getMove(Board board) {
        for (Move move: board.possibleMoves()) {
            if (move will win the game)
                add move to list of good moves
            else for (Move counterMove: board.apply(move).possibleMoves()) {
                if (counterMove will NOT lose the game)
                    call getMove recursively on board.apply(move).apply(counterMove);
                        add move to list of good moves only if recursive call is not null
            }
        }
        return a random move from the list of good moves, or null if it's empty
    }
    

    我自己写了一个解决方案来测试这个理论,并以“bestMoves”方法结束了以下内容:

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

    此方法返回合理移动的列表(赢得游戏或不会导致强制赢得对手的移动)。然后呼叫者可以随机选择一个。它对我有用!如果它对您没有意义,请告诉我(例如,如果您不习惯Java 8流和lambdas)。