Yes. I'll give the moon a punch.

Our objective: To create a simple game of Tic - Tac - Toe using HTML5, CSS3, and Javascript.
Tools used:
HTML5 - for the page and canvas
CSS3 - animations
Javascript - logic of the game
Google Chrome latest version - for the specific CSS3 styles which we would be using
First of all, an introduction to Tic - Tac - Toe:
Wikipedia says:
"Tic - Tac - Toe is a pencil-and-paper game for two players, X and O, who take turns marking the spaces in a 3×3 grid. The X player usually goes first. The player who succeeds in placing three respective marks in a horizontal, vertical, or diagonal row wins the game."
What we will do:
Tic - Tac - Toe for two human players who will alternate playing using the mouse.
Restrictions:
- The game will restart when all squares are filled and no one won. Yeah, it happens.
- The game, when a user won, will ask if you'd like to restart the game. If so, the game will restart. If not, then you'll be looking at the same page. BEWARE:Bugs beyond this point are not covered. So why not restart after someone won automatically? Well, you might want to check where you lost and where your opponent won.

Why will we use <insert technology here>?:
HTML5 = Canvas! I thought they'd be hard to use but they were easy enough. We will use them for the boxes.
CSS3 = Animation! Wow. No more need for flash. This game will have a "flashy" opening.
Javascript = Logic! Um, that's it. The backbone of the game.
What you'll get from reading this long tutorial:
- A basic understanding of HTML5's canvases.
- A basic understanding of CSS3's animations.
- Basic Javascript.
Let's start!
First, we need to create the html file. Create "tictactoe.html" on your favorite text editor or if you're advanced enough you can name it whatever you like, just don't forget to make the extension ".html".
Checklist: Make html file.
Next, we need to fill the html file with html content. Open it up, it's empty. We'll start by typing this tag:
<!DOCTYPE html>
That's how the browser will know that your file will be rendered using HTML5!
Next we put in the basic parts of an html file: the html,head, and body tags. Put it under your doctype.
<html> <head> </head> <body> </body> </html>
Notice something? Yeah. When html elements are concerned, we use the "<" and ">" characters to say that it is an html element. So enclosed in those two characters are html element names. "html" is an element, so is "head" and "body". Now what's up with those "/"? Well, they denote that a particular element ends its part on that tag where they put that backslash. So where do we put stuff then? Well, inside the elements! It's something like this:
Html contains head and body. Head and body can contain other elements, as you'll see when we go along.
What is head? What is body? Yeah, they're like our human parts, and they act almost the same.
Head - Here is where we put most of the stuff that can affect the body, and the whole html page in general. Hey, kind of like our minds! Examples of things we could put in the head part are CSS and Javascript codes.
Body - This contains the elements which will show in the page. It will show us what the page will look like. This is supplemented by other kinds of technologies to give it life.
So let's start with the body first. We need to create the title of the page! What should it be? For this tutorial, let us name it "The Very Basic Tic - Tac - Toe!". Do it like this:
<body> <h1>The </h1><h2>Very Basic</h2><h3> Tic - Tac - Toe!</h3> </body>
See, now our body contains something. Wait, what could those h's be? Well we could do something like post the title without those tags but we need to use them in a moment. So what are those hs?
<h1>These are called "headers". Headers are text you could use for titles and such.</h1> <h2>Yeah there are lots of them. Use as much as you want, but only if...</h2> <h3>you have good reason to. For example, you have varying types of titles, headers are good to use!</h3>
There.
Now we need the boxes! Oh wait. Boxes? No. Canvas? Yeah. This is HTML5, baby! So we will utilize the new feature of HTML: canvas!
<canvas></canvas>
Yeah! We now have a canvas. Wait, it doesn't show yet. We need to specify some data for it to do our bidding and be who we want it to be, a badass Tic - Tac - Toe box!
<canvas width="50" height="50" style="border:1px solid black"></canvas>
It now shows! Let's try to click it... it does nothing! Stupid canvas! Oh wait, we need to give it more attributes to be able to function properly. We forgive you canvas!
<canvas id = "canvas1" width="50" height="50" style="border:1px solid black" onclick="canvasClicked(1)"></canvas>
Dissecting the canvas element:
id = We need to give it an id so that we won't mistake it for another canvas. Wait, there's another canvas? Yeah, we're making a Tic-Tac-Toe game! We need 9 boxes! Duh!
width,height = Specifies their namesake lengths.
style = This shouldn't even be here! For the sake of this tutorial we'll forgive it now, but remember it is always good practice to separate the style from the html page.
onclick = When we click the canvas, we want it to do something. Now what do we want it to do? Render a drawing! A circle or an x. What is that value inside? Well it's a Javascript function! We will now head to Javascript land!
But first, we have to make sure our business with the html body is done: Create 9 canvasses and change their id to canvas + "canvas number" and on the onclick value change the number inside "canvasClicked(<number goes here>)" to the number of that canvas.
Off to Javascript! So how did we get here on the first place?
When a canvas is clicked, it expects the browser to look for the function canvasClicked on the html. Now where is canvasClicked? It's yet unborn, let us make it! Now we'll tackle the head element of the html page! We'll be putting in another language: Javascript!
Do this at your head element:
<head> <script type="text/javascript"> </script> </head>
We now have a new element, the <script> tags. These can contain other languages to help with our html page. Now, we will be using the help of Javascript.
BEWARE: What follows is the logic behind the Tic - Tac - Toe game. Skip this, and you will be lost on how the game works.
So let us begin! Where did we leave off? Oh yeah, we just called canvasClicked. What is it? Why did we call it? It's a Javascript function! What is a function?
A function is a set of procedures that is used to create a certain task that is often repeated elsewhere. See our 9 canvasses? We have 9 canvasClicked calls. So we need to use canvasClicked to accommodate them all.
This is the basic structure of a Javascript function:
function <functionName>(<arguments if any>) { //codes here <optional return value> }
Now if you pay attention to the canvasClicked call, you will see that we supply it with numbers. That is an argument. Here is the complete code for the Javascript used in this game and I will try my best to tell you how it works:
<script type="text/javascript"> //Global Variables var painted; var content; var winningCombinations; var turn = 0; var theCanvas; var c; var cxt; var squaresFilled = 0; var w; var y; //Instanciate Arrays window.onload=function(){ painted = new Array(); content = new Array(); winningCombinations = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]]; for(var l = 0; l <= 8; l++){ painted[l] = false; content[l]=''; } } //Game methods function canvasClicked(canvasNumber){ theCanvas = "canvas"+canvasNumber; c = document.getElementById(theCanvas); cxt = c.getContext("2d"); if(painted[canvasNumber-1] ==false){ if(turn%2==0){ cxt.beginPath(); cxt.moveTo(10,10); cxt.lineTo(40,40); cxt.moveTo(40,10); cxt.lineTo(10,40); cxt.stroke(); cxt.closePath(); content[canvasNumber-1] = 'X'; } else{ cxt.beginPath(); cxt.arc(25,25,20,0,Math.PI*2,true); cxt.stroke(); cxt.closePath(); content[canvasNumber-1] = 'O'; } turn++; painted[canvasNumber-1] = true; squaresFilled++; checkForWinners(content[canvasNumber-1]); if(squaresFilled==9){ alert("THE GAME IS OVER!"); location.reload(true); } } else{ alert("THAT SPACE IS ALREADY OCCUPIED WITH YOUR HEART!"); } } function checkForWinners(symbol){ for(var a = 0; a < winningCombinations.length; a++){ if(content[winningCombinations[a][0]]==symbol&&content[winningCombinations[a][1]]== symbol&&content[winningCombinations[a][2]]==symbol){ alert(symbol+ " WON!"); playAgain(); } } } function playAgain(){ y=confirm("PLAY AGAIN?"); if(y==true){ alert("OKAY! ^^/>"); location.reload(true); } else{ alert("SO LONG,SUCKER!"); } }
A quick glance shows us that there are 4 functions: an anonymous function upon window load,canvasClicked, checkForWinners, and playAgain. Plus a lot of lines outside the functions. What are those things?
The codes outside are global variables. They are used throughout the life of the html page to hold values that are of importance to the game. How does Javascript declare variables? You do it this way:
var variableName = <value>;
What? Only var? No Integer,String or anything? Lame. Well, Javascript is intelligent. See:
var x = 2; var y = "Apple"; var z = 1; alert(x+z); //Will give us 1! alert(x+y+z);//Will give us "2Apple1", whatever that means.
Point is, Javascript will determine what data type your values are. Well, you could explicitly declare a variable's type such as this:
var x = new Array();// This will ensure that x is treated like an array.
I'll point out where we need those global variables when we need them.
The anonymous function upon the loading of the window is what we use to instanciate all the values for arrays. Arrays are group of data that can be accessed through the use of their indices. In this function we instanciate the content,winningCombination and painted arrays. We use content array to see what the canvas contains and we use the painted array to check if the canvas contains something already to prevent using that canvas again. Using our for loop we automate the giving of values to the painted and content arrays. We can simultaneously give them values since they have the same length. The array winningCombinations is another matter.
Array winningCombinations is a multi-dimensional array:meaning it goes through two or more indices. We use two. The main index tells us that this particular index holds another array of values. The second index lets us access particular values of that particular base index. In here we give the winningCombinations all the possible combinations where a player could win in Tic - Tac - Toe, and we will be using it shortly.
So now that we're done with the anonymous function, lets check the main functions of the game!
First function, canvasClicked! Ah, we finally meet. So canvasClicked takes a number eh? Here is the step by step explanation!
function canvasClicked(canvasNumber)
Upon first call, canvasClicked gives the number we sent it from the body of the html to the variable canvasNumber. Why do we need to do this? Well if we just pass a number to this function it will always use that value.
Next lines we have:
theCanvas = "canvas"+canvasNumber;
Variable theCanvas is a global variable, meaning that we don't need to instanciate it everytime we give it a value. See "canvas"? That's a constant string we need to use, and we add to it's tail end the canvasNumber variable. This would give us the complete name of any of the canvasses down on the body. See now? So if we clicked canvas1, canvasClicked will receieve 1, then instantly give theCanvas the value "canvas1". This is how we distinguish what canvas we are now dealing with.
Next lines will finally show us how to use the canvas of HTML5!:
c = document.getElementById(theCanvas);//variable c will now hold the canvas we want, so what is this document.getElementById? It's used in Javascript to access parts of the html page dynamically! See the id attribute we gave on the body? This one will find if there is an id which corresponds to the "theCanvas" variable cxt = c.getContext("2d"); //this gives us the context of the canvas. We will use 2d to draw in the x and y coordinates if(painted[canvasNumber-1] ==false){//this condition tells us that the canvas isn't occupied, we should draw on it, and draw we will! if(turn%2==0){//The '%' or modulus operator gives us the remainder of two values. The "turn" value is globally declared every turn made it is incremented. This condition determines whose turn it is now. //Finally,drawing in canvasses! cxt.beginPath();//this makes sure that we begin drawing, kind of like putting a pencil beside the paper cxt.moveTo(10,10);//This moves the imaginary cursor to a specific location in our canvas, always remember the first value is the x coordinate while the next value is the y coordinate cxt.lineTo(40,40); //This draws a line! From 10,10 to 40,40, we just drew a diagonal line! cxt.moveTo(40,10);//Again, we move teh imaginary cursor cxt.lineTo(10,40);//Again draw another diagonal line to complete the x cxt.stroke();//This command will now draw the lines cxt.closePath();// Will put away the cursor for us. content[canvasNumber-1] = 'X';//This gives the array content the value of 'X', meaning X just marked this canvas } else{//If it isn't X's turn, it's O's turn! Let's draw a circle! cxt.beginPath(); cxt.arc(25,25,20,0,Math.PI*2,true);//Instead of moving to and fro line to line we just use the arc method. The the first three variables are x, y, and radius. X and Y will be the center of the circle cxt.stroke(); cxt.closePath(); content[canvasNumber-1] = 'O'; } turn++;//We increment the turn so that we now that next turn would be the other player! painted[canvasNumber-1] = true;//We tell that this particular canvas is filled squaresFilled++;//We tell that the number of canvasses filled has gone up checkForWinners(content[canvasNumber-1]);//Another function! We'll give it the content of the current canvas so we know which player just made a turn
After drawing the appropriate symbol when a turn is used, we need to check if that turn decided the game! Hence, the checkForWinners function!
function checkForWinners(symbol){ for(var a = 0; a < winningCombinations.length; a++){ if(content[winningCombinations[a][0]]==symbol&&content[winningCombinations[a][1]]== symbol&&content[winningCombinations[a][2]]==symbol){ alert(symbol+ " WON!"); playAgain(); } } }
The function checkForWinners takes in the symbol so that we know what current player just made a move. In the for loop we use the array winningCombinations and give it to content. Why so? Let us dissect this function!
//content array contains either a blank, 'X' or a 'O', so in conjunction with the winningCombinations if we do this: content[winningCombinations[a][2]] //It is equivalent to: content[<a number of a canvas>]
Now as you can see there are three checks if the symbol is equal to three different canvas locations. That is where we use the winningCombinations array. See, the variable a will tell us that the array is currently on a particular combination, and the static numbers of 0,1, and 2 each correspond to the values inside that current index, since there should be 3 to make a line in Tic - Tac - Toe.
Now if our if proves true, the symbol would win. Of course the value of symbol, not symbol itself. So we print a message that the current player(the current value of symbol) won. If not, it's the next players turn. So what happens if someone wins?
We'll we have the last function: playAgain.
function playAgain(){ y=confirm("PLAY AGAIN?");// confirm will show a popup box with the values "OK" or "CANCEL", choosing ok will yield the value "true" to y, otherwise, false. if(y==true){ alert("OKAY! ^^/>"); location.reload(true);//We reload the page automatically! Yeah, with all that crazy animation at the beginning. } else{ alert("SO LONG,SUCKER!");//Don't want to quit? Prepare for a world of pain. This one I did not cover. } }
And we finish with the Javascript section. Whew! That was tiring. Anyway let's now move to the last part, the CSS3 thing! We will use it to give an opening animation to our page. It looks bleak and dreary. We will try to defy common sense and make webpage elements move without flash! Take that Adobe!
Anyway to start off we need to create a new file. I named it "css3.css". You can name it whatever you like as long as it ends with the extension ".css". Save it on the same directory you have the html file unless you want to do directory thingies. You probably could, use Google.
Anyway go inside the css file and put in these codes:
//Simple CSS body{ text-align:center; } .box{ text-align:left; width:auto; height:auto; } //The CSS3 Magic Begins Here! TM h3{ position:relative; -webkit-animation:h3Animation 5s; } h1{ position:relative; -webkit-animation:h1Animation 5s; } h2{ position:relative; -webkit-animation:h2Animation 5s; } canvas{ position:relative; -webkit-animation:canvasAnimation 5s; } @-webkit-keyframes canvasAnimation { 0% {-webkit-transform:rotate(90deg);left:0px; top:0px;} } @-webkit-keyframes h1Animation { 0% {-webkit-transform:rotate(0deg)} 25% {-webkit-transform:rotate(90deg)} 50% {-webkit-transform:rotate(180deg)} 75% {-webkit-transform:rotate(270deg)} 100% { -webkit-transform:rotate(360deg)} } @-webkit-keyframes h2Animation{ 0% {-webkit-transform: scale(1,2);} 25% {-webkit-transform: scale(2,3);} 50% {-webkit-transform: scale(3,4);} 75% {-webkit-transform: scale(4,5);} 100% { -webkit-transform: scale(0,0);} } @-webkit-keyframes h3Animation{ 0% {-webkit-transform: scale(0,0);} 50% {-webkit-transform: scale(0,0);} 100% {-webkit-transform: scale(100,100);} }
First let us dissect a piece of code of simple CSS:
body//This is the name of the element in your html page. This says that it will style the body of the html. { text-align:center;//This is a style. On the left hand style is the style we want to change, the right hand side denotes the value of that style } .box//Some elements begin with a dot. This says that somewhere in our html page there is an element with an id called "box". We can use "#" if we want to use classes, but another tutorial can teach you that. { text-align:left; width:auto; height:auto; }
CSS3 Part!(AKA Magic or World Without Flash)
First, how do we give an element an animation?
canvas { position:relative; -webkit-animation:canvasAnimation 5s; }
-webkit-animation tells us that this animation will work for Chrome. Inside it are two values, the first one, "canvasAnimation" is the name of the animation that element will perform. Beside it is time, in seconds, on how long it will take the element will perform the animation.
Of to the magic!
@-webkit-keyframes canvasAnimation //The name of the animation! See, it looks just like a style { 0% {-webkit-transform:rotate(90deg);left:0px; top:0px;} //The percentage tells us what it will do on that percentage of the time specified on the animation. So as you can see at the start of the page, our canvasses will rotate! Without flash! }
For a more fine grained explanation let us check the animation for our headers:
@-webkit-keyframes h1Animation //Animation for our 1st header, rotating header { 0% {-webkit-transform:rotate(0deg)} //At the start of the page, do nothing 25% {-webkit-transform:rotate(90deg)}//25% in,rotate 90 degrees 50% {-webkit-transform:rotate(180deg)}//50% in,rotate 180 degrees 75% {-webkit-transform:rotate(270deg)}//75% in, rotate 270 degrees 100% { -webkit-transform:rotate(360deg)}//at the final seconds rotate 270 degrees } @-webkit-keyframes h2Animation // Animation for our 2nd header,growing header { 0% {-webkit-transform: scale(1,2);}//Start of the page,scale the header 1 times its width and 2 times its height 25% {-webkit-transform: scale(2,3);} 50% {-webkit-transform: scale(3,4);} 75% {-webkit-transform: scale(4,5);} 100% { -webkit-transform: scale(0,0);}//Go back to its original size } @-webkit-keyframes h3Animation// Animation for our 3nd header,surprise header(Actually, it's just growing header again) { 0% {-webkit-transform: scale(0,0);}//Don't let it show up 50% {-webkit-transform: scale(0,0);}//I said don't! 100% {-webkit-transform: scale(100,100);}//Now go! }
If you can run the page, you will see that it is fascinating to look at. Most of the people would tell you it's flash or Jquery but it is just simple CSS3!
Now, we've finished the whole Tic - Tac - Toe!
Full codes:
tictactoe.html
<!DOCTYPE HTML> <html> <head> <link rel="stylesheet" type="text/css" href="css3.css"/> <script type="text/javascript"> //Global Variables var painted; var content; var winningCombinations; var turn = 0; var theCanvas; var c; var cxt; var squaresFilled = 0; var w; var y; //Instanciate Arrays window.onload=function(){ painted = new Array(); content = new Array(); winningCombinations = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]]; for(var l = 0; l <= 8; l++){ painted[l] = false; content[l]=''; } } //Game methods function canvasClicked(canvasNumber){ theCanvas = "canvas"+canvasNumber; c = document.getElementById(theCanvas); cxt = c.getContext("2d"); if(painted[canvasNumber-1] ==false){ if(turn%2==0){ cxt.beginPath(); cxt.moveTo(10,10); cxt.lineTo(40,40); cxt.moveTo(40,10); cxt.lineTo(10,40); cxt.stroke(); cxt.closePath(); content[canvasNumber-1] = 'X'; } else{ cxt.beginPath(); cxt.arc(25,25,20,0,Math.PI*2,true); cxt.stroke(); cxt.closePath(); content[canvasNumber-1] = 'O'; } turn++; painted[canvasNumber-1] = true; squaresFilled++; checkForWinners(content[canvasNumber-1]); if(squaresFilled==9){ alert("THE GAME IS OVER!"); location.reload(true); } } else{ alert("THAT SPACE IS ALREADY OCCUPIED WITH YOUR HEART!"); } } function checkForWinners(symbol){ for(var a = 0; a < winningCombinations.length; a++){ if(content[winningCombinations[a][0]]==symbol&&content[winningCombinations[a][1]]== symbol&&content[winningCombinations[a][2]]==symbol){ alert(symbol+ " WON!"); playAgain(); } } } function playAgain(){ y=confirm("PLAY AGAIN?"); if(y==true){ alert("OKAY! ^^/>"); location.reload(true); } else{ alert("SO LONG,SUCKER!"); } } </script> </head> <body> <div id ="box"> <h1>THE</h1><h2> VERY BASIC</h2><h3> TIC - TAC - TOE!</h3> <canvas id = "canvas1" width="50" height="50" style="border:1px solid black" onclick="canvasClicked(1)"></canvas> <canvas id = "canvas2" width="50" height="50" style="border:1px solid black" onclick="canvasClicked(2)"></canvas> <canvas id = "canvas3" width="50" height="50" style="border:1px solid black" onclick="canvasClicked(3)"></canvas><br/> <canvas id = "canvas4" width="50" height="50" style="border:1px solid black" onclick="canvasClicked(4)"></canvas> <canvas id = "canvas5" width="50" height="50" style="border:1px solid black" onclick="canvasClicked(5)"></canvas> <canvas id = "canvas6" width="50" height="50" style="border:1px solid black" onclick="canvasClicked(6)"></canvas><br/> <canvas id = "canvas7" width="50" height="50" style="border:1px solid black" onclick="canvasClicked(7)"></canvas> <canvas id = "canvas8" width="50" height="50" style="border:1px solid black" onclick="canvasClicked(8)"></canvas> <canvas id = "canvas9" width="50" height="50" style="border:1px solid black" onclick="canvasClicked(9)"></canvas> </div> </body> </html>
css3.css
body{ text-align:center; } .box{ text-align:left; width:auto; height:auto; } h3{ position:relative; -webkit-animation:h3Animation 5s; } h1{ position:relative; -webkit-animation:h1Animation 5s; } h2{ position:relative; -webkit-animation:h2Animation 5s; } canvas{ position:relative; -webkit-animation:canvasAnimation 5s; } @-webkit-keyframes canvasAnimation { 0% {-webkit-transform:rotate(90deg);left:0px; top:0px;} } @-webkit-keyframes h1Animation { 0% {-webkit-transform:rotate(0deg)} 25% {-webkit-transform:rotate(90deg)} 50% {-webkit-transform:rotate(180deg)} 75% {-webkit-transform:rotate(270deg)} 100% { -webkit-transform:rotate(360deg)} } @-webkit-keyframes h2Animation{ 0% {-webkit-transform: scale(1,2);} 25% {-webkit-transform: scale(2,3);} 50% {-webkit-transform: scale(3,4);} 75% {-webkit-transform: scale(4,5);} 100% { -webkit-transform: scale(0,0);} } @-webkit-keyframes h3Animation{ 0% {-webkit-transform: scale(0,0);} 50% {-webkit-transform: scale(0,0);} 100% {-webkit-transform: scale(100,100);} }
Questions? Violent reactions? Suggestions?
Whew. I want to thank:
WC3Schools for my 1 hour knowledge of HTML5/CSS3.
My friends at the workplace who made me go on.
This computer which is not mine.
To God, for giving me brains to do this thing.
To DICers for not trashing this tutorial(I can still hope right?).
And to myself, a pat on the back for not giving up and w.
I hope if you've read the whole thing you have a basic understanding of HTML5,CSS3 and Javascript. I know now I do.
That's it, thanks all!

This post has been edited by fromTheSprawl: 15 September 2011 - 08:02 PM