Riley's PHP TicTacToe

What is PHP

PHP is a server-side scripting language. A scripting language does not run as a compiled executable like most languages, this is good for live HTML generation. However because this is server-side; the game cannot simply be run on the client (your computer).

What is HTML?

HTML tells your browser how to view the page. When you go on any webpage it is always shown from HTML sent from the server to your computer behind the scenes.
NOTE: HTML is NOT a program language, it is a markup language hence Hyper Text Markup Language.

HTML is definded with a series of elements, <div> opens the element and </div> closes the element NOTE: Elements are also reffered to as tags

How is this solved?

The board is generated by the PHP script from the _GET variable. The server processes the get variable is a method of input defined in the address bar. for example http://rileyjamesbell.ml/ttt/tttpvc.php?turn=O tells the server that the turn was O, as in O just went and the script will return a board made for X's turn

The board is also stored as a value in _GET. The board is abstracted as an array and converted to and from a JSON object. A JSON is a form of array meant for global use of data. http://rileyjamesbell.ml/ttt/tttpvc.php?turn=O&board=[[0,0,0],[0,1,0],[0,0,2]] will generate this;

What does all this mean?

Pretty much, the game's data is stored in the address bar and generated on my server.

A basic rundown of CSS

The look of the board is all done in CSS. CSS is code that describes the look of HTML.
A very simple example of CSS is; #example{ color:red; }
Will make this red.
"this" was in a span element with the ID "example". The # in the CSS looks for the element with the id "example".
NOTE: Do NOT use IDs for multiple elements, use classes instead (research it)

Now lets look through the PHP script that does all the magic

<html>
        <head>
                <title>TicTacToe</title>
                <style>
a.t,span.t {
        padding:5px;
        display: inline-block;
        border-color:black;
        width: 50px;
        height: 50px;
        color:black;
        cursor:default;
        text-decoration: none;
        -webkit-user-select: none;
        -webkit-user-drag: none;
        -webkit-app-region: no-drag;
        font-size: 40px;
}
a.t:hover,span:hover{background-color:yellow;}
#a0x0{
        border-right-style: solid;
        border-bottom-style: solid;
}
#a0x1{
        border-bottom-style: solid;
}
#a0x2{
        border-left-style: solid;
        border-bottom-style: solid;
}

#a1x0{
        border-right-style: solid;
}
#a1x1{
}
#a1x2{
        border-left-style: solid;
}

#a2x0{
        border-right-style: solid;
        border-top-style: solid;
}
#a2x1{
        border-top-style: solid;
}
#a2x2{
        border-left-style: solid;
        border-top-style: solid;
}

#board{    
        border-style: double;
        display: inline-block;
}
                </style>
        </head>
        <body>
                <center>
                        <a href="/">Home</a> | <a href="?">Clear board</a><br>
<?
//Tic Tac Toe game I made in an hour for some class

if(isset($_GET["cheater"])) die("Someone's cheating");
if(isset($_GET["tie"])) die("Tie");

$board= [
[0,0,0],
[0,0,0],
[0,0,0]
];

if(isset($_GET["board"])) $board= json_decode(htmlspecialchars($_GET["board"]));

$tie= true;
foreach($board as $col){
        foreach($col as $tac){
                if(!$tac)$tie=false;
                //echo $tac;
        }
}
if($tie) die("Tie");

//Handle wins
if(($board[0][0]==1)&&($board[1][0]==1)&&($board[2][0]==1)) die("X wins");
if(($board[0][0]==2)&&($board[1][0]==2)&&($board[2][0]==2)) die("O wins");

if(($board[0][1]==1)&&($board[1][1]==1)&&($board[2][1]==1)) die("X wins");
if(($board[0][1]==2)&&($board[1][1]==2)&&($board[2][1]==2)) die("O wins");

if(($board[0][2]==1)&&($board[1][2]==1)&&($board[2][2]==1)) die("X wins");
if(($board[0][2]==2)&&($board[1][2]==2)&&($board[2][2]==2)) die("O wins");

if(($board[0][0]==1)&&($board[0][1]==1)&&($board[0][2]==1)) die("X wins");
if(($board[0][0]==2)&&($board[0][1]==2)&&($board[0][2]==2)) die("O wins");

if(($board[1][0]==1)&&($board[1][1]==1)&&($board[1][2]==1)) die("X wins");
if(($board[1][0]==2)&&($board[1][1]==2)&&($board[1][2]==2)) die("O wins");

if(($board[2][0]==1)&&($board[2][1]==1)&&($board[2][2]==1)) die("X wins");
if(($board[2][0]==2)&&($board[2][1]==2)&&($board[2][2]==2)) die("O wins");

if(($board[0][0]==1)&&($board[1][1]==1)&&($board[2][2]==1)) die("X wins");
if(($board[0][0]==2)&&($board[1][1]==2)&&($board[2][2]==2)) die("O wins");

if(($board[2][0]==1)&&($board[1][1]==1)&&($board[0][2]==1)) die("X wins");
if(($board[2][0]==2)&&($board[1][1]==2)&&($board[0][2]==2)) die("O wins");
//Computer
$turn= (htmlspecialchars($_GET["turn"])=='X'?'O':'X');

$scenerios= [
//tac1 tac2  replace
[[0,2],[0,1],[0,0]],
[[1,1],[2,2],[0,0]],
[[1,0],[2,0],[0,0]],

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

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

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

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

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

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

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

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

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

if($turn=='O'){
        $done=false;
        
        foreach($scenerios as $scenerio){
                if(($board[$scenerio[0][0]][$scenerio[0][1]]==2)&&
                  ( $board[$scenerio[1][0]][$scenerio[1][1]]==2)&&
                  (!$board[$scenerio[2][0]][$scenerio[2][1]])&&(!$done)){
                            $board[$scenerio[2][0]][$scenerio[2][1]]=2;
                            $done=true;}
        }
        foreach($scenerios as $scenerio){
                if(($board[$scenerio[0][0]][$scenerio[0][1]]==1)&&
                  ( $board[$scenerio[1][0]][$scenerio[1][1]]==1)&&
                  (!$board[$scenerio[2][0]][$scenerio[2][1]])&&(!$done)){
                            $board[$scenerio[2][0]][$scenerio[2][1]]=2;
                            $done=true;}
        }
        if(!$board[1][1]){
                $board[1][1]=2;
                $done=true;}
        
        if(!$done){
                $x=rand(0,2);
                $y=rand(0,2);
                while($board[$x][$y]){ 
                        $x=rand(0,2);
                        $y=rand(0,2);}
                $board[$x][$y]=2;
        }
        
        echo "<meta http-equiv=\"refresh\" content=\"0; URL='?turn=".$turn."&board=".json_encode($board)."'\" />";
}

echo "It is ".$turn."'s turn<br>";

echo "<div id=\"board\">";
$x=0;
foreach($board as $row){
        $y=0;
        foreach($row as $col){
                switch($col){
                        case 0:
                                $tac="<span class=\"none\"> </span>";
                                break;
                        case 1:
                                $tac='X';
                                break;
                        case 2:
                                $tac='O';
                                break;
                        default:
                                die("<meta http-equiv=\"refresh\" content=\"0; URL='?cheater'\" />");
                                break;
                }
                $mod= $board;
                $mod[$x][$y]= ($turn=='O')+1;
                echo ($col||$turn=='O'?"<span class=\"t\" id=\"a".$x."x".$y."\">":"<a class=\"t\" href=\"?board=".json_encode($mod)."&turn=".$turn."\" id=\"a".$x."x".$y."\">").
                        $tac.
                        ($col||$turn=='O'?"</span>":"</a>");
                $y++;
        }
        echo "<br>";
        $x++;
}

echo "<style>a.t:hover:before{content:\"".$turn."\";}a.t:hover .none{display:none;}</style>";
?>
                        </div><br>
                        <small>You can save your game by copying the url</small>
                </center>
        </body>
</html>                        
<< An html tag to contain the script is always a good habit
<< Everything in the head tag is meant to describe meta information about the page
<< The title tag sets the title of the tab
<< Everything in the style tag is the CSS
<< This CSS targets the squares













<< This CSS is applied when a square is hovered over
┓
┃This is how the board is displayed
┃These IDs are generated by the script in their respective places
┃Based on where the square is, it'll be given a border
┃Borders in CSS make a line around the defined lines
┃Like this
┃
┃
┃
┃
┃
┃
┃
┃
┃
┃
┃
┃
┃
┃
┃
┃
┃
┃
┃
┃
┃
┛
<< And then, a double border around the whole board





<< What actually is meant to be shown is put in the body tag
<< Everything in the center tag is centered. In the modern day you should really center elements with CSS but I do this because I'm oldschool
<< a tags are links, when you click on the a tag, it goes to whatever is set in the href attribute. This line is just simple navigation
<< <? Starts the PHP engine, everything from here on is PHP
<< Everything after // is counted as a comment and is not processed by the PHP engine, this won't cause errors and is usefull for giving information withing the code itself

<< "if" checks the outcome of what is inside the () and only if the outcome is true it will do the code after it
        The moment "die" is used it stops the script, $_GET is the _GET we talked about earlyer and [] gets the value of that
        
<< Default abstracted board data. Blank





<< Overrides board data if set in _GET

<< Set tie as true


<< If it is not a tie, set tie to false


<< If it is a tie show tie message


<< Everything after here checks for all win scenerios and dies for who won
























<< Switch whos turn it is because it was Xs or Os turn now it's versa

<< Now we get into the NPCs brain
<< These are preset scenerios for the NPC to check




































<< If it's the computers turn, do shit
<< Set done variable because the NPC isn't done yet

<< Loop through all scenerios and make a move that will make it win






<< Loop through all scenerios and make a move that will stop you from winning






<< Go in center if not taken



<< If hasn't made a move yet, take a random spot







<< Switch to other payers turn


<< Show whos turn it is

<< Start board element
<< Set pointer to current column being 0
<< Loop through columns
<< Set pointer to current row being 0
<< Loop through rows
<< Look through board
<< If not taken give link to your move as that spot



<< If X show X



<< If O show O


<< Otherwise someone's probably cheating


<< Reset modded board link from previus loop
<< Set mod to what would be if turn was taken
<< Show the link

<< Iterate to next column


<< Iterate to next row



<< Add a bit more CSS for previews