2
\$\begingroup\$

I designed a tic tac toe using 4 classes. The game class being the main class, the board class being the board, the player class being the decision making, and the AI class keeping the previous game combinations. I found that this code was very inefficient especially as the number of games increases to the hundreds. This game was set specifically for two computers to play against each other. It's not really AI, but it if the same conditions apply (all the other spots are the same), then it won't make the same mistake. What can I do to improve my code efficiency since there are over 250k possible combinations for tic tac toe?

            public class Game
            {
             public static void main(String args[])
             {
              int playerWin = 0;
              int computerWin = 0;
              int ties = 0;
              int totalGame = 1;
              System.out.println("Welcome to Tic Tac Toe");
              Board bgame = new Board();
              Player p1 = new Player();
              Player p2 = new Player();
              bgame.createGrid();
              while (true)
              {
              bgame.turnNum();
              bgame.printGrid();
              System.out.println("Player Wins: " + playerWin + " Computer Wins: " + computerWin + " " + "Game Ties: " + ties + " Total Games: " + totalGame);
              if (bgame.checkTie())
              {
                System.out.println("The game ended in a tie :( "); 
               bgame.printGrid();
               totalGame++;
               ties++;
               bgame = new Board();
               bgame.createGrid();
              }
              if ((bgame.checkWinRow() || bgame.checkWinCol() || bgame.checkWinDiag()) && bgame.playerWin)
              {
               System.out.println("You have won!");
               bgame.printGrid();
               AI lossSave = new AI(bgame.getMap());
               p2.addLoss(lossSave);
               totalGame++;
               playerWin++;

               bgame = new Board();
               bgame.createGrid();
              }

              else if ((bgame.checkWinRow() || bgame.checkWinCol() || bgame.checkWinDiag()) && !(bgame.playerWin))
              {
               System.out.println("Computer has won!");
               bgame.printGrid();
               totalGame++;
               computerWin++;
               bgame = new Board();
               bgame.createGrid();
              }

              bgame.setPosGrid(p1.computerMove(bgame.getMap(), bgame.getNum()));
              if (bgame.checkTie())
              {
                System.out.println("The game ended in a tie :( "); 
               bgame.printGrid();
               totalGame++;
               ties++;
               bgame = new Board();
               bgame.createGrid();
              }
              if ((bgame.checkWinRow() || bgame.checkWinCol() || bgame.checkWinDiag()) && bgame.playerWin)
              {
               System.out.println("You have won!");
               bgame.printGrid();
               AI lossSave = new AI(bgame.getMap());
               p2.addLoss(lossSave);
               totalGame++;
               playerWin++;

               bgame = new Board();
               bgame.createGrid();
              }
              else if ((bgame.checkWinRow() || bgame.checkWinCol() || bgame.checkWinDiag()) && !(bgame.playerWin))
              {
               System.out.println("Computer has won!");
               bgame.printGrid();
               totalGame++;
               computerWin++;
               bgame = new Board();
               bgame.createGrid();
              }
              bgame.setPosGrid(p2.computerMove(bgame.getMap(), bgame.getNum()));
              }
             }
            }

        import java.io.*;
        import java.util.*;
        public class Player
        {
         public Player()
         {

         }
         public int[] playerMove(String[][] tempMap, int playerTurn)
         {
           int[] ret = new int[2];
           if (playerTurn % 2 == 0)
           {
           System.out.println("Enter coordinate to place O, format: 0, 3");
           }
           else
           {
            System.out.println("Enter coordinate to place X, format: 1, 2"); 
           }
           Scanner usr_in = new Scanner(System.in);
           String u_in = usr_in.nextLine();
           String[] rAndC = new String[2];
           rAndC = u_in.split(", ");
           ret[0] = Integer.parseInt(rAndC[0]);
           ret[1] = Integer.parseInt(rAndC[1]);
           while (!(tempMap[ret[1]][ret[0]] == "   "))
           {
            System.out.println("That spot is already taken, please try again."); 
            if (playerTurn % 2 == 0)
            {
              System.out.println("Enter coordinate to place O, format: 0, 3");
            }
            else
            {
              System.out.println("Enter coordinate to place X, format: 1, 2"); 
            }
            Board.printGrid(tempMap);
            u_in = usr_in.nextLine();
            rAndC = u_in.split(", ");
            ret[0] = Integer.parseInt(rAndC[0]);
            ret[1] = Integer.parseInt(rAndC[1]);
           }
           return ret;
         }

         public int[] computerMove(String[][] tempMap, int playerTurn)
         {
          String[][] aiCheck = new String[3][3];

          String currentPlayer = "";
          if (playerTurn % 2 == 0)
          {
           currentPlayer = "O"; 
          }
          else
          {
           currentPlayer = "X"; 
          }
          for (int i = 0; i < 3; i++)
          {
           for (int a = 0; a < 3; a++)
           {
            aiCheck[i][a] = tempMap[i][a]; 
           }
          }
          System.out.println("The computer's turn: ");
          int[] grid = new int[2];
          int row;
          int column;
          do
          {
            row = (int) (Math.random() * 3);
            column = (int) (Math.random() * 3);
          }
          while (tempMap[column][row] != "   ");
          int aiCounter = -1;
          if (rem.size() == 0)
          {

          }
          else
          {
            aiCheck[row][column] = currentPlayer;
           while (aiCounter < rem.size() - 1)
           {
             aiCounter++;
             if (!((AI)rem.get(aiCounter)).compareIt(aiCheck))
             {
              continue;
             }
             else
             {
              aiCounter = 0;
              do
              {
                aiCheck[row][column] = tempMap[row][column];
                row = (int) (Math.random() * 3);
                column = (int) (Math.random() * 3);
                aiCheck[row][column] = currentPlayer;
              }
              while (tempMap[column][row] != "   " && !(((AI)rem.get(aiCounter)).compareIt(aiCheck)));
             }
           }
          }
          grid[0] = row;
          grid[1] = column;
          Board.printGrid(tempMap);
          return grid;
         }

         public void addLoss(AI a)
         {
           rem.add(a);
         }

         public List retEv()
         {
          return rem; 
         }

         public List rem = new ArrayList();
        }

    public class Board
    {
     // Board Size is 3 x 3
     public Board()
     {

     }
     public void createGrid()
     {
      for (int r = 0; r < 3; r++)
      {
       for (int c = 0; c < 3; c++)
       {
        map[r][c] = "   "; 
       }
      }
     }

     public void setBoard(String[][] test)
     {
      for (int i = 0; i < 3; i++)
      {
       for (int a = 0; a < 3; a++)
       {
        map[i][a] = test[i][a]; 
       }
      }
     }
     // Method to Print Graphics
     public void printGrid()
     {
       for (int r = 0; r < 3; r++)
       {
        for (int c = 0; c < 3; c++)
        {
          System.out.print(map[r][c]);
          if (c == 0 || c == 1)
          {
           System.out.print(" | "); 
          }
        }
        if (r == 0 || r == 1)
        {
         System.out.println();
         System.out.println("---------------"); 
        }
       }
       System.out.println();
     }
      public static void printGrid(String tGrid[][])
     {
       for (int r = 0; r < 3; r++)
       {
        for (int c = 0; c < 3; c++)
        {
          System.out.print(tGrid[r][c]);
          if (c == 0 || c == 1)
          {
           System.out.print(" | "); 
          }
        }
        if (r == 0 || r == 1)
        {
         System.out.println();
         System.out.println("---------------"); 
        }
       }
       System.out.println();
     }
     // Method to set a position to a X or O
     public void setPosGrid(int[] rAndC)
     {
       int row = rAndC[1];
       int column = rAndC[0];
       if (turn %2 == 0)
       {
        map[row][column] = " O ";
       }
       else
       {
        map[row][column] = " X "; 
       }
       turn++;
     }

     public void turnNum()
     {
      if (turn % 2 == 0)
      {
       System.out.println("It is the computer's turn, O"); 
      }
      else
      {
       System.out.println("It is the player's turn, X"); 
      }
     }

     public String[][] getMap()
     {
      return map; 
     }

     public int getNum()
     {
      return turn; 
     }

     public String[] getRow(int r)
     {
       String[] row = new String[3];
       for (int i = 0; i < 3; i++)
       {
         row[i] = map[r][i];
       }
       return row;
     }
     public String[] getColumn(int c)
     {
       String[] column = new String[3];
       for (int i = 0; i < 3; i++)
       {
         column[i] = map[i][c];
       }
       return column;
     }
     //check win using row & columns method
     public boolean checkWinRow()
     {
      for (int i = 0; i < 3; i++)
      {
       String test[] = getRow(i);
       String prev = test[0];
       int counter = 0;
       for (int a = 1; a < 3; a++)
       {
         if (test[a].equals(prev) && prev != "   ")
         {
          counter++; 
         }
         else
         {
          counter = 0; 
         }
       }
       if (counter == 2)
       {
        if(prev.equals(" X "))
             {
          playerWin = true; 
        }
           return true;
        }
      }
    return false;
     }

     public boolean checkWinCol()
     {
      for (int i = 0; i < 3; i++)
      {
       String test[] = getColumn(i);
       String prev = test[0];
       int counter = 0;
       for (int a = 1; a < 3; a++)
       {
         if (test[a].equals(prev) && prev != "   ")
         {
          counter++; 
         }
         else
         {
          counter = 0; 
         }
       }
       if (counter == 2)
       {
        if(prev.equals(" X "))
             {
          playerWin = true; 
        }
           return true;
        }
      }
    return false;
     }

     public boolean checkWinDiag()
     {
       String s = map[1][1];
       if (map[0][0].equals(s) && map[2][2].equals(s) && !(s.equals("   ")))
       {
        if (s.equals(" X "))
        {
         playerWin = true; 
        }
        return true;
       }
       else if (map[2][0].equals(s) && map[0][2].equals(s) && !(s.equals("   ")))
       {
        if (s.equals(" X "))
        {
         playerWin = true; 
        }
        return true;
       }
       else
       {
        return false; 
       }

     }

     public boolean checkTie()
     {
      for (int i = 0; i < 3; i++)
      {
       for (int a = 0; a < 3;a ++)
       {
        if (map[i][a].equals("   "))
              {
          return false; 
        }
       }
      }
    return true;
     }

     public boolean playerWin = false;
     private int turn = 1;
     private String[][] map = new String[3][3];
    }

public class AI
{
 public AI(String[][] temp)
 {
   for (int i = 0; i < 3; i++)
   {
    for (int a = 0; a < 3; a++)
    {
     perm[i][a] = temp[i][a]; 
    }
   }
 }

 public boolean compareIt(String[][] check)
 {
  boolean notSame = true;
  for (int i = 0; i < 3; i++)
  {
   for (int a = 0; a < 3; a++)
   {
    if (perm[i][a].equals(check[i][a]))
    {
     continue; 
    }
    else
    {
     notSame = false;
     return notSame;
    }
   }
  }
  return true;
 }

 public String[][] retIt()
 {
  return perm; 
 }
 public String[][] perm = new String[3][3];
}
\$\endgroup\$
  • \$\begingroup\$ There are import statements in the middle of the code, which makes me wonder of you copied multiple source files into a single code box. Also the indentation is very strange. \$\endgroup\$ – Martin R May 21 '18 at 11:31
  • 1
    \$\begingroup\$ Every time you lose a game you're adding a new object to a list. That list will get bigger and bigger, so walking through it is going to take more and more time. You should consider a rules-based AI instead. \$\endgroup\$ – Eric Stein May 21 '18 at 14:47
  • \$\begingroup\$ Can you elaborate on a rules-based AI? The list will become too big and become inefficient. I'm not sure how I would implement a rule based AI to work with the code. My indentation is weird sometimes, I'm not sure why. I believe it's because I didn't split the code into separate classes correctly. \$\endgroup\$ – XTImpossible May 23 '18 at 22:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.