Search code examples
javaartificial-intelligencetic-tac-toe

TicTacToe AI Java


So this is a college assignment and everything is pretty much done except the AI doesn't know how to "take the win" and its moves at the start aren't as random as I'd like to be as they always go top corner and work their way down. The assignment only required two rules for the AI in that it could "take the win" or "block the win".

Also the game doesn't seem to end when the board is filled. It asks me to choose my move.

I was hoping some people might have suggestions as to how I can improve it or point out where it is I'm going wrong.

Any help would be greatly appreciated.

Here is the play

import java.util.Scanner;

public class play {



    public static void main(String[] args) {


        System.out.println("Welcome to Tickle Tackle Toe!!! :D");
        System.out.println();

        //creat markers
        String marker1 = "x";
        String marker2 = "o";
        boolean playAgain = true;

        Scanner s = new Scanner(System.in);



        //create player objects
        Human human = new Human();
        Computer computer = new Computer();

        while(playAgain){
        //run board setup
        set Setup = new set();

        Setup.createBoard();
        Setup.printBoard();

        System.out.println("please choose your marker");
        System.out.println("type 1 for 'x' or 2 for 'o'");

        //set markers
        if(s.nextInt() == 1){
         // create player objects
         human.setMarker("x");
         computer.setMarker("o");
        } 
        else
        {
        human.setMarker("o");
        computer.setMarker("x");

        }




    // determine who goes first
    int first = (int) (Math.random() * 2);





    boolean won = false;
    int turns = 0;

   if(first == 0){
   System.out.println("You go first!");
    System.out.println();
   while(!won){
    human.takeTurn(Setup.getBoard());
    turns++;
    Setup.printBoard();
    if(Setup.hasWon(Setup.getBoard())){
        won = true;
        System.out.println("Congrats you won!");
        }
        if(turns == 9){
        won = true;
        System.out.println("Its a draw!");
        break;
        }
    if(!won){
        computer.takeTurn(Setup.getBoard(), human);
        turns++;
        System.out.println();
        Setup.printBoard();
        System.out.println();
        if(Setup.hasWon(Setup.getBoard())){
            won = true;
            System.out.println("You lost!");
            }
            if(turns == 9){
        won = true;
        System.out.println("Its a draw!");
        break;
        }
        }

   }  // close while 1
  }
  else {

    System.out.println("Computer goes first!");
    System.out.println();
    while(!won){
    computer.takeTurn(Setup.getBoard(), human);
    turns++;
    Setup.printBoard();
    if(Setup.hasWon(Setup.getBoard())){
        won = true;
        System.out.println("You lost!");
        }
    if(!won){
        human.takeTurn(Setup.getBoard());
        turns++;
        System.out.println();
        Setup.printBoard();
        System.out.println();
        if(Setup.hasWon(Setup.getBoard())){
            won = true;
            System.out.println("Congrats you won!");
            }
        }



   }  // close while 2

  }

  System.out.println("Would you like to play again? Type 1 for yes or 2 to quit");
   System.out.println();
   if(s.nextInt() == 2){
   playAgain = false;
   }

  }

}
}

And here is the computer class

class Computer extends player {

    public Computer(){

    }

    int boardsize = 3;


    public void takeTurn(String[][] board, Human human) {

    int vertical = 0;
    int horizontal = 0;
    int diagonal = 0;
    boolean mademove = false;

    // check if you can take a win horizontally
    for(int i = 0; i<3; i++){

        if(board[0][i].equals(board[1][i]) && board[0][i].equals(Marker)){

            if(board[2][i] != human.getMarker()){
            board[2][i] = Marker;
            mademove = true;
            return;
            }

        }

    }

    for(int i = 0; i<3; i++){

        if(board[2][i].equals(board[1][i]) && board[2][i].equals(Marker)){

            if(board[0][i] != human.getMarker()){
            board[0][i] = Marker;
            mademove = true;
            return;
            }

        }


    }


        // check if you can take a win vertically
    for(int i = 0; i<3; i++){

        if(board[i][0].equals(board[i][1]) && board[i][0].equals(Marker)){

            if(board[i][2] != human.getMarker()){
            board[i][2] = Marker;
            mademove = true;
            return;
            }

        }

    }

    for(int i = 0; i<3; i++){

        if(board[i][2].equals(board[i][1]) && board[i][2].equals(Marker)){

            if(board[i][0] != human.getMarker()){
            board[i][0] = Marker;
            mademove = true;
            return;
            }

        }

    }


    // check if you can take a win diagonally 


        if(board[0][0].equals(board[1][1]) && board[0][0].equals(Marker)){

            if(board[2][2] != human.getMarker()){
            board[2][2] = Marker;
            mademove = true;
            return;
            }
    }

        if(board[2][2].equals(board[1][1]) && board[2][2].equals(Marker)){

            if(board[0][0] != human.getMarker()){
            board[0][0] = Marker;
            mademove = true;
            return;
            }
    }

        if(board[0][0].equals(board[1][1]) && board[0][0].equals(Marker)){

            if(board[2][2] != human.getMarker()){
            board[2][2] = Marker;
            mademove = true;
            return;
            }
    }

        if(board[0][2].equals(board[1][1]) && board[0][2].equals(Marker)){

            if(board[2][0] != human.getMarker()){
            board[2][0] = Marker;
            mademove = true;
            return;
            }
    }

        if(board[2][0].equals(board[1][1]) && board[2][0].equals(Marker)){

            if(board[0][2] != human.getMarker()){
            board[0][2] = Marker;
            mademove = true;
            return;
            }
    }


    // BLOCKS!!!! //

    // check if you can block a win horizontally
    for(int i = 0; i<3; i++){

        if(board[0][i].equals(board[1][i]) && board[0][i].equals(human.getMarker())){
            if(board[2][i] != Marker){
            board[2][i] = Marker;
            mademove = true;
            return;
            }

        }

    }

    for(int i = 0; i<3; i++){

        if(board[2][i].equals(board[1][i]) && board[0][i].equals(human.getMarker())){

            if(board[0][i] != Marker){
            board[0][i] = Marker;
            mademove = true;
            return;
            }

        }


    }



    // check if you can block a win horizontally
    for(int i = 0; i<3; i++){

        if(board[i][0].equals(board[i][1]) && board[i][0].equals(human.getMarker())){

            if(board[i][2] != Marker){
            board[i][2] = Marker;
            mademove = true;
            return;
            }

        }

    }

    for(int i = 0; i<3; i++){

        if(board[i][2].equals(board[i][1]) && board[i][2].equals(human.getMarker())){

            if(board[i][0] != Marker){
            board[i][0] = Marker;
            mademove = true;
            return;
            }

        }

    }


    // check if you can block a win diagonally 


        if(board[0][0].equals(board[1][1]) && board[0][0].equals(human.getMarker())){

            if(board[2][2] != Marker){
            board[2][2] = Marker;
            mademove = true;
            return;
            }
    }

        if(board[2][2].equals(board[1][1]) && board[2][2].equals(human.getMarker())){

            if(board[0][0] != Marker){
            board[0][0] = Marker;
            mademove = true;
            return;
            }
    }

        if(board[0][0].equals(board[1][1]) && board[0][0].equals(human.getMarker())){
            board[2][2] = Marker;
            mademove = true;
            return;
    }

        if(board[0][2].equals(board[1][1]) && board[0][2].equals(human.getMarker())){

            if(board[2][0] != Marker){
            board[2][0] = Marker;
            mademove = true;
            return;
            }
    }

        if(board[2][0].equals(board[1][1]) && board[2][0].equals(human.getMarker())){

            if(board[0][2] != Marker){
            board[0][2] = Marker;
            mademove = true;
            return;
            }
    }




         // make random move if above rules dont apply
        for(int i = 0; i<3; i++){
        if(board[i][0] != "x" && board[i][0] != "o"){
            board[i][0] = Marker;
            return;
            }
        }
        for(int i = 0; i<3; i++){
        if(board[i][1] != "x" && board[i][0] != "o"){
            board[i][1] = Marker;
            return;
            }
        }
            for(int i = 0; i<3; i++){
        if(board[i][2] != "x" && board[i][0] != "o"){
            board[i][2] = Marker;
            return;
            }
        }


    }   
}

Solution

  • So I thought i'd come back after finding the old code I did for this and answer how I did it.

    It's probably still far from perfect but it's very close.

    I started with a very simple class of player which would get and set markers.

    public class player {
    
        public String Marker;
    
        // set marker method
    
        public void setMarker(String marker){
    
            Marker = marker;
    
        }
    
        //get marker method 
    
        public String getMarker(){
    
            return Marker;
    
        }
    
    }
    

    I then added a set class which would set up and print the board after each move.

    import java.util.Random;
    import java.util.Scanner;
    
    
    
    public class set {
    
        // setup variables default board size and board
        private int N = 3;
        public String[][] board = new String [N][N];
    
        public boolean hasWon (String [] [] board){
            //horizontal 
            for(int i = 0; i<3; i++){
                if(board[i][0].equals(board[i][1]) && board[i][1].equals(board[i][2])){
                    return true;
                }
            }
            //vertical
            for(int i = 0; i<3; i++){
                if(board [0][i].equals(board[1][i]) && board[1][i].equals(board[2][i])){
                    return true;
                }
            }
            //diagonal
            if(board[0][0].equals(board[1][1]) && board[1][1].equals(board[2][2]) || board[2][0].equals(board[1][1]) && board[1][1].equals(board[0][2]))
                return true;
            return false;
        }
    
    
        int x = 1;
    
        public void createBoard(){
            for(int i = 0; i < board.length; i++){
                for(int j = 0; j < board.length; j++){
                    board[i][j] = "" + (x);
                    x++;
                }
            }
        }
    
        public void printBoard(){
    
            for(int i = 0; i < board.length; i++){
                for(int j = 0; j < board.length; j++){
                    System.out.print("[" + board[i][j] + "]" + " ");
    
                }
                System.out.println();
            }
    
        }
    
        public String[][] getBoard(){
    
            return board;
    
        }
    
    
    
    }
    

    The Computer class with AI.

    class Computer extends player {
    
    public Computer(){
    
    }
    
    int boardsize = 3;
    
    
    public void takeTurn(String[][] board, Human human) {
    
        int vertical = 0;
        int horizontal = 0;
        int diagonal = 0;
        boolean mademove = false;
    
        // check if you can take a win horizontally
        for(int i = 0; i<3; i++){
    
            if(board[0][i].equals(board[1][i]) && board[0][i].equals(Marker)){
    
                if(board[2][i] != human.getMarker() && board[2][i] != Marker){
                    board[2][i] = Marker;
                    mademove = true;
                    return;
                }
    
            }
    
        }
    
        for(int i = 0; i<3; i++){
    
            if(board[2][i].equals(board[1][i]) && board[2][i].equals(Marker)){
    
                if(board[0][i] != human.getMarker() && board[0][i] != Marker){
                    board[0][i] = Marker;
                    mademove = true;
                    return;
                }
    
            }
    
    
        }
    
    
    
        // check if you can take a win horizontally
        for(int i = 0; i<3; i++){
    
            if(board[i][0].equals(board[i][1]) && board[i][0].equals(Marker)){
    
                if(board[i][2] != human.getMarker() && board[i][2] != Marker){
                    board[i][2] = Marker;
                    mademove = true;
                    return;
                }
    
            }
    
        }
    
        for(int i = 0; i<3; i++){
    
            if(board[i][2].equals(board[i][1]) && board[i][2].equals(Marker)){
    
                if(board[i][0] != human.getMarker() && board[i][0] != Marker){
                    board[i][0] = Marker;
                    mademove = true;
                    return;
                }
    
            }
    
        }
    
    
        // check if you can take a win diagonally bottom
    
    
        if(board[0][0].equals(board[1][1]) && board[0][0].equals(Marker)){
    
            if(board[2][2] != human.getMarker() && board[2][2] != Marker){
                board[2][2] = Marker;
                mademove = true;
                return;
            }
        }
    
        if(board[2][2].equals(board[1][1]) && board[2][2].equals(Marker)){
    
            if(board[0][0] != human.getMarker() && board[0][0] != Marker){
                board[0][0] = Marker;
                mademove = true;
                return;
            }
        }
    
        if(board[0][0].equals(board[1][1]) && board[0][0].equals(Marker)){
    
            if(board[2][2] != human.getMarker() && board[2][2] != Marker){
                board[2][2] = Marker;
                mademove = true;
                return;
            }
        }
    
        if(board[0][2].equals(board[1][1]) && board[0][2].equals(Marker)){
    
            if(board[2][0] != human.getMarker() && board[2][0] != Marker){
                board[2][0] = Marker;
                mademove = true;
                return;
            }
        }
    
        if(board[2][0].equals(board[1][1]) && board[2][0].equals(Marker)){
    
            if(board[0][2] != human.getMarker() && board[0][2] != Marker){
                board[0][2] = Marker;
                mademove = true;
                return;
            }
        }
    
    
        // BLOCKS!!!! //
    
        // check if you can block a win horizontally
        for(int i = 0; i<3; i++){
    
            if(board[0][i].equals(board[1][i]) && board[0][i].equals(human.getMarker())){
                if(board[2][i] != Marker && board[2][i] != human.getMarker()){
                    board[2][i] = Marker;
                    mademove = true;
                    return;
                }
    
            }
    
        }
    
        for(int i = 0; i<3; i++){
    
            if(board[2][i].equals(board[1][i]) && board[0][i].equals(human.getMarker())){
    
                if(board[0][i] != Marker && board[0][i] != human.getMarker()){
                    board[0][i] = Marker;
                    mademove = true;
                    return;
                }
    
            }
    
    
        }
    
        // check if you can block a win vertically
    
    
        for(int i = 0; i<3; i++){
    
            if(board[i][0].equals(board[i][1]) && board[i][0].equals(human.getMarker())){
    
                if(board[i][2] != Marker && board[i][2] != human.getMarker()){
                    board[i][2] = Marker;
                    mademove = true;
                    return;
                }
    
            }
    
        }
    
        for(int i = 0; i<3; i++){
    
            if(board[i][2].equals(board[i][1]) && board[i][2].equals(human.getMarker())){
    
                if(board[i][0] != Marker && board[i][0] != human.getMarker()){
                    board[i][0] = Marker;
                    mademove = true;
                    return;
                }
    
            }
    
        }
    
        for(int i = 0; i<3; i++){
    
            if(board[2][i].equals(board[1][i]) && board[2][i].equals(human.getMarker())){
    
                if(board[0][i] != Marker && board[0][i] != human.getMarker()){
                    board[0][i] = Marker;
                    mademove = true;
                    return;
                }
    
            }
    
        }
    
    
    
        // check if you can block a win diagonally 
    
    
        if(board[0][0].equals(board[1][1]) && board[0][0].equals(human.getMarker())){
    
            if(board[2][2] != Marker && board[2][2] != human.getMarker()){
                board[2][2] = Marker;
                mademove = true;
                return;
            }
        }
    
        if(board[2][2].equals(board[1][1]) && board[2][2].equals(human.getMarker())){
    
            if(board[0][0] != Marker && board[0][0] != human.getMarker()){
                board[0][0] = Marker;
                mademove = true;
                return;
            }
        }
    
        if(board[0][0].equals(board[1][1]) && board[0][0].equals(human.getMarker())){
            if(board[2][2] != Marker && board[2][2] != human.getMarker()){
                board[2][2] = Marker;
                mademove = true;
                return;
            }
        }
    
        if(board[0][2].equals(board[1][1]) && board[0][2].equals(human.getMarker())){
    
            if(board[2][0] != Marker && board[2][0] != human.getMarker()){
                board[2][0] = Marker;
                mademove = true;
                return;
            }
        }
    
        if(board[2][0].equals(board[1][1]) && board[2][0].equals(human.getMarker())){
    
            if(board[0][2] != Marker && board[0][2] != human.getMarker()){
                board[0][2] = Marker;
                mademove = true;
                return;
            }
        }
    
    
    
    
        // make random move if above rules dont apply
        int rand1 = 0;
        int rand2 = 0;
    
        while(!mademove){
    
            rand1 = (int) (Math.random() * 3);
            rand2 = (int) (Math.random() * 3);
    
            if(board[rand1][rand2] != "x" && board[rand1][rand2] != "o"){
                board[rand1][rand2] = Marker;
                mademove = true;        
    
            }
    
        }
    
    
    }   
    

    }

    Human class

    import java.util.Scanner;
    

    class Human extends player {

    public Human(){
    
    }
    
    
    public void takeTurn(String[][] board) {
    
        Scanner s = new Scanner(System.in);
    
        boolean turn = true;
    
        while(turn){
            System.out.println("please enter row");
            int row = s.nextInt();
            System.out.println("please enter col");
            int col = s.nextInt();
            System.out.print("you entered "+row+" "+col);
            System.out.println();
            if(board[row - 1][col - 1] != "x" && board[row - 1][col - 1] != "o"){
                board[row - 1][col - 1] = Marker;
                turn = false;
            } // closes if
            else {
                System.out.println("Already Marker here! please guess again!");
            }
        } // ends while
    } // ends method
    
    } // ends class
    

    Finally the playing of the game.

        import java.util.Scanner;
    
    public class play {
    
    
    
        public static void main(String[] args) {
    
    
            System.out.println("Welcome to Tickle Tackle Toe!!! :D");
            System.out.println();
    
            //creat markers
            String marker1 = "x";
            String marker2 = "o";
            boolean playAgain = true;
    
            Scanner s = new Scanner(System.in);
    
    
    
            //create player objects
            Human human = new Human();
            Computer computer = new Computer();
    
            while(playAgain){
                //run board setup
                set Setup = new set();
    
                Setup.createBoard();
                Setup.printBoard();
    
                System.out.println("please choose your marker");
                System.out.println("type 1 for 'x' or 2 for 'o'");
    
                //set markers
                if(s.nextInt() == 1){
                    // create player objects
                    human.setMarker("x");
                    computer.setMarker("o");
                } 
                else
                {
                    human.setMarker("o");
                    computer.setMarker("x");
    
                }
    
    
    
    
                // determine who goes first
                int first = (int) (Math.random() * 2);
    
    
    
    
    
                boolean won = false;
                int turns = 0;
    
                if(first == 0){
                    System.out.println("You gots the winz!");
                    System.out.println();
                    while(!won){
                        human.takeTurn(Setup.getBoard());
                        turns++;
                        Setup.printBoard();
                        if(Setup.hasWon(Setup.getBoard())){
                            won = true;
                            System.out.println("Congrats you won!");
                        }
                        if(turns == 9){
                            won = true;
                            System.out.println("Its a bore draw!");
                            break;
                        }
                        if(!won){
                            computer.takeTurn(Setup.getBoard(), human);
                            turns++;
                            System.out.println();
                            Setup.printBoard();
                            System.out.println();
                            if(Setup.hasWon(Setup.getBoard())){
                                won = true;
                                System.out.println("You just got pwned by an A.I with an incomplete rule set. FACEPALM.");
                            }
                            if(turns == 9){
                                won = true;
                                System.out.println("Its a bore draw!");
                                break;
                            }
                        }
    
                    }  // close while 1
                }
                else {
    
                    System.out.println("Computer goes first!");
                    System.out.println();
                    while(!won){
                        computer.takeTurn(Setup.getBoard(), human);
                        turns++;
                        Setup.printBoard();
                        if(Setup.hasWon(Setup.getBoard())){
                            won = true;
                            System.out.println("You just got pwned by an A.I with an incomplete rule set. FACEPALM.");
                        }
                        if(turns == 9){
                            won = true;
                            System.out.println("Its a draw!");
                            break;
                        }
                        if(!won){
                            human.takeTurn(Setup.getBoard());
                            turns++;
                            System.out.println();
                            Setup.printBoard();
                            System.out.println();
                            if(Setup.hasWon(Setup.getBoard())){
                                won = true;
                                System.out.println("You gots the winz!");
                            }
                            if(turns == 9){
                                won = true;
                                System.out.println("Its a draw!");
                                break;
                            }
                        }
    
    
    
                    }  // close while 2
    
                }
    
                System.out.println("Would you like to play again? Type 1 for yes or 2 to quit");
                System.out.println();
                if(s.nextInt() == 2){
                    playAgain = false;
                }
    
            }
    
        }
    }