1 import { ChessRules
, Move
, PiPo
} from "@/base_rules";
3 export class SwitchingRules
extends ChessRules
{
5 // Build switch move between squares x1,y1 and x2,y2
6 getSwitchMove_s([x1
, y1
], [x2
, y2
]) {
7 const c
= this.getColor(x1
, y1
); //same as color at square 2
8 const p1
= this.getPiece(x1
, y1
);
9 const p2
= this.getPiece(x2
, y2
);
12 new PiPo({ x: x2
, y: y2
, c: c
, p: p1
}),
13 new PiPo({ x: x1
, y: y1
, c: c
, p: p2
})
16 new PiPo({ x: x1
, y: y1
, c: c
, p: p1
}),
17 new PiPo({ x: x2
, y: y2
, c: c
, p: p2
})
20 // Move completion: promote switched pawns (as in Magnetic)
21 const lastRank
= (c
== "w" ? 0 : V
.size
.x
- 1);
23 if ((p1
== V
.PAWN
&& x2
== lastRank
) || (p2
== V
.PAWN
&& x1
== lastRank
)) {
24 const idx
= (p1
== V
.PAWN
? 0 : 1);
25 move.appear
[idx
].p
= V
.ROOK
;
27 for (let piece
of [V
.KNIGHT
, V
.BISHOP
, V
.QUEEN
]) {
28 let cmove
= JSON
.parse(JSON
.stringify(move));
29 cmove
.appear
[idx
].p
= piece
;
33 // Swap moves[i].appear[0] and [1] for moves presentation [TODO...]
35 let tmp
= m
.appear
[0];
36 m
.appear
[0] = m
.appear
[1];
47 getPotentialMovesFrom([x
,y
]) {
48 let moves
= super.getPotentialMovesFrom([x
,y
]);
49 const piece
= this.getPiece(x
,y
);
50 const color
= this.turn
;
51 const oppCol
= V
.GetOppCol(color
);
52 const kp
= this.kingPos
[color
];
53 // Add switches (if not under check, from anything but the king)
54 if (piece
!= V
.KING
&& !this.isAttacked(kp
, oppCol
)) {
55 const steps
= V
.steps
[V
.ROOK
].concat(V
.steps
[V
.BISHOP
]);
56 for (let step
of steps
) {
57 const [i
, j
] = [x
+step
[0], y
+step
[1]];
60 this.board
[i
][j
] != V
.EMPTY
&&
61 this.getColor(i
,j
) == color
&&
62 this.getPiece(i
,j
) != piece
64 const switchMove_s
= this.getSwitchMove_s([x
,y
], [i
,j
]);
65 Array
.prototype.push
.apply(moves
, switchMove_s
);
73 // Did some king move?
74 move.appear
.forEach(a
=> {
76 this.kingPos
[a
.c
] = [a
.x
, a
.y
];
77 this.castleFlags
[a
.c
] = [V
.size
.y
, V
.size
.y
];
80 const firstRank
= (move.vanish
[0].c
== 'w' ? 7 : 0);
81 for (let coords
of [move.start
, move.end
]) {
83 Object
.keys(firstRank
).includes(coords
.x
) &&
84 this.castleFlags
[firstRank
[coords
.x
]].includes(coords
.y
)
86 const c
= firstRank
[coords
.x
];
87 const flagIdx
= (coords
.y
== this.castleFlags
[c
][0] ? 0 : 1);
88 this.castleFlags
[c
][flagIdx
] = V
.size
.y
;
94 // Did some king move?
95 move.vanish
.forEach(v
=> {
96 if (v
.p
== V
.KING
) this.kingPos
[v
.c
] = [v
.x
, v
.y
];
100 static get SEARCH_DEPTH() {
101 // Branching factor is quite high
105 getAllPotentialMoves() {
106 // Since this function is used only for computer play,
107 // remove duplicate switches:
108 return super.getAllPotentialMoves().filter(m
=> {
110 m
.appear
.length
== 1 ||
111 (m
.appear
[0].p
== V
.KING
&& m
.appear
[1].p
== V
.ROOK
) ||
112 (m
.appear
[1].x
<= m
.vanish
[1].x
&& m
.appear
[1].y
<= m
.vanish
[1].y
)
118 if (move.appear
.length
== 1)
120 return super.getNotation(move);
121 if (move.appear
[0].p
== V
.KING
&& move.appear
[1].p
== V
.ROOK
)
123 return (move.end
.y
< move.start
.y
? "0-0-0" : "0-0");
125 return "S" + V
.CoordsToSquare(move.start
) + V
.CoordsToSquare(move.end
);