##Dead Code##
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");
}