Let's Build Tic Tac Toe in Java
Tags: java, beginners
Published: 2021-08-01 21:07:00

Recently, I have wanted to broaden my horizon and have started to learn Java. I’ve watched online lectures, read forums, and practice small bits of code. This has been a great start but it is time to move on to a small project. I built a very simple command line Tic Tac Toe game in Java using a tutorial on youtube as a reference. To get the most out of this learning experience I want to summarize the project in my own words. Let's dive in to see how it works. 

##Setup
To get started I downloaded the Java SE Development Kit 16.0.2 and IntelliJ IDE for my local development. I created a new project with the command line template. From there I went coded everything out in one file if you would like to follow along. In the `main` we will use a while loop to handle our game. We need to do this so that way the game will keep working till we have a winner and then stop.

##Game Board
First, let's start by creating a game board to use. A 2D array will represent our game board. A 2D array is just an Array of Arrays. Let's make it with the datatype `char`. This allows us to easily place X and O on the board. The `gameBoard` array has 5 elements. We need to have 3 rows for our X and O input and then we need to have the other two rows as lines to make our grid show. 

```java
char[][] gameBoard = {{' ','|',' ', '|', ' '},
        {'-','+','-', '+', '-'},
        {' ','|',' ', '|', ' '},
        {'-','+','-', '+', '-'},
        {' ','|',' ', '|', ' ‘}};
```

Now that we have our 2D array we need to print this out to the console. The `printGameBoard(char[][] gameBoard)` will handle this. This method takes in the `gameBoard` as a parameter. This way we can pass in the new game board every time it's updated with a move. Printing the game board is very easy. All we have to do is iterate through our `gameBoard` array. The first iteration will give us access to the row and the second gives us access to the each `char` in the row. All we have to do is print them to the console and it shows up nicely. 

```java
public static void printGameBoard(char[][] gameBoard) {
    for(char[] row: gameBoard){
        for(char c: row){
            System.out.print(c);
        }
        System.out.println();
    }
}
```

##Player input
Great, we now have our game board showing on our console. It is now time to get input from the user so we can start filling our board. The first thing we need to do is create a `static` variable for both `playerPositions` and `cpuPositions`. We need this to record each move. Having this record will allow us to check for winning combinations and to also make sure we don’t have duplicate moves.

```java
static ArrayList<Integer> playerPositions = new ArrayList<Integer>();
static ArrayList<Integer> cpuPositions = new ArrayList<Integer>();
```
To get input from the user lets imported the `Scanner class` and print a message to the console asking for their input. Once we received the input, add it to `playerPos` variable. Then take this variable to check to see if it's valid. To do this let's created a while loop that takes this position and checks to see if this position is in the `playerPositions` or `cpuPositions` ArrayList. If it is, prompt a message asking for a new move. Once we have a unique move, we then call our `placePiece()` to place the piece on the board. 

```java
Scanner scan = new Scanner(System.in);
System.out.println("Enter your placement (1-9):");
int playerPos = scan.nextInt();
while(playerPositions.contains(playerPos) || cpuPositions.contains(playerPos)){
    System.out.println("Position taken. Try again!");
    playerPos =  scan.nextInt();
}

placePiece(gameBoard, playerPos, "player");
```
##X Marks the Spot
Now that we have the input we need to place an X on the corresponding place on the `gameBoard`. Let's do this with a method called `placePiece()`. This will be the method for placing both the users and computers turns on the board. This method takes in the parameters for `gameBoard`, `position`, and `user`. These parameters allows this method to be the only method needed to place both X and O on the `gameBoard`. The variable `symbol` depends on the user parameter. If it is a `player` it will change the symbol to 'X' and if it's a cpu then the symbol will be 'O'. Then the switch statement will look at the `position` parameter. Depending on the position it will change the `char` in the 2D `gameBoard` array to the correct `char`. Now we just have to call our `printGameBoard()` method to update the `gameBoard` with our players move.

```java
public static void placePiece(char[][] gameBoard, int pos, String user){
    char symbol = ' ';
    if(user.equals("player")){
        symbol = 'X';
        playerPositions.add(pos);
    } else if(user.equals("cpu")){
        symbol = 'O';
        cpuPositions.add(pos);
    }

    switch (pos){
        case 1:
            gameBoard[0][0] = symbol;
            break;
        case 2:
            gameBoard[0][2] = symbol;
            break;
        case 3:
            gameBoard[0][4] = symbol;
            break;
        case 4:
            gameBoard[2][0] = symbol;
            break;
        case 5:
            gameBoard[2][2] = symbol;
            break;
        case 6:
            gameBoard[2][4] = symbol;
            break;
        case 7:
            gameBoard[4][0] = symbol;
            break;
        case 8:
            gameBoard[4][2] = symbol;
            break;
        case 9:
            gameBoard[4][4] = symbol;
            break;
    }
}

```

For the computers move we need to import the Random class and create a random number between 1 and 9. At first this works great till the random number is the same number as a previous users turn and it overwrites their spot on the board! To fix this we used the same while loop that we used to check the validation for the users move. 

```java
Random rand = new Random();
int cpuPos = rand.nextInt(9) + 1;

while(playerPositions.contains(cpuPos) || cpuPositions.contains(cpuPos)){
    System.out.println("");
    cpuPos = rand.nextInt(9)+1;
}

placePiece(gameBoard, cpuPos, "cpu");

```

##Winner Winner
So now we have a game board, input from the user, cpu generating random placement, and a check system to make sure the inputs are unique. How do we know when to stop the program and declare a winner? The `checkWinner()` method will check to see if there is a winner or if the game continues. In this method we have all the possible winning conditions. Then we add these conditions to a `List` of `List` so we can iterate through the `List` and search for these conditions in the `playerPositions` and `cpuPositions`. If the `playerPositions` or `cpuPositions` contains all three positions then they are the winner. If the number of positions for both cpu and player add up to 9 and they do not have any of the winning conditions then that means the Cat won. If there is no winner and there is still room on the board it will just return an empty string.

```java
public static String checkWinner() {
    List tRow = Arrays.asList(1, 2, 3);
    List mRow = Arrays.asList(4, 5, 6);
    List bRow = Arrays.asList(7, 8, 9);
    List lCol = Arrays.asList(1, 4, 7);
    List cCol = Arrays.asList(2, 5, 8);
    List rCol = Arrays.asList(3, 6, 9);
    List fDiagonal = Arrays.asList(1, 5, 9);
    List bDiagonal = Arrays.asList(3, 5, 7);

    List<List> winningConditions = new ArrayList<List>();
    winningConditions.add(tRow);
    winningConditions.add(mRow);
    winningConditions.add(bRow);
    winningConditions.add(cCol);
    winningConditions.add(lCol);
    winningConditions.add(rCol);
    winningConditions.add(fDiagonal);
    winningConditions.add(bDiagonal);

    for (List l : winningConditions) {
        if (playerPositions.containsAll(l)) {
            return "Yay you won!";
        } else if (cpuPositions.containsAll(l)) {
            return "Sorry better luck next time!";
        } else if (playerPositions.size() + cpuPositions.size() == 9) {
            return "Cat won!";
        }

    }
    return "";
}

```

Now in the while loop of our `Main` we check for winner after every player and cpu move. A conditional checks to see if `checkWinner()` returns a string longer than 0. If the length is zero that means we still have moves to make, but if it's greater than 0 that means we have some sort of winner. When there is a winner `checkWinner()` prints out the message and then uses the break keyword to stop the program. 

```java
String result = checkWinner();

if(result.length()>0){
    System.out.println(result);
    break;
}
```
##Summary
There you have it, a nice simple Tic Tac Toe game made with Java. This was a great first project for me to create with Java. When I was learning Ruby and Javascript I followed a tutorial and created this same game. Following tutorials can be helpful when starting, but to get the most of them, don’t just mindlessly follow along. Take notes and write summaries like this to help you fully grasp the code. This method has helped me tremendously on expanding my knowledge base. I had a great time with this project and I hope others do as well! Now its time for me to build something from scratch! If you want to see the my code for this project go check it out at my Github https://github.com/turpp/JavaTicTacToe.