Several small improvements + integrate options + first working draft of Cwda
[vchess.git] / client / src / variants / Joker.js
1 import { ChessRules, Move, PiPo } from "@/base_rules";
2 import { Antiking2Rules } from "@/variants/Antiking2";
3
4 export class JokerRules extends ChessRules {
5
6 static get PawnSpecs() {
7 return Object.assign(
8 {},
9 ChessRules.PawnSpecs,
10 { promotions: ChessRules.PawnSpecs.promotions.concat([V.JOKER]) }
11 );
12 }
13
14 static GenRandInitFen(options) {
15 const antikingFen = Antiking2Rules.GenRandInitFen(options);
16 return antikingFen.replace('a', 'J').replace('A', 'j');
17 }
18
19 static get JOKER() {
20 return 'j';
21 }
22
23 static get PIECES() {
24 return ChessRules.PIECES.concat([V.JOKER]);
25 }
26
27 getPpath(b) {
28 return (b.charAt(1) == 'j' ? "Joker/" : "") + b;
29 }
30
31 getPotentialMovesFrom([x, y]) {
32 const piece = this.getPiece(x, y);
33 if (piece == V.JOKER) return this.getPotentialJokerMoves([x, y]);
34 let moves = super.getPotentialMovesFrom([x, y]);
35 if (piece == V.PAWN) {
36 const c = this.turn;
37 const alreadyOneJoker = this.board.some(row =>
38 row.some(cell => cell == c + 'j'));
39 if (alreadyOneJoker) moves = moves.filter(m => m.appear[0].p != V.JOKER)
40 }
41 return moves;
42 }
43
44 canTake([x1, y1], [x2, y2]) {
45 if (this.getPiece(x1, y1) == V.JOKER) return false;
46 return super.canTake([x1, y1], [x2, y2]);
47 }
48
49 getPotentialJokerMoves([x, y]) {
50 const moving =
51 super.getSlideNJumpMoves([x, y], V.steps[V.KNIGHT], 1)
52 .concat(super.getSlideNJumpMoves([x, y],
53 V.steps[V.ROOK].concat(V.steps[V.BISHOP])));
54 let swapping = [];
55 const c = this.turn;
56 for (let i=0; i<8; i++) {
57 for (let j=0; j<8; j++) {
58 // Following test is OK because only one Joker on board at a time
59 if (this.board[i][j] != V.EMPTY && this.getColor(i, j) == c) {
60 const p = this.getPiece(i, j);
61 swapping.push(
62 new Move({
63 vanish: [
64 new PiPo({ x: x, y: y, c: c, p: V.JOKER }),
65 new PiPo({ x: i, y: j, c: c, p: p })
66 ],
67 appear: [
68 new PiPo({ x: i, y: j, c: c, p: V.JOKER }),
69 new PiPo({ x: x, y: y, c: c, p: p })
70 ]
71 })
72 );
73 }
74 }
75 }
76 return moving.concat(swapping);
77 }
78
79 postPlay(move) {
80 super.postPlay(move);
81 // Was my king swapped?
82 if (move.vanish.length == 2 && move.vanish[1].p == V.KING)
83 this.kingPos[move.appear[1].c] = [move.appear[1].x, move.appear[1].y];
84 }
85
86 postUndo(move) {
87 super.postUndo(move);
88 if (move.vanish.length == 2 && move.vanish[1].p == V.KING)
89 this.kingPos[move.vanish[1].c] = [move.vanish[1].x, move.vanish[1].y];
90 }
91
92 static get VALUES() {
93 return Object.assign({ j: 2 }, ChessRules.VALUES);
94 }
95
96 static get SEARCH_DEPTH() {
97 return 2;
98 }
99
100 };