/* vim:set filetype=javascript:*/
/*jsl:import BoardPiece.js*/
/*jsl:import BoardPosition.js*/
/*jsl:import PieceColor.js*/
/*jsl:import PieceType.js*/
/*jsl:import PiecePosition.js*/
/*global Class, BoardPiece, PieceColor, PieceType, PiecePosition, BoardPosition */
/**
@class Represents a full board This is the main class to interact with.
Using this class you can: 1. Use pieces: put, remove and move them.
2. Do something with all pieces.
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
var Board = Class.create(/** @lends Board.prototype */{
/**
creates a new instance
@this {Board}
@return {Board} the new object created.
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
initialize: function() {
var i, j, ar;
// create 8x8 undefined squares
this.bd = [];
for (i = 0; i < 8; i++) {
ar = [];
for (j = 0; j < 8; j++) {
ar.push(undefined);
}
this.bd.push(ar);
}
this.pieces = [];
// callbacks
this.preAddCB = [];
this.postAddCB = [];
this.preRemoveCB = [];
this.postRemoveCB = [];
this.preMoveCB = [];
this.postMoveCB = [];
},
/**
toString method that allows you to get a nice printout for this type
@this {Board}
@return {string} string representation of this object.
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
toString: function() {
var i, j;
var str = '';
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
str += this.bd[i][j];
}
str += '\n';
}
return str;
},
/**
Check that no piece is at a certain position.
Will throw an exception if that is not the case.
@this {Board}
@param {PiecePosition} piecePosition position to check that no piece is at.
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
checkNoPieceAt: function(piecePosition) {
if (this.bd[piecePosition.x][piecePosition.y] !== undefined) {
throw 'already have piece at position ' + piecePosition.toString();
}
},
/**
Check that piece is at a certain position.
Will throw an exception if that is not the case.
@this {Board}
@param {PiecePosition} piecePosition position to check that a piece is at.
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
checkPieceAt: function(piecePosition) {
if (this.bd[piecePosition.x][piecePosition.y] === undefined) {
throw 'dont have piece at position ' + piecePosition.toString();
}
},
/**
Check that a certain piece is at a certain position.
Will throw an exception if that is not the case.
@this {Board}
@param {BoardPiece} boardPiece the piece in question.
@param {PiecePosition} piecePosition position to check that a piece is at.
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
checkBoardPieceAt: function(boardPiece, piecePosition) {
if (this.bd[piecePosition.x][piecePosition.y] !== boardPiece) {
throw 'wrong piece at position ' + piecePosition.toString();
}
},
/**
Add a piece to the position
@this {Board}
@param {BoardPiece} boardPiece piece to add.
@param {PiecePosition} piecePosition where to add the piece.
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
addPiece: function(boardPiece, piecePosition) {
this.preAddCB.forEach(function(f) {
f(boardPiece, piecePosition);
});
this.checkNoPieceAt(piecePosition);
this.bd[piecePosition.x][piecePosition.y] = boardPiece;
this.postAddCB.forEach(function(f) {
f(boardPiece, piecePosition);
});
},
/**
Remove a piece
@this {Board}
@param {BoardPiece} boardPiece piece to remove.
@param {PiecePosition} piecePosition the position to remove it from.
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
removePiece: function(boardPiece, piecePosition) {
this.checkBoardPieceAt(boardPiece, piecePosition);
this.preRemoveCB.forEach(function(f) {
f(boardPiece, piecePosition);
});
this.bd[piecePosition.x][piecePosition.y] = undefined;
this.postRemoveCB.forEach(function(f) {
f(boardPiece, piecePosition);
});
},
/**
Move a piece
@this {Board}
@param {BoardPiece} boardPiece piece to move.
@param {PiecePosition} fromPiecePosition from where to move the piece.
@param {PiecePosition} toPiecePosition to where to move the piece.
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
movePiece: function(boardPiece, fromPiecePosition, toPiecePosition) {
this.checkPieceAt(fromPiecePosition);
this.checkNoPieceAt(toPiecePosition);
this.preMoveCB.forEach(function(f) {
f(boardPiece, fromPiecePosition, toPiecePosition);
});
this.bd[fromPiecePosition.x][fromPiecePosition.y] = undefined;
this.bd[toPiecePosition.x][toPiecePosition.y] = boardPiece;
this.postMoveCB.forEach(function(f) {
f(boardPiece, fromPiecePosition, toPiecePosition);
});
},
/**
Clear the board
@this {Board}
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
clearPieces: function() {
var that = this;
this.forEachPiece(function(boardPiece, piecePosition) {
that.removePiece(boardPiece, piecePosition); });
},
/**
Add a piece to the position (seperate pieces of data).
@this {Board}
@param {string} color color of the piece (black/white).
@param {string} type type of the piece (rook/knight/bishop/queen/king/pawn).
@param {number} x x location of the piece [0..8).
@param {number} y y location of the piece [0..8).
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
addPieceVals: function(color, type , x, y) {
var boardPiece = new BoardPiece(
new PieceColor(color),
new PieceType(type));
this.addPiece(boardPiece, new PiecePosition(x, y));
},
/**
Run a function for each piece in this position
@this {Board}
@param {function()} f function to be called back for each piece.
This function should receive the piece to work on.
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
forEachPiece: function(f) {
var i, j;
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
if (this.bd[i][j] !== undefined) {
f(this.bd[i][j], new PiecePosition(i, j));
}
}
}
},
/**
Get a piece at a specific position
@this {Board}
@param {PiecePosition} piecePosition position to get the piece at.
@return {BoardPiece} the piece at the specified position.
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
getPieceAtPosition: function(piecePosition) {
this.checkPieceAt(piecePosition);
return this.bd[piecePosition.x][piecePosition.y];
},
/**
Get a piece at a specific position (in parts)
@this {Board}
@param {number} x x position to get piece at [0..8).
@param {number} y y position to get piece at [0..8).
@return {BoardPiece} the piece at the specified position.
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
getPieceAtPositionVals: function(x, y) {
return this.getPieceAtPosition(new PiecePosition(x, y));
},
/**
Do we have a piece in a specific position?
@this {Board}
@param {PiecePosition} piecePosition position to check for a piece at.
@return {boolean} whether there is a piece at the position.
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
hasPieceAtPosition: function(piecePosition) {
return this.bd[piecePosition.x][piecePosition.y] !== undefined;
},
/**
Do we have a piece in a specific position?
@this {Board}
@param {number} x x position to check for piece at [0..8).
@param {number} y y position to check for piece at [0..8).
@return {boolean} is there a piece at position.
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
hasPieceAtPositionVals: function(x, y) {
return this.hasPieceAtPosition(new PiecePosition(x, y));
},
/**
Add a callback for adding a piece
@this {Board}
@param {function()} f callback function.
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
addPiecePostAddCallback: function(f) {
this.postAddCB.push(f);
},
/**
Add a callback for removing a piece
@this {Board}
@param {function()} f callback function.
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
addPiecePostRemoveCallback: function(f) {
this.postRemoveCB.push(f);
},
/**
Add a callback for moving a piece
@this {Board}
@param {function()} f callback function.
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
addPiecePostMoveCallback: function(f) {
this.postMoveCB.push(f);
},
/**
Clear the board and add a position to the current board
@this {Board}
@param {BoardPosition} boardPosition position to set.
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
setPosition: function(boardPosition) {
this.clearPieces();
var that = this;
boardPosition.forEachPiece(function(boardPiece, piecePosition) {
that.addPiece(boardPiece, piecePosition); });
},
/**
Put the board in starting position of standard chess.
@this {Board}
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
startPosition: function() {
this.setPosition(BoardPosition.startPos());
},
/**
Move a piece according to positions.
@this {Board}
@param {PiecePosition} fromPiecePosition from where to move.
@param {PiecePosition} toPiecePosition to where to move.
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
movePieceByPos: function(fromPiecePosition, toPiecePosition) {
var boardPiece = this.getPieceAtPosition(fromPiecePosition);
this.movePiece(boardPiece, fromPiecePosition, toPiecePosition);
},
/**
Get the position of a piece
@this {Board}
@param {BoardPiece} boardPiece piece to get the position for.
@return {PiecePosition} the position of the piece in question.
@author mark.veltzer@gmail.com (Mark Veltzer)
*/
getPiecePosition: function(boardPiece) {
var i, j;
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
if (this.bd[i][j] === boardPiece) {
return new PiecePosition(i, j);
}
}
}
throw 'piece not on board ' + boardPiece;
}
});