-1

I am trying to make a Tic-tac-toe game where the user gets to select whether they would like to play a single player game or a two player game. I have gotten both of them to work but am trying to make the AI have some logic as to where it places its "o". Currently, the computer randomly generates a row and a column and if the corresponding square in the array has a "-" (signifying that it is empty), it will fill it with an "o". I am looking for a simple way to go through the 2d array and sees if it has a way to win. If not, it should check if the user can win and prevent them from winning. If none of them are true, then it should randomly select a square and make it's move. Also, I am relatively new to Java so if I am doing something wrong, please let me know how to do it so that I can fix it and improve my own skills. Here is the code.

Driver File:

public class DriverTicTacToe
{
   public static void main(String[] args)
   {
      TicTacToe game = new TicTacToe(); //creates an object
      game.play();//this simulates the whole game from asking the number of players all the way to printing the win message.
   }
}

Resource File:

import java.util.Scanner;

public class TicTacToe
{  
   //declares the symbol character that will hold either "x" or "o"
   char symbol;
   
   //create a 3*3 array of characters that acts as the board in the game.
   char[][] board = new char[3][3];
   //declares multiple integers used throughout the game simulation
   int player = 1, row, col, numPlayers;
   //creates scanner object used to get user input
   Scanner kb = new Scanner(System.in);
   
   //constructor that fill the board array with dashes.
   public TicTacToe()
   {
      for(int i = 0; i <3; i++)
      {
         for(int j = 0; j < 3; j++)
            board[i][j] = '-';
      }   
   }
   
   //asks the user for the number of players
   public int getNumPlayers()
   {
      System.out.println("How many players are there (1 or 2)");
      numPlayers = kb.nextInt();
      return numPlayers;
   }
   
   //used to cycle through "x" and "o"
   public void setSymbol(int playerNumber)
   {
      if (playerNumber % 2 == 1)
         symbol = 'x';
      else 
         symbol = 'o';
   }  
   
   //prints the array as a 3*3 board
   public void printBoard()
   {
      for(int i = 0; i < 3; i++)
      {
         for(int j = 0; j<3; j++)
            System.out.print(board[i][j]);
         System.out.println();
      }   
   }
   
   //checks if there is an empty place on the board
   public boolean boardNotFilled()
   {
      for(int i = 0; i < 3; i++)
      {
         for(int j = 0; j < 3; j++)
         {
            if(board[i][j] == '-') 
               return true;
         }
      }
      return false;
    }
   
   //checks if someone has won the game  
   public boolean checkGameOn()
   {
      if(board[0][0] == board[0][1] && board[0][1] == board[0][2] && board[0][0] != '-')
         return false;
      else if(board[1][0] == board[1][1] && board[1][1] == board[1][2] && board[1][0] != '-')
         return false;
      else if(board[2][0] == board[2][1] && board[2][1] == board[2][2] && board[2][0] != '-')
         return false;
      else if(board[0][0] == board[1][0] && board[1][0] == board[2][0] && board[0][0] != '-')
         return false;
      else if(board[0][1] == board[1][1] && board[1][1] == board[2][1] && board[0][1] != '-')
         return false;
      else if(board[0][2] == board[1][2] && board[1][2] == board[2][2] && board[0][2] != '-')
         return false;
      else if(board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != '-')
         return false;
      else if(board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != '-')
         return false;
      else
         return true;
   }
   
  //ask user for a row. The number is decreased by one to get to the corresponding index
  public void getRow()
  {
     System.out.println("Enter a row: ");
     row = kb.nextInt() - 1;
     //return row;
  } 
  
  //ask user for a column. The number is decreased by one to get to the corresponding index
  public void getColumn()
  {
     System.out.println("Enter a column: ");
     col = kb.nextInt() - 1;
     //return col;
  } 
  
  //switches the value at a point from a "-" to the symbol
  public boolean switchVal()
  {
      board[row][col] = symbol;
  }
  
  //selects to random numbers for a computer move. Keeps running until an empty index is found.
  public void compMove()
  {
     while(true)
     {
        row = (int)(Math.random()*3);
        col = (int)(Math.random()*3);
        if(board[row][col] == '-')
           break;
     }
  }
  
  //Prints winner for a 2 player game
  public void winStatement()
  {
     if(symbol == 'x')
        System.out.println("Congratulations Player 1, you win");
     else
       System.out.println("Congratulations Player 2, you win");
  }
  
  //simulates a single player game
  public void singlePlayer()
  {
     int playerNum = 1;
      
      TicTacToe game = new TicTacToe();
      
      while (game.checkGameOn() && game.boardNotFilled())
      {
         game.printBoard();
         if(playerNum != 1)
         {
            System.out.println();
            System.out.println("I made my move! Your turn.");
            System.out.println(); 
         }
         game.setSymbol(playerNum);
         game.getRow();
         game.getColumn();
         game.switchVal();
         game.printBoard();
         System.out.println();
         System.out.println("Computer's turn!");
         System.out.println();
         playerNum++;
         game.setSymbol(playerNum);
         game.compMove();
         game.switchVal();
         playerNum++;
      }
      
      game.printBoard();
      if(game.boardNotFilled())
         System.out.println("Congratulations, you win!");
      else
         System.out.println("Game Tied");
  }
  
  //simulates a two player game
  public void twoPlayer()
  {
     int playerNum = 1;
      
      TicTacToe game = new TicTacToe();
      
      while (game.checkGameOn() && game.boardNotFilled())
      {
         game.printBoard();
         game.setSymbol(playerNum);
         game.getRow();
         game.getColumn();
         game.switchVal();
         playerNum++;
      }
      
      game.printBoard();
      if(game.boardNotFilled())
         game.winStatement();
      else
         System.out.println("Game Tied");
  }
  
  //simulates everything from asking user how many players all the way to running the game.
  public void play()
  {
     TicTacToe game = new TicTacToe();
     int  numPlayers = game.getNumPlayers();
     if(numPlayers == 1)
        game.singlePlayer();
     else if(numPlayers == 2)
        game.twoPlayer();
     else
        System.out.println("Error");
  }
}
  • Does this answer your question? [could someone explain minimax tic tac toe algorithm](https://stackoverflow.com/questions/45822215/could-someone-explain-minimax-tic-tac-toe-algorithm) – robere2 Jul 02 '22 at 19:50
  • 1
    @robere2 From my understanding, the minimax algorithm is used to look multiple moves ahead to see what is the best move. I am looking for something that would just cycle through to check if a win is possible and if not, preventing the user from winning on the next move. If there is no immediate win and the computer is not losing on the next move, I am fine with the ai making a random move. – Leraner Jul 02 '22 at 19:56

1 Answers1

0

How about you add board as a parameter in the checkGameOn method, then you can loop through and check for modified versions of your board if its a winning move and in that case thats where the computer wants draw its O.

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            if(board[i][j] != '-')continue;
            board[i][j] = 'x';
            if (checkGameOn(board)) board[i][j] = 'o';
            else board2[i][j] = '-';
        }
    }
David_RotU
  • 26
  • 2
  • Do you have any suggestions for how to check if the ai can win since that should be the priority. – Leraner Jul 02 '22 at 20:09
  • you can use the exact same code but change to board2[i][j] = 'o' instead. – David_RotU Jul 03 '22 at 20:28
  • I tried something along those lines but am getting a logic error. I'm not to sure how to show the new code as this is my first time using Stackoverflow. Should I edit my initial question or use the Answer Your Question feature to add a comment? – Leraner Jul 03 '22 at 22:11
  • I guess add an answer. Edits are ment to correct things like spelling – David_RotU Jul 03 '22 at 23:05
  • Hey Leraner I made a big mistake in the code sorry I didnt actually test it. clone() gives only a shallow copy so the second dimension of board2 basically becomes a direct reference of board. Im pretty sure this is whats causing you problems. I will edit my code. – David_RotU Jul 04 '22 at 22:19