brandonclay brandonclay - 14 days ago 5
Javascript Question

HTML/JavaScript Tic Tac Toe with a 2D array

I am fairly new to HTML5 and JavaScript and i am trying to learn game programming. So i decided to try to make a Tic Tac Toe game with the board being rendered from a 2D array. I set it up so it changes color with the CSS:hover but now i'm just trying to make each box change to the color red when it is clicked and this is where i am stuck.

I'm not looking for anyone to finish my code for me its just I am trying to take things slow(ish) and i would like to figure those out on my own. My question is how do i make each box change color when you click? Currently i have each element of the array create a and i then positioned them and added a addEventListener to their class. My code KIND-OF works in the sense that the very last element changes color when you click it, but none of the others do.

Here's my code.

<!doctype html>
<title>Tic Tac Toe</title>

<style>

#stage
{
position: relative;
}

.cell
{
position: absolute;
width: 100px;
height: 100px;
border: 1px solid black;
background-color: white;
}

.cell:hover
{
background-color: blue;
}

</style>

<div id="stage"></div>

<script>

//get a reference to the stage
var stage = document.querySelector("#stage");

//the 2d array that defines the board
var board =
[
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
];

//the size of each cell
var SIZE = 100;

//the space between each cell
var SPACE = 10;

//display the array
var ROWS = board.length;
var COLUMNS = board[0].length;

for(var row = 0; row < ROWS; row++)
{
for(var column = 0; column < COLUMNS; column++)
{
//create a div HTML element called cell
var cell = document.createElement("div");

//set its CSS class to cell
cell.setAttribute("class", "cell");

//add the div HTML element to the stage
stage.appendChild(cell);

//position the cell
cell.style.top = row * (SIZE + SPACE) + "px";
cell.style.left = column * (SIZE + SPACE) + "px";
}
}

cell.addEventListener("click", clickHandler, false);

function clickHandler()
{
cell.style.backgroundColor = "red";
console.log("worked");
}

</script>


Any help would be greatly appreciated! Thanks!

Answer

There's one simple mistake, you bound the click handler outside your loop. When you move it inside the loop, you'll need to change cell.style to this.style, because cell will reference the last value of the variable after the loop instead of the current cell.

It's also worth noting that your current code is not compatible with Internet Explorer 8 and below because of the addEventListener method. It is recommended that if you plan on manipulating elements on your page, you use jQuery, which makes these compatibility issues irrelevant to some degree (in this case you would need the v1.x.x version of jquery, since v2.x.x has dropped support for IE 8)

var stage = document.querySelector("#stage");

//the 2d array that defines the board
var board = [
    [0, 0, 0],
    [0, 0, 0],
    [0, 0, 0]
];

//the size of each cell
var SIZE = 100;

//the space between each cell
var SPACE = 10;

//display the array
var ROWS = board.length;
var COLUMNS = board[0].length;

for(var row = 0; row < ROWS; row++){
    for(var column = 0; column < COLUMNS; column++){
        //create a div HTML element called cell
        var cell = document.createElement("div");

        //set its CSS class to cell
        cell.setAttribute("class", "cell");

        //add the div HTML element to the stage
        stage.appendChild(cell);

        //position the cell
        cell.style.top = row * (SIZE + SPACE) + "px";
        cell.style.left = column * (SIZE + SPACE) + "px";

        //handle click
        cell.addEventListener("click", clickHandler, false);
    }
}

function clickHandler(){
    this.style.backgroundColor = "red";
    console.log("worked");
}