1 class SwitchingRules
extends ChessRules
3 // Build switch move between squares x1,y1 and x2,y2
4 getSwitchMove_s([x1
,y1
],[x2
,y2
])
6 const c
= this.getColor(x1
,y1
); //same as color at square 2
7 const p1
= this.getPiece(x1
,y1
);
8 const p2
= this.getPiece(x2
,y2
);
9 const V
= VariantRules
;
10 if (p1
== V
.KING
&& p2
== V
.ROOK
)
11 return []; //avoid duplicate moves (potential conflict with castle)
14 new PiPo({x:x2
,y:y2
,c:c
,p:p1
}),
15 new PiPo({x:x1
,y:y1
,c:c
,p:p2
})
18 new PiPo({x:x1
,y:y1
,c:c
,p:p1
}),
19 new PiPo({x:x2
,y:y2
,c:c
,p:p2
})
24 // Move completion: promote switched pawns (as in Magnetic)
25 const sizeX
= VariantRules
.size
[0];
26 const lastRank
= (c
== "w" ? 0 : sizeX
-1);
28 if ((p1
==V
.PAWN
&& x2
==lastRank
) || (p2
==V
.PAWN
&& x1
==lastRank
))
30 const idx
= (p1
==V
.PAWN
? 0 : 1);
31 move.appear
[idx
].p
= V
.ROOK
;
33 for (let piece
of [V
.KNIGHT
, V
.BISHOP
, V
.QUEEN
])
35 let cmove
= JSON
.parse(JSON
.stringify(move));
36 cmove
.appear
[idx
].p
= piece
;
41 // Swap moves[i].appear[0] and [1] for moves presentation [TODO...]
43 let tmp
= m
.appear
[0];
44 m
.appear
[0] = m
.appear
[1];
54 getPotentialMovesFrom([x
,y
], computer
)
56 let moves
= super.getPotentialMovesFrom([x
,y
]);
57 // Add switches: respecting chessboard ordering if "computer" is on
58 const V
= VariantRules
;
59 const color
= this.turn
;
60 const piece
= this.getPiece(x
,y
);
61 const [sizeX
,sizeY
] = V
.size
;
62 const steps
= V
.steps
[V
.ROOK
].concat(V
.steps
[V
.BISHOP
]);
63 const kp
= this.kingPos
[color
];
64 const oppCol
= this.getOppCol(color
);
65 for (let step
of steps
)
67 let [i
,j
] = [x
+step
[0],y
+step
[1]];
68 if (!!computer
&& (i
<x
|| (i
==x
&& j
<y
)))
69 continue; //only switch with superior indices
70 if (i
>=0 && i
<sizeX
&& j
>=0 && j
<sizeY
&& this.board
[i
][j
]!=V
.EMPTY
71 && this.getColor(i
,j
)==color
&& this.getPiece(i
,j
)!=piece
72 // No switching under check (theoretically non-king pieces could, but not)
73 && !this.isAttacked(kp
, [oppCol
]))
75 let switchMove_s
= this.getSwitchMove_s([x
,y
],[i
,j
]);
76 if (switchMove_s
.length
== 1)
77 moves
.push(switchMove_s
[0]);
79 moves
= moves
.concat(switchMove_s
);
85 getAllValidMoves(computer
)
87 const color
= this.turn
;
88 const oppCol
= this.getOppCol(color
);
89 let potentialMoves
= [];
90 const [sizeX
,sizeY
] = VariantRules
.size
;
91 for (let i
=0; i
<sizeX
; i
++)
93 for (let j
=0; j
<sizeY
; j
++)
95 if (this.board
[i
][j
] != VariantRules
.EMPTY
&& this.getColor(i
,j
) == color
)
97 Array
.prototype.push
.apply(potentialMoves
,
98 this.getPotentialMovesFrom([i
,j
], computer
));
102 return this.filterValid(potentialMoves
);
105 updateVariables(move)
107 super.updateVariables(move);
108 if (move.appear
.length
== 2 && move.vanish
.length
== 2
109 && move.appear
[1].p
== VariantRules
.KING
)
111 // Switch with the king; not castle, and not handled by main class
112 const color
= this.getColor(move.start
.x
, move.start
.y
);
113 this.kingPos
[color
] = [move.appear
[1].x
, move.appear
[1].y
];
117 unupdateVariables(move)
119 super.unupdateVariables(move);
120 if (move.appear
.length
== 2 && move.vanish
.length
== 2
121 && move.appear
[1].p
== VariantRules
.KING
)
123 const color
= this.getColor(move.start
.x
, move.start
.y
);
124 this.kingPos
[color
] = [move.appear
[0].x
, move.appear
[0].y
];
128 static get SEARCH_DEPTH() { return 2; } //high branching factor
132 if (move.appear
.length
== 1)
133 return super.getNotation(move); //no switch
135 if (move.appear
[0].p
== VariantRules
.KING
&& move.appear
[1].p
== VariantRules
.ROOK
)
136 return (move.end
.y
< move.start
.y
? "0-0-0" : "0-0");
139 String
.fromCharCode(97 + move.start
.y
) + (VariantRules
.size
[0]-move.start
.x
);
141 String
.fromCharCode(97 + move.end
.y
) + (VariantRules
.size
[0]-move.end
.x
);
142 return "S" + startSquare
+ finalSquare
;