jocly/src/games/chessbase/glinski-model.js
ecobabush 8727c790f3 Bugfixes_Added pawn promotion at d9 and g10.
Debugged pawn promotion at d9, g8, g10.
2017-08-26 20:43:17 +03:00

233 lines
6.4 KiB
JavaScript

(function() {
var posNames = {
2:'a1',13:'b1',23:'c1',34:'d1',44:'e1',55:'f1',66:'g1',78:'h1',89:'i1',101:'k1',112:'l1',
3:'a2',14:'b2',24:'c2',35:'d2',45:'e2',56:'f2',67:'g2',79:'h2',90:'i2',102:'k2',113:'l2',
4:'a3',15:'b3',25:'c3',36:'d3',46:'e3',57:'f3',68:'g3',80:'h3',91:'i3',103:'k3',114:'l3',
5:'a4',16:'b4',26:'c4',37:'d4',47:'e4',58:'f4',69:'g4',81:'h4',92:'i4',104:'k4',115:'l4',
6:'a5',17:'b5',27:'c5',38:'d5',48:'e5',59:'f5',70:'g5',82:'h5',93:'i5',105:'k5',116:'l5',
7:'a6',18:'b6',28:'c6',39:'d6',49:'e6',60:'f6',71:'g6',83:'h6',94:'i6',106:'k6',117:'l6',
19:'b7',29:'c7',40:'d7',50:'e7',61:'f7',72:'g7',84:'h7',95:'i7',107:'k7',
30:'c8',41:'d8',51:'e8',62:'f8',73:'g8',85:'h8',96:'i8',
42:'d9',52:'e9',63:'f9',74:'g9',86:'h9',
53:'e10',64:'f10',75:'g10',
65:'f11',
};
var geometry = Model.Game.cbBoardGeometryHex([
' # + . # + . ',
' + . # + . # + ',
' . # + . # + . # ',
' # + . # + . # + . ',
' + . # + . # + . # + ',
'. # + . # + . # + . # ',
' + . # + . # + . # + ',
' # + . # + . # + . ',
' . # + . # + . # ',
' + . # + . # + ',
' # + . # + . '
],posNames);
var pawnPoss = {
"1": {13:1,24:1,36:1,47:1,59:1,69:1,80:1,90:1,101:1},
"-1": {19:1,29:1,40:1,50:1,61:1,72:1,84:1,95:1,107:1},
}
var promo = {
"1": { 7:1, 19:1, 30:1, 42:1, 53:1, 65:1, 75:1, 86:1, 96:1, 107:1, 117:1 },
"-1": { 2:1, 13:1, 23:1, 34:1, 44:1, 55:1, 66:1, 78:1, 89:1, 101:1, 112:1 },
}
// for each side and position, calculate distance to promotion line
var distPromo={ "1": {}, "-1": {} };
var distance = geometry.GetDistances();
["1","-1"].forEach(function(side) {
for(var pos in geometry.confine) {
var minDist=Infinity;
for(var pos1 in promo[side]) {
var dist=distance[pos][pos1];
if(dist<minDist) {
distPromo[side][pos]=dist;
minDist=dist;
}
}
}
});
Model.Game.cbDefine = function() {
return {
geometry: geometry,
pieceTypes: {
0: {
name: 'pawn-w',
aspect: 'pawn',
graph: this.cbGLPawnGraph(geometry,1,1),
value: 1,
abbrev: '',
fenAbbrev: 'P',
epCatch: true,
},
1: {
name: 'ipawn-w',
aspect: 'pawn',
graph: this.cbGLPawnGraph(geometry,1,2),
value: 1,
abbrev: '',
fenAbbrev: 'P',
initial: [{s:1,p:13},{s:1,p:24},{s:1,p:36},{s:1,p:47},{s:1,p:59},{s:1,p:69},{s:1,p:80},{s:1,p:90},{s:1,p:101}],
epTarget: true,
},
2: {
name: 'pawn-b',
aspect: 'pawn',
graph: this.cbGLPawnGraph(geometry,-1,1),
value: 1,
abbrev: '',
fenAbbrev: 'P',
epCatch: true,
},
3: {
name: 'ipawn-b',
aspect: 'pawn',
graph: this.cbGLPawnGraph(geometry,-1,2),
value: 1,
abbrev: '',
fenAbbrev: 'P',
initial: [{s:-1,p:19},{s:-1,p:29},{s:-1,p:40},{s:-1,p:50},{s:-1,p:61},{s:-1,p:72},{s:-1,p:84},{s:-1,p:95},{s:-1,p:107}],
epTarget: true,
},
4: {
name: 'knight',
graph: this.cbGLKnightGraph(geometry),
value: 2.9,
abbrev: 'N',
initial: [{s:1,p:34},{s:1,p:78},{s:-1,p:42},{s:-1,p:86}],
},
5: {
name: 'bishop',
graph: this.cbGLBishopGraph(geometry),
value: 3.1,
abbrev: 'B',
initial: [{s:1,p:55},{s:1,p:56},{s:1,p:57},{s:-1,p:65},{s:-1,p:64},{s:-1,p:63}],
},
6: {
name: 'rook',
graph: this.cbGLRookGraph(geometry),
value: 5,
abbrev: 'R',
initial: [{s:1,p:23},{s:1,p:89},{s:-1,p:30},{s:-1,p:96}],
castle: true,
},
7: {
name: 'queen',
graph: this.cbGLQueenGraph(geometry),
value: 9,
abbrev: 'Q',
initial: [{s:1,p:44},{s:-1,p:53}],
},
8: {
name: 'king',
isKing: true,
graph: this.cbGLKingGraph(geometry),
abbrev: 'K',
initial: [{s:1,p:66},{s:-1,p:75}],
},
},
promote: function(aGame,piece,move) {
if(piece.t==1 && !(move.t in pawnPoss[1]))
return [0];
else if(piece.t==3 && !(move.t in pawnPoss[-1]))
return [2];
else if(piece.t==0 && (move.t in promo[1]))
return [4,5,6,7];
else if(piece.t==2 && (move.t in promo[-1]))
return [4,5,6,7];
return [];
},
evaluate: function(aGame,evalValues,material) {
// check lack of material to checkmate
var white=material[1].count;
var black=material[-1].count;
if(!white[0] && !white[1] && !white[4] && !white[5] && !white[6] && !white[7]) { // white king single
if(!black[2] && !black[3] && !black[6] && !black[7] && (black[4]+black[5]<2 || black[5]<2)) {
this.mFinished=true;
this.mWinner=JocGame.DRAW;
}
}
if(!black[2] && !black[3] && !black[4] && !black[5] && !black[6] && !black[7]) { // black king single
if(!white[0] && !white[1] && !white[6] && !white[7] && (white[4]+white[5]<2 || white[5]<2)) {
this.mFinished=true;
this.mWinner=JocGame.DRAW;
}
}
// check 50 moves without capture
if(this.noCaptCount>=100) {
this.mFinished=true;
this.mWinner=JocGame.DRAW;
}
// motivate pawns to reach the promotion line
var distPromo0=aGame.cbUseTypedArrays?new Int8Array(3):[0,0,0];
var pawns=material[1].byType[0],pawnsLength;
if(pawns) {
pawnsLength=pawns.length;
for(var i=0;i<pawnsLength;i++) {
var dProm=distPromo[1][pawns[i].p];
if(dProm>0 && dProm<4)
distPromo0[dProm-1]++;
}
}
pawns=material[-1].byType[2],pawnsLength;
if(pawns) {
pawnsLength=pawns.length;
for(var i=0;i<pawnsLength;i++) {
var dProm=distPromo[-1][pawns[i].p];
if(dProm>0 && dProm<4)
distPromo0[dProm-1]--;
}
}
if(distPromo0[0]!=0)
evalValues['distPawnPromo1']=distPromo0[0];
if(distPromo0[1]!=0)
evalValues['distPawnPromo2']=distPromo0[1];
if(distPromo0[2]!=0)
evalValues['distPawnPromo3']=distPromo0[2];
// motivate knights and bishops to deploy early
var minorPiecesMoved=0;
for(var t=4;t<=5;t++)
for(var s=1;s>=-1;s-=2) {
var pieces=material[s].byType[t];
if(pieces)
for(var i=0;i<pieces.length;i++)
if(pieces[i].m)
minorPiecesMoved+=s;
}
if(minorPiecesMoved!=0) {
evalValues['minorPiecesMoved']=minorPiecesMoved;
}
},
};
}
})();