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 if (p1
== V
.KING
&& p2
== V
.ROOK
)
10 return []; //avoid duplicate moves (potential conflict with castle)
13 new PiPo({x:x2
,y:y2
,c:c
,p:p1
}),
14 new PiPo({x:x1
,y:y1
,c:c
,p:p2
})
17 new PiPo({x:x1
,y:y1
,c:c
,p:p1
}),
18 new PiPo({x:x2
,y:y2
,c:c
,p:p2
})
23 // Move completion: promote switched pawns (as in Magnetic)
24 const lastRank
= (c
== "w" ? 0 : V
.size
.x
-1);
26 if ((p1
==V
.PAWN
&& x2
==lastRank
) || (p2
==V
.PAWN
&& x1
==lastRank
))
28 const idx
= (p1
==V
.PAWN
? 0 : 1);
29 move.appear
[idx
].p
= V
.ROOK
;
31 for (let piece
of [V
.KNIGHT
, V
.BISHOP
, V
.QUEEN
])
33 let cmove
= JSON
.parse(JSON
.stringify(move));
34 cmove
.appear
[idx
].p
= piece
;
39 // Swap moves[i].appear[0] and [1] for moves presentation [TODO...]
41 let tmp
= m
.appear
[0];
42 m
.appear
[0] = m
.appear
[1];
52 getPotentialMovesFrom([x
,y
], computer
)
54 let moves
= super.getPotentialMovesFrom([x
,y
]);
55 // Add switches: respecting chessboard ordering if "computer" is on
56 const color
= this.turn
;
57 const piece
= this.getPiece(x
,y
);
58 const steps
= V
.steps
[V
.ROOK
].concat(V
.steps
[V
.BISHOP
]);
59 const kp
= this.kingPos
[color
];
60 const oppCol
= this.getOppCol(color
);
61 for (let step
of steps
)
63 let [i
,j
] = [x
+step
[0],y
+step
[1]];
64 if (!!computer
&& (i
<x
|| (i
==x
&& j
<y
)))
65 continue; //only switch with superior indices
66 if (V
.OnBoard(i
,j
) && this.board
[i
][j
]!=V
.EMPTY
67 && this.getColor(i
,j
)==color
&& this.getPiece(i
,j
)!=piece
68 // No switching under check (theoretically non-king pieces could, but not)
69 && !this.isAttacked(kp
, [oppCol
]))
71 let switchMove_s
= this.getSwitchMove_s([x
,y
],[i
,j
]);
72 if (switchMove_s
.length
== 1)
73 moves
.push(switchMove_s
[0]);
75 moves
= moves
.concat(switchMove_s
);
81 getAllValidMoves(computer
)
83 const color
= this.turn
;
84 const oppCol
= this.getOppCol(color
);
85 let potentialMoves
= [];
86 for (let i
=0; i
<V
.size
.x
; i
++)
88 for (let j
=0; j
<V
.size
.y
; j
++)
90 if (this.board
[i
][j
] != V
.EMPTY
&& this.getColor(i
,j
) == color
)
92 Array
.prototype.push
.apply(potentialMoves
,
93 this.getPotentialMovesFrom([i
,j
], computer
));
97 return this.filterValid(potentialMoves
);
100 updateVariables(move)
102 super.updateVariables(move);
103 if (move.appear
.length
== 2 && move.vanish
.length
== 2
104 && move.appear
[1].p
== V
.KING
)
106 // Switch with the king; not castle, and not handled by main class
107 const color
= move.vanish
[0].c
;
108 this.kingPos
[color
] = [move.appear
[1].x
, move.appear
[1].y
];
112 unupdateVariables(move)
114 super.unupdateVariables(move);
115 if (move.appear
.length
== 2 && move.vanish
.length
== 2
116 && move.appear
[1].p
== V
.KING
)
118 const color
= move.vanish
[0].c
;
119 this.kingPos
[color
] = [move.appear
[0].x
, move.appear
[0].y
];
123 static get SEARCH_DEPTH() { return 2; } //high branching factor
127 if (move.appear
.length
== 1)
128 return super.getNotation(move); //no switch
130 if (move.appear
[0].p
== V
.KING
&& move.appear
[1].p
== V
.ROOK
)
131 return (move.end
.y
< move.start
.y
? "0-0-0" : "0-0");
133 return "S" + V
.CoordsToSquare(move.start
) + V
.CoordsToSquare(move.end
);
137 const VariantRules
= SwitchingRules
;