Skip to content

Instantly share code, notes, and snippets.

@deanrad
Created September 6, 2013 02:41
Show Gist options
  • Save deanrad/6458897 to your computer and use it in GitHub Desktop.
Save deanrad/6458897 to your computer and use it in GitHub Desktop.
BDD version of an incremental version of player-to-player chess
<!DOCTYPE html>
</html>
<head>
<title>Jasmine Test Suite for Player-to-Player Chess</title>
</head>
<body>
<script type="text/javascript" src="//searls.github.io/jasmine-all/jasmine-all-min.js"></script>
<!-- script type="text/javascript" src="/js/jasmine-all-min.js"></script -->
<script type="text/javascript">
describe("Positions Vectors and Sides, oh my", function(){
it("are indexed a1-h8", function(){
var p = new Position('a1');
expect(p.file).toEqual('a');
expect(p.rank).toEqual('1');
expect(p.fileidx).toEqual( 0 );
expect(p.rankidx).toEqual( 0 );
expect(p.toString()).toEqual('a1');
var p = new Position('h8');
expect(p.file).toEqual('h');
expect(p.rank).toEqual('8');
expect(p.fileidx).toEqual( 7 );
expect(p.rankidx).toEqual( 7 );
expect(p.toString()).toEqual('h8');
});
it("calls the vector from d2 to d4 [0,2]", function(){
var d2 = new Position('d2'), d4 = new Position('d4');
expect(d4.minus(d2)).toEqual([0,2]);
});
it("Asserts that d2 + [0,2] is d4", function(){
var d2 = new Position('d2'), d4 = new Position('d4');
expect(d2.plus([0,2])).toEqual( d4 );
});
it("Asserts that d2 + [1,1] is e3", function(){
var d2 = new Position('d2'), e3 = new Position('e3');
expect(d2.plus([1,1])).toEqual( e3 );
});
it("Asserts that a8 is colored white (aka 'white on right' rule)", function(){
var a8 = new Position('a8');
var a1 = new Position('a1');
expect(a8.color()).toEqual('white');
expect(a1.color()).toEqual('black');
});
it("Asserts that black is the opposite of white", function(){
expect('white'.opposite()).toEqual('black');
expect('black'.opposite()).toEqual('white');
});
});
describe("The Board", function(){
it("calls the advance direction of white [0,1]", function(){
expect(Board.advanceVector('white')).toEqual([0,1]);
});
it("calls the advance direction of black [0,-1]", function(){
expect(Board.advanceVector('black')).toEqual([0, -1]);
});
it("has a configurable size, set to 8 for chess", function(){
expect(Board.xSize).toEqual(8);
expect(Board.ySize).toEqual(8);
});
it("detects invalid positions", function(){
expect(Board.validPosition('a1')).toEqual(true);
expect(Board.validPosition('d2')).toEqual(true);
expect(Board.validPosition('h8')).toEqual(true);
expect(Board.validPosition('B8')).toEqual(false);
expect(Board.validPosition('a9')).toEqual(false);
expect(Board.validPosition('Q11')).toEqual(false);
expect(Board.validPosition('')).toEqual(false);
expect(Board.validPosition(null)).toEqual(false);
expect(Board.validPosition(undefined)).toEqual(false);
});
it("knows either black or white is next to move", function(){
var b = new Board();
expect(b.turnToMove('white')).toEqual(true);
});
it("knows whether white/black king/queenside castling is available", function(){
var b = new Board();
//initially true, until a move makes it so (to be implemented later, just a field now)
expect(b.castle_available_white_king).toEqual(true);
expect(b.castle_available_white_queen).toEqual(true);
expect(b.castle_available_black_king).toEqual(true);
expect(b.castle_available_black_queen).toEqual(true);
//can change any of them
b.castle_available_white_king = false;
expect( b.castle_available_white_king ).toEqual(false);
});
it("has or does not have an enpassant square", function(){
var b = new Board();
expect(b.en_passant_square).toBeUndefined();
});
});
/*
Board state
- See FEN - the following fields define the complete state of a game, for resume purposes
- Pieces positions, who to move, castling avail w/b k/q, ep target, 1/2 move clock, 1 move clock
Liberties
- piece.liberties(board): those moves a piece is capable of regardless of game state
- board.positionOf(piece) must be defined
- passing board allows answer to be relative to a forward direction / the boards edges
- example: for a pawn, only the three forward single-steps are liberties
Blocking/Capturing rules
- piece.blocked?(board, from, to)
- eg. a piece's 'to' is blocked by its own color, can capture if the other color
- except a pawn, whose diagonal liberties are 'blocked' by emptiness also, and whose forward liberty is blocked by anything
- intervening pieces of any color matter, except for knights whose crooked liberties define no intervening pieces
Special cases
- for a pawn, moving double is an option if on its home rank, but it must set EP on the board
-
*/
describe("Space Kitty", function(){
it("meows, of course", function(){
expect( spaceKitty()).toEqual("meow!");
});
});
</script>
<script type="text/javascript">
/* begin chess code */
function Position(file,rank){
if(!rank){
if(!file || file.length != 2) return null;
f = file.substr(0,1);
r = file.substr(1,1);
}
this.file = f;
this.rank = r;
this.fileidx = f.charCodeAt(0) - 97;
this.rankidx = r - 1;
};
Position.prototype.initialize = function(fileidx, rankidx){
this.fileidx = fileidx;
this.rankidx = rankidx;
this.file = String.fromCharCode(fileidx + 97);
this.rank = rankidx+1+"";
return this;
}
Position.prototype.toString = function(){
return this.file + this.rank;
}
Position.prototype.minus = function(other){
return [this.fileidx-other.fileidx, this.rankidx-other.rankidx];
}
Position.prototype.plus = function(filerank_vector){
var newpos = new Position('a1'); //ignored
return newpos.initialize(this.fileidx + filerank_vector[0], this.rankidx + filerank_vector[1]);
}
Position.prototype.color = function(){
return ((this.fileidx+this.rankidx) % 2 == 0 ) ? 'black' : 'white';
}
//see FEN
function Board(){
this.nextToMove = 'white';
this.castle_available_white_king = true;
this.castle_available_white_queen = true;
this.castle_available_black_king = true;
this.castle_available_black_queen = true;
}
Board.xSize = 8;
Board.ySize = 8;
Board.validPosition = function(pos){
p = new Position(pos);
return p.fileidx >= 0 && p.fileidx < this.xSize &&
p.rankidx >= 0 && p.rankidx < this.ySize ;
}
Board.advanceVector = function(side){
if(side.indexOf('w') > -1)
return [0,1];
else
return [0,-1];
};
Board.prototype.turnToMove = function(side){
return (side==this.nextToMove);
}
String.prototype.opposite = function(){
if (this.toString()=='white') return 'black';
if (this.toString()=='black') return 'white';
return null;
}
/* end chess code */
window.spaceKitty = function(){ return "meow!"; };
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment