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