I built a Tic Tac Toe Game with Vanilla PHP

In this post I will outline some of the steps I took to build a tic tac toe game with PHP. I will also attempt to make it seem more awesome than it actually is.

Design

A Tic tac toe board consists of a 3 by 3 Grid so an array is the best way I thought to represent this.

A horribly drawn tic tac toe

The default board will be an array of threes.

$board = [
   [3,3,3],
   [3,3,3],
  [3,3,3]
];

If an X was play we will change the value to a 1. If O was play the value will be zero.

The first hurdle to overcome was storage. What would be our storage method to save the state of the plays.

To solve this problem we used json_encode to save our array state and then I realized while writing this post that was an unnecessary step since the form is where our state is actually saved.

Oh well! On to the next step. It does come in handy later on so no worries.

The X and the O

To create our X’s and O’s we use a select element. So the default value will be select. Then you can choose either X or O.

Selecting X or O

To do this we had to dynamically generate the select element based on changes to our $board array.

I created a function called create_tile it takes the current value of the board and a unique number.

 <?php $count=1; foreach($board as $row): ?>

                <tr>
                    <?php foreach($row as $tile):?>
                        <td>
                            <?php echo create_tile($tile, $count);?>
                        </td>
                        <?php $count++; endforeach;?>
                </tr>

            <?php endforeach;?>

The function create_tile has to do a few things. It must

  • Create a select element
  • Set the select element option to be selected and disabled if the tile is selected
  • Give the select element a unique name
  • Decide if X or O is selected based on the value begin 1 or 0

All of this is fine but one extra thing is required. When a select element is disabled the value is not submitted so we have to place an hidden input to mimic its value.

  • Add hidden input if selected (special)

If you don’t do this you will have to spend hours trying to figure out what when wrong. 😦

Part of the create_tile function

Rebuilding the board

This is the part I got confused with earlier. Every time you submit the form you have to rebuild the board based on the values from the form. You then overwrite the board with the new data.

Form to Board relationship

But you do need to keep the previous board for reference which is where json_encode came in handy.

When we submit the form we loop through all the post values. We skip the ones we don’t want using the function in_array as seen below.

    foreach ($_POST as $key=>$value){
        if(!in_array($key,["board","play",'last'])){
            if($value == 'O'){
                $rowarray[] = 0;
            }else if($value == 'X'){
                $rowarray[]= 1;
            }else{
                $rowarray[] = 3;
            }
            $counter++;
            if($counter % 3 == 0){
                $responses[] = $rowarray;
                $rowarray = [];
            }
        }
    }

We convert the Values of O’s to zero and X’s to ones. We can then set the board to the new board.

We check for three items in our array using the modulus operator. So we know when to end a row.

   if($counter % 3 == 0){
                $responses[] = $rowarray;
                $rowarray = [];
            }

Rules of the Game

You can’t play twice. That’s the main rule in tic tac toe. So we need to make sure that the board doesn’t have more than one change during submission. To do this we need to compare the previous board with the current board.

This is where we need json_encode we save the previous board within our form using it.

    <input name="board" type="hidden" value="<?php echo json_encode($board);?>"/>

Using a hidden input we can do this. When we submit our form we use json_decode to get back our board.

    $board = isset($_POST['board']) ? json_decode($_POST['board']) : [];

Now we compare our board. If we have multiple changes we complain to the user.

Checking for changes between two the current and previous board

Winning Conditions

The winning conditions are for X’s or O’s to have certain places on the board. We record these places and represent them in an array called $win_conditions shown below.

$win_conditions = [
    [[0,0],[0,1],[0,2]],
    [[1,0],[1,1],[1,2]],
    [[2,0],[2,1],[2,2]],
    [[0,0],[1,0],[2,0]],
    [[0,1],[1,1],[2,1]],
    [[0,2],[1,2],[2,2]],
    [[0,0],[1,1],[2,2]],
    [[0,2],[1,1],[2,0]],
];

All our win conditions are represented in this array. You can understand the conditions more clearly by mapping the board.

The first win condition is

[0,0],[0,1],[0,2]

This will look like the image below.

Checking for the winner

So what we do next is to check for the winner. The conditions for a winner based on our setup is

  • The tile has to be selected (Not equal to 3)
  • The tile must match the previous match unless the match is null ( X or O check)
     if($response[$x][$y] !=3){
                if($lr == $response[$x][$y] || $lr == null){
                    $matches[] = $response[$x][$y];
                    $lr = $response[$x][$y];
                }else{
                    $lr = null;
                    $matches = [];
                    continue;
                }
            }

Finally if we have three matches

  • Confirm that all three matches are the same
  if(count($matches) == 3){
            if($matches[0] == $matches[1] && $matches[1]== $matches[2]){
                return true;
            }else{
                $matches = [];
                $lr = null;
            }
        }

Now we know who the winner is. Hurray!.

Thats it. Our tic tac toe game is complete.

You can check out the full code here.

I did a whole video on it.

Styling it was the hardest part though.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s