5d838b46026b70411f12627a6e2d8e4a075ee4af
[vchess.git] / client / src / variants / Wormhole1.js
1 import { ChessRules } from "@/base_rules";
2 import { Wormhole2Rules } from "@/variants/Wormhole2";
3
4 export class Wormhole1Rules extends Wormhole2Rules {
5
6 static get PawnSpecs() {
7 return Object.assign(
8 {},
9 ChessRules.PawnSpecs,
10 { promotions: [V.LION, V.CHAMPION, V.WIZARD, V.KNIGHT] }
11 );
12 }
13
14 static get LION() {
15 return 'm';
16 }
17 static get WIZARD() {
18 return 'w';
19 }
20 static get CHAMPION() {
21 return 'c';
22 }
23
24 static get PIECES() {
25 return [V.PAWN, V.CHAMPION, V.KNIGHT, V.WIZARD, V.LION, V.KING];
26 }
27
28 getPpath(b) {
29 if (b[0] == 'x') return "Wormhole/hole";
30 if ([V.LION, V.CHAMPION, V.WIZARD].includes(b[1]))
31 return "Wormhole/" + b;
32 return b;
33 }
34
35 static get steps() {
36 return {
37 w: [
38 [ [-2, 0], [-1, -1] ],
39 [ [-2, 0], [-1, 1] ],
40 [ [0, -2], [-1, -1] ],
41 [ [0, 2], [-1, 1] ],
42 [ [0, -2], [1, -1] ],
43 [ [0, 2], [1, 1] ],
44 [ [2, 0], [1, -1] ],
45 [ [2, 0], [1, 1] ]
46 ],
47 d: [
48 [-2, 0],
49 [0, -2],
50 [2, 0],
51 [0, 2]
52 ],
53 a: [
54 [2, 2],
55 [2, -2],
56 [-2, 2],
57 [-2, -2]
58 ],
59 f: [
60 [-1, -1],
61 [-1, 1],
62 [1, -1],
63 [1, 1]
64 ],
65 z: [
66 [-1, 0],
67 [1, 0],
68 [0, -1],
69 [0, 1]
70 ],
71 n: Wormhole2Rules.steps[V.KNIGHT],
72 k: Wormhole2Rules.steps[V.KING]
73 };
74 }
75
76 static GenRandInitFen(options) {
77 if (options.randomness == 0)
78 return "cnwmkwnc/pppppppp/8/8/8/8/PPPPPPPP/CNWMKWNC w 0";
79
80 // Mapping new --> standard:
81 const piecesMap = {
82 'r': 'c',
83 'n': 'n',
84 'b': 'w',
85 'q': 'm',
86 'k': 'k'
87 };
88
89 const baseFen = ChessRules.GenRandInitFen(options);
90 return (
91 baseFen.substr(0, 8).split('').map(p => piecesMap[p]).join('') +
92 baseFen.substr(8, 27) +
93 baseFen.substr(35, 8).toLowerCase().split('')
94 .map(p => piecesMap[p]).join('').toUpperCase() +
95 " w 0"
96 );
97 }
98
99 getPotentialMovesFrom(sq) {
100 switch (this.getPiece(sq[0], sq[1])) {
101 case V.PAWN: return super.getPotentialPawnMoves(sq);
102 case V.CHAMPION: return this.getPotentialChampionMoves(sq);
103 case V.KNIGHT: return super.getPotentialKnightMoves(sq);
104 case V.WIZARD: return this.getPotentialWizardMoves(sq);
105 case V.LION: return this.getPotentialLionMoves(sq);
106 case V.KING: return super.getPotentialKingMoves(sq);
107 }
108 return [];
109 }
110
111 getJumpMoves([x, y], steps, onlyTake) {
112 let moves = [];
113 for (let step of steps) {
114 const sq = this.getSquareAfter([x,y], step);
115 if (sq &&
116 (
117 (!onlyTake && this.board[sq[0]][sq[1]] == V.EMPTY) ||
118 (this.board[sq[0]][sq[1]] != V.EMPTY && this.canTake([x, y], sq))
119 )
120 ) {
121 moves.push(this.getBasicMove([x, y], sq));
122 }
123 }
124 return moves;
125 }
126
127 getPotentialChampionMoves(sq) {
128 const steps = V.steps['d'].concat(V.steps['a']).concat(V.steps['z']);
129 return this.getJumpMoves(sq, steps);
130 }
131
132 getPotentialWizardMoves(sq) {
133 const steps = V.steps['w'].concat(V.steps['f']);
134 return this.getJumpMoves(sq, steps);
135 }
136
137 getPotentialLionMoves(sq) {
138 let steps = V.steps['d'].concat(V.steps['a']);
139 const moves1 = this.getJumpMoves(sq, steps);
140 steps = V.steps['f'].concat(V.steps['z']);
141 const moves2 = this.getJumpMoves(sq, steps, "onlyTake");
142 return moves1.concat(moves2);
143 }
144
145 isAttacked(sq, color) {
146 return (
147 super.isAttackedByPawn(sq, color) ||
148 this.isAttackedByChampion(sq, color) ||
149 super.isAttackedByKnight(sq, color) ||
150 this.isAttackedByWizard(sq, color) ||
151 this.isAttackedByLion(sq, color) ||
152 super.isAttackedByKing(sq, color)
153 );
154 }
155
156 isAttackedByWizard(sq, color) {
157 return (
158 this.isAttackedByJump(sq, color, V.WIZARD, V.steps['f']) ||
159 // NOTE: wizard attack is not symmetric in this variant:
160 // steps order need to be reversed.
161 this.isAttackedByJump(
162 sq,
163 color,
164 V.WIZARD,
165 V.steps['w'].map(s => s.reverse())
166 )
167 );
168 }
169
170 isAttackedByChampion(sq, color) {
171 const steps = V.steps['d'].concat(V.steps['a']).concat(V.steps['z']);
172 return this.isAttackedByJump(sq, color, V.CHAMPION, steps);
173 }
174
175 isAttackedByLion(sq, color) {
176 const steps = V.steps['d'].concat(V.steps['a'])
177 .concat(V.steps['f']).concat(V.steps['z']);
178 return this.isAttackedByJump(sq, color, V.LION, steps);
179 }
180
181 static get VALUES() {
182 return {
183 p: 1,
184 n: 3,
185 c: 8,
186 m: 9,
187 w: 3,
188 k: 1000
189 };
190 }
191
192 };