Commit | Line | Data |
---|---|---|
ecb8f91b BA |
1 | import { ChessRules } from "@/base_rules"; |
2 | ||
da9e846e | 3 | // Pawns relayed by one square at a time (but with relaying piece movements) |
ecb8f91b BA |
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]); | |
da9e846e BA |
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)) | |
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 | } | |
ecb8f91b | 60 | |
da9e846e | 61 | filterValid(moves) { |
ecb8f91b BA |
62 | return moves; |
63 | } | |
da9e846e BA |
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 | } | |
ecb8f91b BA |
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 | }; |