HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

HTML5 / JavaScript Tic-Tac-Toe

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
javascripttoetictachtml5

Problem

As an exercise, I decided to create a simple Tic-Tac-Toe game. It is Ruby on Rails based, but as for now I'm not using the server side for anything (I intend to build up on it in the future, though).

As I'm rather new with JavaScript, HTML5 and CSS, I'd like some feedback regarding what did I do wrong or what could be done better.

index.html.erb


  
    
    
    
  
  
    
    
    
  
  
    
    
    
  
  
    
  


tic_tac_toe.js

```
var tokenAttributeName = 'token';
var idAttributeName = 'id';

var circleTokenName = 'Circle';
var crossTokenName = 'Cross';
var noTokenName = 'None';

var circleColor = 'green';
var crossColor = 'red';
var fontColor = 'black';
var font = "bold 30px Helvetica";

var resetText = "Reset";

var hoverOnOpacity = 1.0;
var hoverOffOpacity = 0.75;
var highlightTime = 100;

var turn = circleTokenName;
var won = false;

$(document).ready(function() {
drawResetCanvas();

$('canvas#reset').click(function(e) {
location.reload();
});

$('canvas').hover(
function(e) {
var field = $(this);

field.animate({ opacity: hoverOnOpacity }, highlightTime);
},
function(e) {
var field = $(this);

field.animate({ opacity: hoverOffOpacity }, highlightTime);
});

$('canvas.field').click(function(e) {
var field = $(this);
var fieldId = field.attr(idAttributeName);

if (field.attr(tokenAttributeName) != noTokenName || won) {
return;
}

if (turn == circleTokenName) {
drawCircle(fieldId);
field.attr(tokenAttributeName, circleTokenName);
}
else {
drawCross(fieldId);
field.attr(tokenAttributeName, crossTokenName);
}

//field.animate({opacity: 1.0}, 0, function() { field.animate({opacity:0.75},2000)});

if (checkWin(turn)) {
alert(turn + ' won!');
won = true;
}
else if (checkDraw()) {
alert('Draw!');
};

turn = turn == circleTokenName ? crossTokenName : circleTokenName;
});
});

function checkWin(f

Solution

First, a (proper) HTML document looks like this:


    
        Tic tac toe
    
    
        
    


Html, head, body, and title are strongly recommended, tho not required.

You seem to be using `s a lot… why? Can't you just make them images?


    
    
    

    
    
    

    
    
    


Canvases are ugly and pixely, images are beautiful and potentially vector (or at least easier to make high-res (important for retina devices)). The only downside is you have to create the images… but I just did it for you (tweak to your liking):

 
    
    

 
    


Don't make a bajillion
ids. Instead of $('canvas#f' + rowId + colId)`:

document.getElementById('container').children[rowId].children[colId]


Yeah, I hate jQuery. Especially the animations. CSS transitions are supported wide enough that you should probably use that instead. It's smoother - the DOM isn't meant to be messed around with every 20ms (as is the case with jQuery animations).

So, pretty good job for recent unzoomed desktop browsers with users who can't notice jQuery's slowness. Now just make it vector and vanilla and not have a bunch of… things in the DOM (ids, "tokens" (invalid attribute)) which can be put in arrays.

Code Snippets

<!DOCTYPE html>
<html>
    <head>
        <title>Tic tac toe</title>
    </head>
    <body>
        <!-- Stuff -->
    </body>
</html>
<div class="row">
    <img class="field" />
    <img class="field" />
    <img class="field" />
</div>
<div class="row">
    <img class="field" />
    <img class="field" />
    <img class="field" />
</div>
<div class="row">
    <img class="field" />
    <img class="field" />
    <img class="field" />
</div>
<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" fill="#f00"> <!-- An X -->
    <polygon points="0,4 4,0 50,46 46,50" />
    <polygon points="50,4 4,50 0,46 46,0" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" stroke="#090" stroke-width="5" fill="none"> <!-- An O -->
    <circle cx="25" cy="25" r="22" />
</svg>
document.getElementById('container').children[rowId].children[colId]

Context

StackExchange Code Review Q#48995, answer score: 7

Revisions (0)

No revisions yet.