Add temporary patch for preset challenges
[vchess.git] / client / src / variants / Knightrelay2.js
1 import { ChessRules } from "@/base_rules";
2
3 export class Knightrelay2Rules extends ChessRules {
4
5 getPotentialMovesFrom([x, y]) {
6 let moves = super.getPotentialMovesFrom([x, y]);
7
8 // Expand possible moves if guarded by a knight:
9 const piece = this.getPiece(x,y);
10 if (piece != V.KNIGHT) {
11 const color = this.turn;
12 let guardedByKnight = false;
13 for (const step of V.steps[V.KNIGHT]) {
14 if (
15 V.OnBoard(x+step[0],y+step[1]) &&
16 this.getPiece(x+step[0],y+step[1]) == V.KNIGHT &&
17 this.getColor(x+step[0],y+step[1]) == color
18 ) {
19 guardedByKnight = true;
20 break;
21 }
22 }
23 if (guardedByKnight) {
24 const lastRank = color == "w" ? 0 : V.size.x - 1;
25 for (const step of V.steps[V.KNIGHT]) {
26 if (
27 V.OnBoard(x+step[0],y+step[1]) &&
28 this.getColor(x+step[0],y+step[1]) != color
29 ) {
30 // Potential promotions:
31 const finalPieces = piece == V.PAWN && x + step[0] == lastRank
32 ? [V.ROOK, V.KNIGHT, V.BISHOP, V.QUEEN]
33 : [piece];
34 for (let p of finalPieces) {
35 moves.push(
36 this.getBasicMove([x,y], [x+step[0],y+step[1]], {
37 c: color,
38 p: p
39 })
40 );
41 }
42 }
43 }
44 }
45 }
46
47 return moves;
48 }
49
50 isAttacked(sq, color) {
51 if (super.isAttacked(sq, color)) return true;
52
53 // Check if a (non-knight) piece at knight distance
54 // is guarded by a knight (and thus attacking)
55 const x = sq[0],
56 y = sq[1];
57 for (const step of V.steps[V.KNIGHT]) {
58 if (
59 V.OnBoard(x+step[0],y+step[1]) &&
60 this.getColor(x+step[0],y+step[1]) == color &&
61 this.getPiece(x+step[0],y+step[1]) != V.KNIGHT
62 ) {
63 for (const step2 of V.steps[V.KNIGHT]) {
64 const xx = x+step[0]+step2[0],
65 yy = y+step[1]+step2[1];
66 if (
67 V.OnBoard(xx,yy) &&
68 this.getColor(xx,yy) == color &&
69 this.getPiece(xx,yy) == V.KNIGHT
70 ) {
71 return true;
72 }
73 }
74 }
75 }
76
77 return false;
78 }
79
80 static get VALUES() {
81 return {
82 p: 1,
83 r: 5,
84 n: 7, //the knight is valuable
85 b: 3,
86 q: 9,
87 k: 1000
88 };
89 }
90
91 static get SEARCH_DEPTH() {
92 return 2;
93 }
94
95 getNotation(move) {
96 if (move.appear.length == 2 && move.appear[0].p == V.KING)
97 // Castle
98 return move.end.y < move.start.y ? "0-0-0" : "0-0";
99
100 // Translate final and initial square
101 const initSquare = V.CoordsToSquare(move.start);
102 const finalSquare = V.CoordsToSquare(move.end);
103 const piece = this.getPiece(move.start.x, move.start.y);
104
105 // Since pieces and pawns could move like knight,
106 // indicate start and end squares
107 let notation =
108 piece.toUpperCase() +
109 initSquare +
110 (move.vanish.length > move.appear.length ? "x" : "") +
111 finalSquare
112
113 if (
114 piece == V.PAWN &&
115 move.appear.length > 0 &&
116 move.appear[0].p != V.PAWN
117 ) {
118 // Promotion
119 notation += "=" + move.appear[0].p.toUpperCase();
120 }
121
122 return notation;
123 }
124
125 };