5 return undefined; //no en-passant
8 // Complete a move with magnetic actions
9 applyMagneticLaws([x
,y
], move)
14 getBasicMove([sx
,sy
], [ex
,ey
], tr
)
21 c: !!tr
? tr
.c : this.getColor(sx
,sy
),
22 p: !!tr
? tr
.p : this.getPiece(sx
,sy
)
29 c: this.getColor(sx
,sy
),
30 p: this.getPiece(sx
,sy
)
35 if (this.board
[ex
][ey
] != VariantRules
.EMPTY
)
41 c: this.getColor(ex
,ey
),
42 p: this.getPiece(ex
,ey
)
46 this.applyMagneticLaws([ex
,ey
], mv
);
52 const c
= this.getColor(x
,y
);
53 if (x
!= (c
=="w" ? 7 : 0) || y
!= this.INIT_COL_KING
[c
])
54 return []; //x isn't first rank, or king has moved (shortcut)
56 const V
= VariantRules
;
59 const oppCol
= this.getOppCol(c
);
62 const finalSquares
= [ [2,3], [6,5] ]; //king, then rook
64 for (let castleSide
=0; castleSide
< 2; castleSide
++) //large, then small
66 if (!this.flags
[c
][castleSide
])
68 // If this code is reached, rooks and king are on initial position
70 // Nothing on the path of the king (and no checks; OK also if y==finalSquare)?
71 let step
= finalSquares
[castleSide
][0] < y
? -1 : 1;
72 for (i
=y
; i
!=finalSquares
[castleSide
][0]; i
+=step
)
74 if (this.isAttacked([x
,i
], oppCol
) || (this.board
[x
][i
] != V
.EMPTY
&&
75 // NOTE: next check is enough, because of chessboard constraints
76 (this.getColor(x
,i
) != c
|| ![V
.KING
,V
.ROOK
].includes(this.getPiece(x
,i
)))))
78 continue castlingCheck
;
82 // Nothing on the path to the rook?
83 step
= castleSide
== 0 ? -1 : 1;
84 for (i
= y
+ step
; i
!= this.INIT_COL_ROOK
[c
][castleSide
]; i
+= step
)
86 if (this.board
[x
][i
] != V
.EMPTY
)
87 continue castlingCheck
;
89 const rookPos
= this.INIT_COL_ROOK
[c
][castleSide
];
91 // Nothing on final squares, except maybe king and castling rook?
94 if (this.board
[x
][finalSquares
[castleSide
][i
]] != V
.EMPTY
&&
95 this.getPiece(x
,finalSquares
[castleSide
][i
]) != V
.KING
&&
96 finalSquares
[castleSide
][i
] != rookPos
)
98 continue castlingCheck
;
102 // If this code is reached, castle is valid
103 let cmove
= new Move({
105 new PiPo({x:x
,y:finalSquares
[castleSide
][0],p:V
.KING
,c:c
}),
106 new PiPo({x:x
,y:finalSquares
[castleSide
][1],p:V
.ROOK
,c:c
})],
108 new PiPo({x:x
,y:y
,p:V
.KING
,c:c
}),
109 new PiPo({x:x
,y:rookPos
,p:V
.ROOK
,c:c
})],
110 end: Math
.abs(y
- rookPos
) <= 2
112 : {x:x
, y:y
+ 2 * (castleSide
==0 ? -1 : 1)}
114 this.applyMagneticLaws([x
,finalSquares
[castleSide
][1]], cmove
);
121 // TODO: verify this assertion
124 // return true; //always at least one possible move
129 return false; //there is no check
132 getCheckSquares(move)
134 const c
= this.getOppCol(this.turn
); //opponent
135 const saveKingPos
= this.kingPos
[c
]; //king might be taken
137 // The only way to be "under check" is to have lost the king (thus game over)
138 let res
= this.kingPos
[c
][0] < 0;
139 ? [ JSON
.parse(JSON
.stringify(saveKingPos
)) ]
145 updateVariables(move)
147 super.updateVariables(move);
148 const c
= this.getColor(move.start
.x
,move.start
.y
);
149 if (c
!= this.getColor(move.end
.x
,move.end
.y
)
150 && this.board
[move.end
.x
][move.end
.y
] != VariantRules
.EMPTY
151 && this.getPiece(move.end
.x
,move.end
.y
) == VariantRules
.KING
)
153 // We took opponent king !
154 const oppCol
= this.getOppCol(c
);
155 this.kingPos
[oppCol
] = [-1,-1];
156 this.flags
[oppCol
] = [false,false];
160 unupdateVariables(move)
162 super.unupdateVariables(move);
163 const c
= this.getColor(move.start
.x
,move.start
.y
);
164 const oppCol
= this.getOppCol(c
);
165 if (this.kingPos
[oppCol
][0] < 0)
167 // Last move took opponent's king
168 for (let psq
of move.vanish
)
172 this.kingPos
[oppCol
] = [psq
.x
, psq
.y
];
181 if (this.checkRepetition())
184 const color
= this.turn
;
185 // TODO: do we need "atLeastOneMove()"?
186 if (this.atLeastOneMove() && this.kingPos
[color
][0] >= 0)
189 return this.checkGameEnd();
194 // No valid move: our king disappeared
195 return this.turn
== "w" ? "0-1" : "1-0";