Creating a TicTacToe game in Java

Problem:

In a game of TicTacToe, two players take turns marking an available cell in a 3 3 grid with their respective tokens (either X or O). When one player has placed three tokens in a horizontal, vertical, or diagonal row on the grid, the game is over and that player has won. A draw (no winner) occurs when all the cells on the grid have been filled with tokens and neither player has achieved a win. Create a program for playing TicTacToe. The program prompts two players to enter X token and O token alternately. Whenever a token is entered, the program redisplays the board on the console and determines the status of the game (win, draw, or continue).


Output:

-------------
|   |   |   |
-------------
|   |   |   |
-------------
|   |   |   |
-------------
Enter a row (1, 2, or 3) for player X: 2
Enter a column (1, 2, or 3) for player X: 2
-------------
|   |   |   |
-------------
|   | X |   |
-------------
|   |   |   |
-------------
Enter a row (1, 2, or 3) for player O: 1
Enter a column (1, 2, or 3) for player O: 1
-------------
| O |   |   |
-------------
|   | X |   |
-------------
|   |   |   |
-------------
Enter a row (1, 2, or 3) for player X: 1
Enter a column (1, 2, or 3) for player X: 3
-------------
| O |   | X |
-------------
|   | X |   |
-------------
|   |   |   |
-------------
Enter a row (1, 2, or 3) for player O: 3
Enter a column (1, 2, or 3) for player O: 1
-------------
| O |   | X |
-------------
|   | X |   |
-------------
| O |   |   |
-------------
Enter a row (1, 2, or 3) for player X: 2
Enter a column (1, 2, or 3) for player X: 1
-------------
| O |   | X |
-------------
| X | X |   |
-------------
| O |   |   |
-------------
Enter a row (1, 2, or 3) for player O: 2
Enter a column (1, 2, or 3) for player O: 3
-------------
| O |   | X |
-------------
| X | X | O |
-------------
| O |   |   |
-------------
Enter a row (1, 2, or 3) for player X: 1
Enter a column (1, 2, or 3) for player X: 2
-------------
| O | X | X |
-------------
| X | X | O |
-------------
| O |   |   |
-------------
Enter a row (1, 2, or 3) for player O: 3
Enter a column (1, 2, or 3) for player O: 2
-------------
| O | X | X |
-------------
| X | X | O |
-------------
| O | O |   |
-------------
Enter a row (1, 2, or 3) for player X: 3
Enter a column (1, 2, or 3) for player X: 3
-------------
| O | X | X |
-------------
| X | X | O |
-------------
| O | O | X |
-------------
No one has won!

Solution:

import java.util.Scanner;

public class TicTacToe
{  
  /** Before you begin with reading the solution, note this is
   how the tic tac toe
   board is going to look:
  -------------
  |   |   |   |
  -------------
  |   |   |   |
  -------------
  |   |   |   |
  -------------   */
  public static String[][] fillEmptyArray()
  {
    String[][] str = new String[7][13];
    //Why 13? Because count the characters between 
    //the parentheses, you'll get 13: ("|   |   |   |")
    for (int i = 0; i< str.length; i++)
    {
      for (int j =0; j <str[i].length;j++)
      {
        if (i % 2 == 0) str[i][j]= "-";
        else if (i % 2 != 0 && (j==0 || j == 4 || j == 8 || j ==12))
            //The indexes of "|" in the array are: 0,4,8 and 12
          str[i][j]="|";
        else
          str[i][j]=" ";
        
      }
    }
    return str;
  }

  public static String[][] playGameX (String[][] str)
  {
    String[][] str1 = str;
    Scanner scan =  new Scanner (System.in);
    boolean doItAgain = true;
    while (doItAgain)
    {
    System.out.print("Enter a row (1, 2, or 3) for player X: ");
    //We add -1 to deal with the index of the two-dimensional array
    int row = 2*(scan.nextInt() - 1) +1 ;
    //Don't freak out! We used 2n + 1, and we'll tell why:
    //1, 3 and 5 are the real row indexes of where X will be placed,
    //they are distinct from the user input, reason of adding formula.
    //If the user enters 1: 2(1-1) + 1 = 1  
    //If the user enters 2: 2(2-1) + 1 = 3
    //If the user enters 3: 2(3-1) + 1 = 5
    //The program we make will insert the number of 
    //column in the corresponding
    //array, this is why we used the formula.
    System.out.print("Enter a column (1, 2, or 3) for player X: ");
    int column = ( 4*(scan.nextInt()-1) + 2 );
    //Again! Don't freak out! We used 4n + 2, and we'll tell why:
    //("| 2 | 6 | 10 |"), those are the column indexes of where
    // X will be placed
    //If the user enters 1: 4(1-1) + 2 = 2 
    //If the user enters 2: 4(2-1) + 2 = 6
    //If the user enters 2: 4(3-1) + 2 = 10
    //The program we make will insert the number of column 
    //in the corresponding
    //array, this is why we used the formula.
    if ( str1[row][column] == " ")
    {
    str1[row][column] = "X";
    doItAgain = false;
    }
    else
      System.out.println("An X/O is already there, try again!");
    }
    return str1;
  }
  //playGameO is 100% identical to playGameX, instead replace X with O;
  public static String[][] playGameO (String[][] str)
  {
    String[][] str1 = str;
    Scanner scan =  new Scanner (System.in);
    System.out.print("Enter a row (1, 2, or 3) for player O: ");
    //We add -1 to deal with the index of the two-dimensional array
    int row = 2*(scan.nextInt() - 1) +1 ;
    //Don't freak out! We used 2n + 1, and we'll tell why:
    //1, 3 and 5 are the real row indexes of where O will be placed,
    //they are distinct from the user input, this is why we add 
    //the formula
    //If the user enters 1: 2(1-1) + 1 = 1  
    //If the user enters 2: 2(2-1) + 1 = 3
    //If the user enters 3: 2(3-1) + 1 = 5
    //The program we make will insert the number of column in the 
    //corresponding array, this is why we used the formula.
    System.out.print("Enter a column (1, 2, or 3) for player O: ");
    int column = ( 4*(scan.nextInt()-1) + 2 );
    //Again! Don't freak out! We used 4n + 2, and we'll tell why:
    //("| 2 | 6 | 10 |"), those are the column indexes of O:
    //If the user enters 1: 4(1-1) + 2 = 2 
    //If the user enters 2: 4(2-1) + 2 = 6
    //If the user enters 2: 4(3-1) + 2 = 10
    //The program we make will insert the number of column in the
    //array, this is why we used the formula.
    if ( str1[row][column] == " ")
    str1[row][column] = "O";
    else
      System.out.println("Invalid input! An X/O is already there.");
    return str1;
  }
  
  public static String checkForWinner(String[][] str)
  {
    for (int i =1;i<str.length; i+= 2)
    {
      if ( ( str[i][2] == str[i][6]) && ( str[i][6] == str[i][10]) 
       && str[i][2] != " " && str[i][6] != " " && str[i][10] != " ")
          return str[i][2];
    }
    
    for (int j =2;j<str[1].length; j+=4)
    {
      if ( ( str[1][j] == str[3][j]) && ( str[3][j] == str[5][j]) && 
           str[1][j] != " " && str[3][j] != " " && str[5][j] != " ")
        return str[1][j];
    }
    
    if (  (str[1][2] == str[3][6]) && (str[3][6] == str[5][10])   && 
          str[1][2] != " " && str[3][6] != " " && str[5][10] != " "  )
      return str[1][2];
    
    if (   (str[1][10] == str[3][6]) && (str[3][6] == str[5][2])  &&
          str[1][10] != " " && str[3][6] != " " && str[5][2] != " " )
      return str[1][10];
    
    return "zero";
  }
  
  public static void printArray(String[][] str)
  {
    //I guess this is the easiest method
    for (int i =0;i < str.length;i++)
    {
      for (int j =0;j < str[i].length;j++)
      {
        System.out.print(str[i][j]);
      }
      System.out.println();
    }
  }
  public static void main (String[] args)
  {
    boolean play = true;
    String[][] original = fillEmptyArray();
    printArray(original);
    int XorY = 0;
    String[][] updated;
    while (play)
    {
    if (XorY % 2 == 0)
      updated = playGameX(original);
    else
      updated = playGameO(original);
    XorY++;
    printArray(updated);
    if (checkForWinner(updated) != "zero")
    {
      System.out.print(checkForWinner(updated) + " have won");
      play = false;
    }
    if (XorY > 8 )
    {
      play = false;
      System.out.println("No one has won!");
    }

  }
}
}

No comments:

Post a Comment