'update'
[vchess.git] / client / src / variants / Relayup.js
1 import { ChessRules } from "@/base_rules";
2
3 // Pawns relayed by one square at a time (but with relaying piece movements)
4 // diff from https://www.chessvariants.com/rules/relay-chess ==> new name
5 export class RelayupRules extends ChessRules {
6
7 static get PawnSpecs() {
8 return Object.assign(
9 {},
10 ChessRules.PawnSpecs,
11 { twoSquares: false }
12 );
13 }
14
15 static get HasFlags() {
16 return false;
17 }
18
19 static get HasEnpassant() {
20 return false;
21 }
22
23 getPotentialMovesFrom([x, y]) {
24 let moves = super.getPotentialMovesFrom([x, y]);
25 // Expand potential moves if guarded by friendly pieces.
26 // NOTE: pawns cannot be promoted through a relaying move
27 const piece = this.getPiece(x,y);
28 const color = this.turn;
29 const lastRank = (color == 'w' ? 0 : 7);
30 const sq = [x, y];
31 const oneStep = (piece == V.PAWN);
32 let guardedBy = {};
33 if (piece != V.ROOK && super.isAttackedByRook(sq, color))
34 guardedBy[V.ROOK] = true;
35 if (piece != V.KNIGHT && super.isAttackedByKnight(sq, color))
36 guardedBy[V.KNIGHT] = true;
37 if (piece != V.BISHOP && super.isAttackedByBishop(sq, color))
38 guardedBy[V.BISHOP] = true;
39 if (piece != V.QUEEN && super.isAttackedByQueen(sq, color))
40 guardedBy[V.QUEEN] = true;
41 if (piece != V.KING && super.isAttackedByKing(sq, color))
42 guardedBy[V.KING] = true;
43 Object.keys(guardedBy).forEach(pg => {
44 let steps = null;
45 if ([V.ROOK, V.KNIGHT, V.BISHOP].includes(pg)) steps = V.steps[pg];
46 else steps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]);
47 const extraMoves =
48 super.getSlideNJumpMoves(
49 sq, steps, (oneStep || [V.KNIGHT, V.KING].includes(pg) ? 1 : null))
50 .filter(m => {
51 return (
52 (piece != V.PAWN || m.end.x != lastRank) &&
53 (moves.every(mv => mv.end.x != m.end.x || mv.end.y != m.end.y))
54 );
55 });
56 moves = moves.concat(extraMoves);
57 });
58 return moves;
59 }
60
61 filterValid(moves) {
62 return moves;
63 }
64 getCheckSquares() {
65 return [];
66 }
67
68 postPlay(move) {
69 super.postPlay(move);
70 if (move.vanish.length == 2 && move.vanish[1].p == V.KING)
71 this.kingPos[move.vanish[1].c] = [-1, -1];
72 }
73
74 postUndo(move) {
75 super.postUndo(move);
76 if (move.vanish.length == 2 && move.vanish[1].p == V.KING) {
77 const v = move.vanish[1];
78 this.kingPos[v.c] = [v.x, v.y];
79 }
80 }
81
82 getCurrentScore() {
83 const c = this.turn;
84 if (this.kingPos[c][0] < 0) return (c == 'w' ? "0-1" : "1-0");
85 // It seems that there is always a possible move (TODO: check this)
86 return "*";
87 }
88
89 getNotation(move) {
90 // Translate final and initial square
91 const initSquare = V.CoordsToSquare(move.start);
92 const finalSquare = V.CoordsToSquare(move.end);
93 const piece = this.getPiece(move.start.x, move.start.y);
94
95 // Since pieces and pawns could move like knight,
96 // indicate start and end squares
97 let notation =
98 piece.toUpperCase() +
99 initSquare +
100 (move.vanish.length > move.appear.length ? "x" : "") +
101 finalSquare
102
103 if (
104 piece == V.PAWN &&
105 move.appear.length > 0 &&
106 move.appear[0].p != V.PAWN
107 ) {
108 // Promotion
109 notation += "=" + move.appear[0].p.toUpperCase();
110 }
111
112 return notation;
113 }
114
115 };