patternjavascriptMinor
Tic-Tac-Toe game with HTML5 canvas
Viewed 0 times
withtoetictacgamehtml5canvas
Problem
I know it is a simple game, but what I am doing here is practice what I took in an AI course. I'm also playing a little with the canvas and trying to improve the readability of my code and using JavaScript as an object oriented language.
I divided my code into 3 main classes (objects).
-
The app script. This is not a class, it is just a the script that makes use of the other scripts and runs the game.
Note: I have not implemented the minimax algorithm yet.
index.html
app.js
Board.js
```
function Board(data){
data = (data === 'undefined') ? {} : data;
if(data){
this.canvas = data.canvas;
this.ctx = data.ctx;
this.cell = [];
this.isXTurn = true;
this
I divided my code into 3 main classes (objects).
- Board class which represents the board object and contain its properties like width and height and the canvas to draw with.
- Cell class which represents the individual cell object and contain its properties also.
-
The app script. This is not a class, it is just a the script that makes use of the other scripts and runs the game.
- Is what I'm doing by dividing my code into these classes reasonable or it can be done in a simpler way?
- Is making these classes affecting the performance or not?
- Does my work need to be divided into more classes(objects)?
- What I can do better?
Note: I have not implemented the minimax algorithm yet.
index.html
Tic
Tic Tac Toc
app.js
$(document).ready(function(){
var canvas = $("#canvas").get(0);
var ctx = canvas.getContext('2d');
var data =
{
canvas : canvas,
ctx : ctx,
x : canvas.width/2-150,
y : canvas.height/2-150,
width : 300,
height : 300,
playerX: "Abdulaziz",
playerY: "salmaaa"
};
var board = new Board(data);
board.drawBoard();
$("#canvas").click({board: board, canvasId: "canvas"}, board.click);
});Board.js
```
function Board(data){
data = (data === 'undefined') ? {} : data;
if(data){
this.canvas = data.canvas;
this.ctx = data.ctx;
this.cell = [];
this.isXTurn = true;
this
Solution
Dead Code
This isn't doing anything, so just delete it.
Enums
Right here, you are using a string literal to specify the player who needs to move:
Typically, you would use a player
Spacing
If you put spaces around your operators, your code is easier to read, debug (especially when finding order-of-operations bugs), and maintain:
Early Returns
Right here, you have some unnecessarily deep indentation:
If I wrote this, I would use early returns at the top to use less indentation:
else{
//undefined data object
}This isn't doing anything, so just delete it.
Enums
Right here, you are using a string literal to specify the player who needs to move:
this.player = "x";Typically, you would use a player
enum to specify the player.Spacing
If you put spaces around your operators, your code is easier to read, debug (especially when finding order-of-operations bugs), and maintain:
this.ctx.moveTo((this.x+2*this.width/3), this.y);Early Returns
Right here, you have some unnecessarily deep indentation:
if(Board.isInBounds(coord) && board.gameStatus == "turn"){
var cell = board.getCell(coord);
if(board.cell[cell.v][cell.h].player == ""){
board.moves++;
if(board.isXTurn){
board.cell[cell.v][cell.h].drawX();
board.isXTurn = !board.isXTurn;
}else{
board.cell[cell.v][cell.h].drawO();
board.isXTurn = !board.isXTurn;
}
board.gameStatus = board.checkStatus(board);
if(board.gameStatus == "turn"){
board.drawStatusBar(board, "Player "+((board.isXTurn)?"X":"O")+" Turn!!");
}else if(board.gameStatus == "win"){
board.drawStatusBar(board, "Player "+((board.isXTurn)?"O":"X")+" Won!!");
}else if(board.gameStatus == "tie"){
board.drawStatusBar(board, "It is a Tie :D");
}
}
}If I wrote this, I would use early returns at the top to use less indentation:
if (!Board.isInBounds(coord) || board.gameStatus != "turn") {
return;
}
var cell = board.getCell(coord);
if (board.cell[cell.v][cell.h].player != "") {
return;
}
board.moves++;
if (board.isXTurn) {
board.cell[cell.v][cell.h].drawX();
board.isXTurn = !board.isXTurn;
} else {
board.cell[cell.v][cell.h].drawO();
board.isXTurn = !board.isXTurn;
}
board.gameStatus = board.checkStatus(board);
if (board.gameStatus == "turn") {
board.drawStatusBar(board, "Player "+((board.isXTurn)?"X":"O")+" Turn!!");
} else if (board.gameStatus == "win"){
board.drawStatusBar(board, "Player "+((board.isXTurn)?"O":"X")+" Won!!");
} else if (board.gameStatus == "tie"){
board.drawStatusBar(board, "It is a Tie :D");
}Code Snippets
else{
//undefined data object
}this.player = "x";this.ctx.moveTo((this.x+2*this.width/3), this.y);if(Board.isInBounds(coord) && board.gameStatus == "turn"){
var cell = board.getCell(coord);
if(board.cell[cell.v][cell.h].player == ""){
board.moves++;
if(board.isXTurn){
board.cell[cell.v][cell.h].drawX();
board.isXTurn = !board.isXTurn;
}else{
board.cell[cell.v][cell.h].drawO();
board.isXTurn = !board.isXTurn;
}
board.gameStatus = board.checkStatus(board);
if(board.gameStatus == "turn"){
board.drawStatusBar(board, "Player "+((board.isXTurn)?"X":"O")+" Turn!!");
}else if(board.gameStatus == "win"){
board.drawStatusBar(board, "Player "+((board.isXTurn)?"O":"X")+" Won!!");
}else if(board.gameStatus == "tie"){
board.drawStatusBar(board, "It is a Tie :D");
}
}
}if (!Board.isInBounds(coord) || board.gameStatus != "turn") {
return;
}
var cell = board.getCell(coord);
if (board.cell[cell.v][cell.h].player != "") {
return;
}
board.moves++;
if (board.isXTurn) {
board.cell[cell.v][cell.h].drawX();
board.isXTurn = !board.isXTurn;
} else {
board.cell[cell.v][cell.h].drawO();
board.isXTurn = !board.isXTurn;
}
board.gameStatus = board.checkStatus(board);
if (board.gameStatus == "turn") {
board.drawStatusBar(board, "Player "+((board.isXTurn)?"X":"O")+" Turn!!");
} else if (board.gameStatus == "win"){
board.drawStatusBar(board, "Player "+((board.isXTurn)?"O":"X")+" Won!!");
} else if (board.gameStatus == "tie"){
board.drawStatusBar(board, "It is a Tie :D");
}Context
StackExchange Code Review Q#92272, answer score: 5
Revisions (0)
No revisions yet.