575 lines
17 KiB
JavaScript
575 lines
17 KiB
JavaScript
|
/*
|
||
|
* Copyright(c) 2013-2017 - jocly.com
|
||
|
*
|
||
|
* You are allowed to use and modify this source code as long as it is exclusively for use in the Jocly API.
|
||
|
*
|
||
|
* Original authors: Jocly team
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
(function() {
|
||
|
|
||
|
var geometry = Model.Game.cbBoardGeometryGrid(12,12);
|
||
|
|
||
|
Model.Game.cbDefine = function() {
|
||
|
|
||
|
var $this = this;
|
||
|
|
||
|
/*
|
||
|
* Movement/capture graph for the prince
|
||
|
*/
|
||
|
function PrinceGraph(side) {
|
||
|
var graph={};
|
||
|
for(var pos=0;pos<geometry.boardSize;pos++) {
|
||
|
graph[pos]=[];
|
||
|
var forward=[]; // hold the pos line in front of the piece
|
||
|
var pos1=geometry.Graph(pos,[0,side]);
|
||
|
if(pos1!=null) {
|
||
|
forward.push(pos1 | $this.cbConstants.FLAG_MOVE | $this.cbConstants.FLAG_CAPTURE); // capture and move allowed at first forward position
|
||
|
pos1=geometry.Graph(pos1,[0,side]);
|
||
|
if(pos1!=null)
|
||
|
forward.push(pos1 | $this.cbConstants.FLAG_MOVE); // move to second forward only, no capture
|
||
|
graph[pos].push($this.cbTypedArray(forward));
|
||
|
}
|
||
|
}
|
||
|
return $this.cbMergeGraphs(geometry,
|
||
|
$this.cbShortRangeGraph(geometry,[[-1,-1],[-1,1],[-1,0],[1,0],[1,-1],[1,1],[0,-side]]), // direction other than forward
|
||
|
graph // forward direction
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Movement/capture graph for the eagle
|
||
|
*/
|
||
|
function EagleGraph() {
|
||
|
var flags = $this.cbConstants.FLAG_MOVE | $this.cbConstants.FLAG_CAPTURE;
|
||
|
var graph={};
|
||
|
for(var pos=0;pos<geometry.boardSize;pos++) {
|
||
|
graph[pos]=[];
|
||
|
[[-1,-1],[-1,1],[1,-1],[1,1]].forEach(function(delta) { // loop on all 4 diagonals
|
||
|
var pos1=geometry.Graph(pos,delta);
|
||
|
if(pos1!=null) {
|
||
|
for(var dir=0;dir<2;dir++) { // dir=0 for row, dir=1 for column
|
||
|
var away=[] // hold the sliding line
|
||
|
for(var n=1;n<11;n++) { // board is 12 cells long, so only consider max 11 cell displacements
|
||
|
var delta2=[];
|
||
|
delta2[dir]=delta[dir]*n;
|
||
|
delta2[1-dir]=0; // delta2 is now only about moving orthogonally, away from the piece
|
||
|
var pos2=geometry.Graph(pos1,delta2);
|
||
|
if(pos2!=null) {
|
||
|
if(n==1) // possible to slide at least 1 cell, make sure the diagonal cell is not occupied, but cannot move to this cell
|
||
|
away.push(pos1 | $this.cbConstants.FLAG_STOP);
|
||
|
away.push(pos2 | flags);
|
||
|
}
|
||
|
}
|
||
|
if(away.length>0)
|
||
|
graph[pos].push($this.cbTypedArray(away));
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
return $this.cbMergeGraphs(geometry,
|
||
|
$this.cbShortRangeGraph(geometry,[[-1,-1],[-1,1],[1,-1],[1,1]]),
|
||
|
graph
|
||
|
);
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
|
||
|
geometry: geometry,
|
||
|
|
||
|
pieceTypes: {
|
||
|
|
||
|
0: {
|
||
|
name: 'pawn-w',
|
||
|
aspect: 'fr-pawn',
|
||
|
graph: this.cbPawnGraph(geometry,1),
|
||
|
value: 1,
|
||
|
abbrev: '',
|
||
|
fenAbbrev: 'P',
|
||
|
epCatch: false,
|
||
|
},
|
||
|
|
||
|
1: {
|
||
|
name: 'ipawn-w',
|
||
|
aspect: 'fr-pawn',
|
||
|
graph: this.cbInitialPawnGraph(geometry,1),
|
||
|
value: 1,
|
||
|
abbrev: '',
|
||
|
fenAbbrev: 'P',
|
||
|
initial: [{s:1,p:24},{s:1,p:25},{s:1,p:26},{s:1,p:27},{s:1,p:28},{s:1,p:29},{s:1,p:30},{s:1,p:31},{s:1,p:32},{s:1,p:33},{s:1,p:34},{s:1,p:35}],
|
||
|
epTarget: true,
|
||
|
epCatch: false,
|
||
|
},
|
||
|
|
||
|
2: {
|
||
|
name: 'pawn-b',
|
||
|
aspect: 'fr-pawn',
|
||
|
graph: this.cbPawnGraph(geometry,-1),
|
||
|
value: 1,
|
||
|
abbrev: '',
|
||
|
fenAbbrev: 'P',
|
||
|
epCatch: false,
|
||
|
|
||
|
},
|
||
|
|
||
|
3: {
|
||
|
name: 'ipawn-b',
|
||
|
aspect: 'fr-pawn',
|
||
|
graph: this.cbInitialPawnGraph(geometry,-1),
|
||
|
value: 1,
|
||
|
abbrev: '',
|
||
|
fenAbbrev: 'P',
|
||
|
initial: [{s:-1,p:108},{s:-1,p:109},{s:-1,p:110},{s:-1,p:111},{s:-1,p:112},{s:-1,p:113},{s:-1,p:114},{s:-1,p:115},{s:-1,p:116},{s:-1,p:117},{s:-1,p:118},{s:-1,p:119}],
|
||
|
epTarget: true,
|
||
|
epCatch: false,
|
||
|
},
|
||
|
|
||
|
4: {
|
||
|
name: 'knight',
|
||
|
aspect: 'fr-knight',
|
||
|
graph: this.cbKnightGraph(geometry),
|
||
|
value: 2.9,
|
||
|
abbrev: 'N',
|
||
|
initial: [{s:1,p:14},{s:1,p:21},{s:-1,p:122},{s:-1,p:129}],
|
||
|
},
|
||
|
|
||
|
5: {
|
||
|
name: 'bishop',
|
||
|
aspect: 'fr-bishop',
|
||
|
graph: this.cbBishopGraph(geometry),
|
||
|
value: 3.1,
|
||
|
abbrev: 'B',
|
||
|
initial: [{s:1,p:15},{s:1,p:20},{s:-1,p:123},{s:-1,p:128}],
|
||
|
},
|
||
|
|
||
|
6: {
|
||
|
name: 'rook',
|
||
|
aspect: 'fr-rook',
|
||
|
graph: this.cbRookGraph(geometry),
|
||
|
value: 5,
|
||
|
abbrev: 'R',
|
||
|
initial: [{s:1,p:13},{s:1,p:22},{s:-1,p:121},{s:-1,p:130}],
|
||
|
castle: true,
|
||
|
},
|
||
|
|
||
|
7: {
|
||
|
name: 'queen',
|
||
|
aspect: 'fr-queen',
|
||
|
graph: this.cbQueenGraph(geometry),
|
||
|
value: 9,
|
||
|
abbrev: 'Q',
|
||
|
initial: [{s:1,p:18},{s:-1,p:126}],
|
||
|
},
|
||
|
|
||
|
8: {
|
||
|
name: 'king',
|
||
|
aspect: 'fr-king',
|
||
|
isKing: true,
|
||
|
graph: this.cbKingGraph(geometry),
|
||
|
abbrev: 'K',
|
||
|
initial: [{s:1,p:17},{s:-1,p:125}],
|
||
|
},
|
||
|
|
||
|
9: {
|
||
|
name: 'cannon',
|
||
|
aspect: 'fr-cannon2',
|
||
|
graph: this.cbXQCannonGraph(geometry),
|
||
|
value: 3.5,
|
||
|
abbrev: 'C',
|
||
|
initial: [{s:1,p:0},{s:1,p:11},{s:-1,p:132},{s:-1,p:143}],
|
||
|
},
|
||
|
|
||
|
10: {
|
||
|
name: 'elephant',
|
||
|
aspect: 'fr-elephant',
|
||
|
graph: this.cbShortRangeGraph(geometry,[[-1,-1],[-1,1],[1,-1],[1,1],[-2,-2],[-2,2],[2,-2],[2,2]]),
|
||
|
value: 2.5,
|
||
|
abbrev: 'E',
|
||
|
initial: [{s:1,p:12},{s:1,p:23},{s:-1,p:120},{s:-1,p:131}],
|
||
|
},
|
||
|
|
||
|
11: {
|
||
|
name: 'prince-w',
|
||
|
aspect: 'fr-admiral',
|
||
|
graph: PrinceGraph(1),
|
||
|
value: 3,
|
||
|
epTarget: true,
|
||
|
abbrev: 'I',
|
||
|
initial: [{s:1,p:16},{s:1,p:19}],
|
||
|
},
|
||
|
|
||
|
12: {
|
||
|
name: 'prince-b',
|
||
|
aspect: 'fr-admiral',
|
||
|
graph: PrinceGraph(-1),
|
||
|
epTarget: true,
|
||
|
value: 3,
|
||
|
abbrev: 'I',
|
||
|
initial: [{s:-1,p:124},{s:-1,p:127}],
|
||
|
},
|
||
|
|
||
|
|
||
|
13: {
|
||
|
name: 'camel',
|
||
|
aspect: 'fr-camel',
|
||
|
graph: this.cbShortRangeGraph(geometry,[[-3,-1],[-3,1],[3,-1],[3,1],[1,3],[1,-3],[-1,3],[-1,-3]]),
|
||
|
value: 2,
|
||
|
abbrev: 'M',
|
||
|
initial: [{s:1,p:1},{s:1,p:10},{s:-1,p:133},{s:-1,p:142}],
|
||
|
},
|
||
|
|
||
|
14: {
|
||
|
name: 'lion',
|
||
|
aspect: 'fr-lion',
|
||
|
graph: this.cbShortRangeGraph(geometry,[
|
||
|
[-1,-1],[-1,1],[1,-1],[1,1],[1,0],[0,1],[-1,0],[0,-1],
|
||
|
[-2,0],[-2,-1],[-2,-2],[-1,-2],[0,-2],
|
||
|
[1,-2],[2,-2],[2,-1],[2,0],[2,1],
|
||
|
[2,2],[1,2],[0,2],[-1,2],[-2,2],[-2,1]]),
|
||
|
value: 7.5,
|
||
|
abbrev: 'L',
|
||
|
initial: [{s:1,p:5},{s:-1,p:137}],
|
||
|
},
|
||
|
15: {
|
||
|
name: 'eagle',
|
||
|
aspect: 'fr-eagle',
|
||
|
graph: EagleGraph(),
|
||
|
value: 8,
|
||
|
abbrev: 'A',
|
||
|
initial: [{s:1,p:6},{s:-1,p:138}],
|
||
|
},
|
||
|
16: {
|
||
|
name: 'unicorn',
|
||
|
aspect: 'fr-unicorn',
|
||
|
graph: this.cbMergeGraphs(geometry,
|
||
|
this.cbShortRangeGraph(geometry,[
|
||
|
[-2,-2],[-2,0],[-2,2],[0,2],[2,2],[2,0],[2,-2],[0,-2],
|
||
|
[-3,-3],[-3,0],[-3,3],[0,3],[3,3],[3,0],[3,-3],[0,-3]]),
|
||
|
this.cbKingGraph(geometry),
|
||
|
this.cbKnightGraph(geometry),
|
||
|
this.cbLongRangeGraph(geometry,[[2,-1],[2,1],[-2,-1],[-2,1],[-1,2],[-1,-2],[1,2],[1,-2]]),
|
||
|
this.cbShortRangeGraph(geometry,[[-3,-1],[-3,1],[3,-1],[3,1],[1,3],[1,-3],[-1,3],[-1,-3]])
|
||
|
),
|
||
|
value: 13,
|
||
|
abbrev: 'Pa',
|
||
|
initial: [{s:1,p:2},{s:-1,p:134}],
|
||
|
},
|
||
|
17: {
|
||
|
name: 'dragon',
|
||
|
aspect: 'fr-dragon',
|
||
|
graph: this.cbMergeGraphs(geometry,
|
||
|
this.cbQueenGraph(geometry),
|
||
|
EagleGraph()),
|
||
|
value: 14,
|
||
|
abbrev: 'D',
|
||
|
initial: [{s:1,p:4},{s:-1,p:136}],
|
||
|
},
|
||
|
18: {
|
||
|
name: 'lighthouse',
|
||
|
aspect: 'fr-lighthouse',
|
||
|
graph: this.cbMergeGraphs(geometry,
|
||
|
this.cbQueenGraph(geometry),
|
||
|
this.cbXQCannonGraph(geometry),
|
||
|
this.cbLongRangeGraph(geometry,[[1,-1],[-1,-1],[-1,1],[1,1]],null,this.cbConstants.FLAG_MOVE | this.cbConstants.FLAG_SCREEN_CAPTURE)),
|
||
|
value: 12,
|
||
|
abbrev: 'LH',
|
||
|
initial: [{s:1,p:3},{s:-1,p:135}],
|
||
|
},
|
||
|
19: {
|
||
|
name: 'emperor',
|
||
|
aspect: 'fr-crowned-rook',
|
||
|
graph: this.cbMergeGraphs(geometry,
|
||
|
this.cbQueenGraph(geometry),
|
||
|
this.cbXQCannonGraph(geometry),
|
||
|
this.cbLongRangeGraph(geometry,[[1,-1],[-1,-1],[-1,1],[1,1]],null,this.cbConstants.FLAG_MOVE | this.cbConstants.FLAG_SCREEN_CAPTURE),
|
||
|
EagleGraph(),
|
||
|
this.cbShortRangeGraph(geometry,[
|
||
|
[-2,-2],[-2,0],[-2,2],[0,2],[2,2],[2,0],[2,-2],[0,-2],
|
||
|
[-3,-3],[-3,0],[-3,3],[0,3],[3,3],[3,0],[3,-3],[0,-3]]),
|
||
|
this.cbKnightGraph(geometry),
|
||
|
this.cbLongRangeGraph(geometry,[[2,-1],[2,1],[-2,-1],[-2,1],[-1,2],[-1,-2],[1,2],[1,-2]]),
|
||
|
this.cbShortRangeGraph(geometry,[[-3,-1],[-3,1],[3,-1],[3,1],[1,3],[1,-3],[-1,3],[-1,-3]])),
|
||
|
value: 20,
|
||
|
abbrev: 'EM',
|
||
|
},
|
||
|
20: {
|
||
|
name: 'commander',
|
||
|
aspect: 'fr-amazon',
|
||
|
graph: this.cbMergeGraphs(geometry,
|
||
|
this.cbQueenGraph(geometry),
|
||
|
this.cbKnightGraph(geometry)),
|
||
|
value: 13,
|
||
|
abbrev: 'Co',
|
||
|
initial: [{s:1,p:7},{s:-1,p:139}],
|
||
|
},
|
||
|
|
||
|
21: {
|
||
|
name: 'cardinal',
|
||
|
aspect: 'fr-cardinal',
|
||
|
graph: this.cbMergeGraphs(geometry,
|
||
|
this.cbBishopGraph(geometry),
|
||
|
this.cbKnightGraph(geometry)),
|
||
|
value: 6,
|
||
|
abbrev: 'Ca',
|
||
|
initial: [{s:1,p:9},{s:-1,p:141}],
|
||
|
},
|
||
|
|
||
|
22: {
|
||
|
name: 'chancellor',
|
||
|
aspect: 'fr-marshall',
|
||
|
graph: this.cbMergeGraphs(geometry,
|
||
|
this.cbRookGraph(geometry),
|
||
|
this.cbKnightGraph(geometry)),
|
||
|
value: 9,
|
||
|
abbrev: 'Ch',
|
||
|
initial: [{s:1,p:8},{s:-1,p:140}],
|
||
|
castle: true,
|
||
|
},
|
||
|
},
|
||
|
|
||
|
promote: function(aGame,piece,move) {
|
||
|
if(piece.t==1 && geometry.R(move.t)==11)
|
||
|
return [14,15,20,16,17,18];
|
||
|
else if(piece.t==3 && geometry.R(move.t)==0)
|
||
|
return [14,15,20,16,17,18];
|
||
|
else if(piece.t==11 && geometry.R(move.t)==11)
|
||
|
return [19];
|
||
|
else if(piece.t==12 && geometry.R(move.t)==0)
|
||
|
return [19];
|
||
|
return [];
|
||
|
},
|
||
|
|
||
|
};
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Model.Board.GenerateMoves:
|
||
|
* - handle setup phase
|
||
|
* - handle king special move: a kind of castle involving only the king
|
||
|
*/
|
||
|
var kingLongMoves={
|
||
|
"1": {
|
||
|
17: [ [15,16],[19,18],[41,29],[39,28],[43,30],[3,4,16],[27,16,28],[40,28,29],[42,29,30],[31,18,30],[7,18,6] ],
|
||
|
5: [ [3,4],[7,8],[29,17],[27,16],[31,18],[15,4,6],[28,16,17],[30,17,18],[19,6,18] ],
|
||
|
},
|
||
|
"-1": {
|
||
|
125: [ [127,126],[123,124],[101,113],[99,112],[103,114],[135,124,136],[111,112,124],[100,112,113],[102,113,114],[115,114,126],[139,126,138] ],
|
||
|
137: [ [139,138],[135,136],[113,125],[115,126],[111,124],[127,126,138],[114,125,126],[112,124,125],[123,124,136] ],
|
||
|
},
|
||
|
}
|
||
|
var SuperModelBoardGenerateMoves=Model.Board.GenerateMoves;
|
||
|
Model.Board.GenerateMoves = function(aGame) {
|
||
|
// first moves (white and black) are managed specifically to setup K,Q,E,L initial position
|
||
|
if(this.setupState===undefined) {
|
||
|
this.mMoves=[{}];
|
||
|
return;
|
||
|
}
|
||
|
if(this.setupState=="setup") {
|
||
|
this.mMoves=[];
|
||
|
for(var i=0;i<12;i++)
|
||
|
this.mMoves.push({setup:i});
|
||
|
return;
|
||
|
}
|
||
|
SuperModelBoardGenerateMoves.apply(this,arguments); // call regular GenerateMoves method
|
||
|
// now consider special 2 cases king moves
|
||
|
var kPiece=this.pieces[this.board[this.kings[this.mWho]]];
|
||
|
if(!kPiece.m && !this.check) {
|
||
|
var lMoves=kingLongMoves[this.mWho][kPiece.p];
|
||
|
for(var i=0;i<lMoves.length;i++) {
|
||
|
var lMove=lMoves[i];
|
||
|
if(this.board[lMove[0]]>=0)
|
||
|
continue;
|
||
|
var canMove=true;
|
||
|
var oppInCheck=false;
|
||
|
for(var j=0;j<lMove.length;j++) {
|
||
|
var pos=lMove[j];
|
||
|
var tmpOut=this.board[pos];
|
||
|
this.board[pos]=-1; // remove possible piece to prevent problems when quick-applying/unapplying
|
||
|
var undo=this.cbQuickApply(aGame,{
|
||
|
f: kPiece.p,
|
||
|
t: pos,
|
||
|
});
|
||
|
var inCheck=this.cbGetAttackers(aGame,pos,this.mWho,true).length>0;
|
||
|
if(!inCheck && j==0)
|
||
|
oppInCheck=this.cbGetAttackers(aGame,this.kings[-this.mWho],-this.mWho,true).length>0;
|
||
|
this.cbQuickUnapply(aGame,undo);
|
||
|
this.board[pos]=tmpOut;
|
||
|
this.cbIntegrity(aGame);
|
||
|
if(inCheck) {
|
||
|
canMove=false;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if(canMove)
|
||
|
this.mMoves.push({
|
||
|
f: kPiece.p,
|
||
|
t: lMove[0],
|
||
|
c: null,
|
||
|
ck: oppInCheck,
|
||
|
a: 'K',
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Model.Board.CopyFrom overriding to copy setupState property
|
||
|
*/
|
||
|
var SuperModelBoardCopyFrom = Model.Board.CopyFrom;
|
||
|
Model.Board.CopyFrom = function(aBoard) {
|
||
|
SuperModelBoardCopyFrom.apply(this,arguments);
|
||
|
this.setupState = aBoard.setupState;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Model.Board.Evaluate overriding: in setup phase, no evaluation
|
||
|
*/
|
||
|
var SuperModelBoardEvaluate = Model.Board.Evaluate;
|
||
|
Model.Board.Evaluate = function(aGame) {
|
||
|
if(this.setupState===undefined || this.setupState=="setup")
|
||
|
return;
|
||
|
SuperModelBoardEvaluate.apply(this,arguments);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Model.Board.ApplyMove overriding: setup phase and king special move
|
||
|
*/
|
||
|
var SuperModelBoardApplyMove=Model.Board.ApplyMove;
|
||
|
Model.Board.ApplyMove = function(aGame,move) {
|
||
|
if(this.setupState===undefined)
|
||
|
this.setupState="setup";
|
||
|
else if(this.setupState=="setup") {
|
||
|
var $this=this, piece;
|
||
|
// at this point, KQLE have arbitrary positions. remember those piece indexes so we can move them
|
||
|
var starting={
|
||
|
"1": { K: 17, Q: 18, L: 5, E: 6 },
|
||
|
"-1": { K: 125, Q: 126, L: 137, E: 138 },
|
||
|
}
|
||
|
var indexes={ "1": {}, "-1": {} };
|
||
|
["1","-1"].forEach(function(side) {
|
||
|
for(var p in starting[side])
|
||
|
indexes[side][p]=$this.board[starting[side][p]];
|
||
|
});
|
||
|
// remove KQLE from the board
|
||
|
[5,6,17,18,125,126,137,138].forEach(function(pos) {
|
||
|
var pIndex=$this.board[pos];
|
||
|
$this.board[pos]=-1;
|
||
|
piece = $this.pieces[pIndex];
|
||
|
piece.p=-1;
|
||
|
$this.zSign=aGame.zobrist.update($this.zSign,"board",piece.t,pos);
|
||
|
});
|
||
|
// setup KQLE positions according to the setup
|
||
|
var setup=move.setup;
|
||
|
var remaining={};
|
||
|
if(setup/6<1) {
|
||
|
this.board[17]=indexes[1].K;
|
||
|
piece = this.pieces[indexes[1].K];
|
||
|
piece.p=17;
|
||
|
$this.zSign=aGame.zobrist.update($this.zSign,"board",piece.t,17);
|
||
|
this.kings[1]=17;
|
||
|
remaining[1]=[18,5,6];
|
||
|
this.board[125]=indexes[-1].K;
|
||
|
piece = this.pieces[indexes[-1].K];
|
||
|
piece.p=125;
|
||
|
$this.zSign=aGame.zobrist.update($this.zSign,"board",piece.t,125);
|
||
|
this.kings[-1]=125;
|
||
|
remaining[-1]=[126,137,138];
|
||
|
} else {
|
||
|
this.board[5]=indexes[1].K;
|
||
|
piece = this.pieces[indexes[1].K];
|
||
|
piece.p=5;
|
||
|
$this.zSign=aGame.zobrist.update($this.zSign,"board",piece.t,5);
|
||
|
this.kings[1]=5;
|
||
|
remaining[1]=[17,18,6];
|
||
|
this.board[137]=indexes[-1].K;
|
||
|
piece = this.pieces[indexes[-1].K];
|
||
|
piece.p=137;
|
||
|
$this.zSign=aGame.zobrist.update($this.zSign,"board",piece.t,137);
|
||
|
this.kings[-1]=137;
|
||
|
remaining[-1]=[125,126,138];
|
||
|
}
|
||
|
setup%=6;
|
||
|
var queen=Math.floor(setup/2);
|
||
|
this.board[remaining[1][queen]]=indexes[1].Q;
|
||
|
piece = this.pieces[indexes[1].Q];
|
||
|
piece.p=remaining[1][queen];
|
||
|
$this.zSign=aGame.zobrist.update($this.zSign,"board",piece.t,remaining[1][queen]);
|
||
|
remaining[1].splice(queen,1);
|
||
|
this.board[remaining[-1][queen]]=indexes[-1].Q;
|
||
|
piece = this.pieces[indexes[-1].Q];
|
||
|
piece.p=remaining[-1][queen];
|
||
|
$this.zSign=aGame.zobrist.update($this.zSign,"board",piece.t,remaining[-1][queen]);
|
||
|
remaining[-1].splice(queen,1);
|
||
|
var eagle,lion;
|
||
|
setup%=2;
|
||
|
if(setup==0) {
|
||
|
eagle=0;
|
||
|
lion=1;
|
||
|
} else {
|
||
|
eagle=1;
|
||
|
lion=0;
|
||
|
}
|
||
|
this.board[remaining[1][eagle]]=indexes[1].E;
|
||
|
piece = this.pieces[indexes[1].E];
|
||
|
piece.p=remaining[1][eagle];
|
||
|
$this.zSign=aGame.zobrist.update($this.zSign,"board",piece.t,remaining[1][eagle]);
|
||
|
this.board[remaining[1][lion]]=indexes[1].L;
|
||
|
piece = this.pieces[indexes[1].L];
|
||
|
piece.p=remaining[1][lion];
|
||
|
$this.zSign=aGame.zobrist.update($this.zSign,"board",piece.t,remaining[1][lion]);
|
||
|
|
||
|
this.board[remaining[-1][eagle]]=indexes[-1].E;
|
||
|
piece = this.pieces[indexes[-1].E];
|
||
|
piece.p=remaining[-1][eagle];
|
||
|
$this.zSign=aGame.zobrist.update($this.zSign,"board",piece.t,remaining[-1][eagle]);
|
||
|
this.board[remaining[-1][lion]]=indexes[-1].L;
|
||
|
piece = this.pieces[indexes[-1].L];
|
||
|
piece.p=remaining[-1][lion];
|
||
|
$this.zSign=aGame.zobrist.update($this.zSign,"board",piece.t,remaining[1][lion]);
|
||
|
|
||
|
this.setupState="done";
|
||
|
} else
|
||
|
SuperModelBoardApplyMove.apply(this,arguments);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Model.Move.ToString overriding for setup notation
|
||
|
*/
|
||
|
var SuperModelMoveToString = Model.Move.ToString;
|
||
|
Model.Move.ToString = function() {
|
||
|
if(this.f===undefined) {
|
||
|
if(this.setup===undefined)
|
||
|
return "--";
|
||
|
else
|
||
|
return "#"+this.setup;
|
||
|
}
|
||
|
return SuperModelMoveToString.apply(this,arguments);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Model.Board.CompactMoveString overriding to help reading PJN game transcripts
|
||
|
*/
|
||
|
var SuperModelBoardCompactMoveString = Model.Board.CompactMoveString;
|
||
|
Model.Board.CompactMoveString = function(aGame,aMove,allMoves) {
|
||
|
if(typeof aMove.ToString!="function") // ensure proper move object, if necessary
|
||
|
aMove=aGame.CreateMove(aMove);
|
||
|
if(this.setupState===undefined || this.setupState=="setup")
|
||
|
return aMove.ToString();
|
||
|
return SuperModelBoardCompactMoveString.apply(this,arguments);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Model.Board.StaticGenerateMoves overriding to prevent using AI during the setup phase
|
||
|
*/
|
||
|
Model.Board.StaticGenerateMoves = function(aGame) {
|
||
|
if(this.setupState=="setup")
|
||
|
return [aGame.CreateMove({setup:Math.floor(Math.random()*12)})];
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
})();
|