Cleaner fen generation + first draft of Apocalypse + a few fixes
[xogo.git] / variants / Ambiguous / class.js
CommitLineData
0a36d31a 1import ChessRules from "/base_rules.js";
554e3ad3 2import GiveawayRules from "/variants/Giveaway/class.js";
0a36d31a
BA
3
4export default class AmbiguousRules extends ChessRules {
5
554e3ad3
BA
6 static get Options() {
7 return {
8 select: C.Options.select,
9 styles: ["cylinder"]
10 };
11 }
0a36d31a
BA
12
13 get hasFlags() {
14 return false;
15 }
16
17 setOtherVariables(fenParsed) {
18 super.setOtherVariables(fenParsed);
19 if (this.movesCount == 0)
20 this.subTurn = 2;
21 else
22 this.subTurn = 1;
23 }
24
f31de5e4 25 genRandInitBaseFen() {
554e3ad3
BA
26 const options = Object.assign({mode: "suicide"}, this.options);
27 const gr = new GiveawayRules({options: options, genFenOnly: true});
f31de5e4 28 return gr.genRandInitBaseFen();
0a36d31a
BA
29 }
30
554e3ad3
BA
31 canStepOver(x, y) {
32 return this.board[x][y] == "" || this.getPiece(x, y) == V.GOAL;
33 }
34
0a36d31a
BA
35 // Subturn 1: play a move for the opponent on the designated square.
36 // Subturn 2: play a move for me (which just indicate a square).
37 getPotentialMovesFrom([x, y]) {
38 const color = this.turn;
554e3ad3 39 const oppCol = C.GetOppCol(color);
0a36d31a
BA
40 if (this.subTurn == 2) {
41 // Just play a normal move (which in fact only indicate a square)
42 let movesHash = {};
43 return (
44 super.getPotentialMovesFrom([x, y])
45 .filter(m => {
554e3ad3 46 // Filter promotions: keep only one, since no choice for now.
0a36d31a 47 if (m.appear[0].p != m.vanish[0].p) {
554e3ad3 48 const hash = C.CoordsToSquare(m.start) + C.CoordsToSquare(m.end);
0a36d31a
BA
49 if (!movesHash[hash]) {
50 movesHash[hash] = true;
51 return true;
52 }
53 return false;
54 }
55 return true;
56 })
57 .map(m => {
65cf1690 58 if (m.vanish.length == 1)
554e3ad3 59 m.appear[0].p = V.GOAL;
f31de5e4 60 else {
554e3ad3 61 m.appear[0].p = V.TARGET_CODE[m.vanish[1].p];
f31de5e4
BA
62 m.appear[0].c = m.vanish[1].c;
63 }
0a36d31a
BA
64 m.vanish.shift();
65 return m;
66 })
67 );
68 }
554e3ad3 69 // At subTurn == 1, play a targeted move for the opponent.
f31de5e4 70 // Search for target:
554e3ad3
BA
71 let target = {x: -1, y: -1};
72 outerLoop: for (let i = 0; i < this.size.x; i++) {
73 for (let j = 0; j < this.size.y; j++) {
74 if (this.board[i][j] != "") {
75 const piece = this.getPiece(i, j);
0a36d31a
BA
76 if (
77 piece == V.GOAL ||
78 Object.keys(V.TARGET_DECODE).includes(piece)
79 ) {
554e3ad3 80 target = {x: i, y:j};
0a36d31a
BA
81 break outerLoop;
82 }
83 }
84 }
85 }
554e3ad3 86 const moves = super.getPotentialMovesFrom([x, y], oppCol);
0a36d31a
BA
87 return moves.filter(m => m.end.x == target.x && m.end.y == target.y);
88 }
89
90 canIplay(x, y) {
91 const color = this.getColor(x, y);
92 return (
93 (this.subTurn == 1 && ![this.turn, this.playerColor].includes(color)) ||
94 (this.subTurn == 2 && super.canIplay(x, y))
95 );
96 }
97
98 // Code for empty square target
99 static get GOAL() {
100 return 'g';
101 }
102
103 static get TARGET_DECODE() {
104 return {
105 's': 'p',
106 't': 'q',
107 'u': 'r',
108 'o': 'n',
109 'c': 'b',
110 'l': 'k'
111 };
112 }
113
114 static get TARGET_CODE() {
115 return {
116 'p': 's',
117 'q': 't',
118 'r': 'u',
119 'n': 'o',
120 'b': 'c',
121 'k': 'l'
122 };
123 }
124
554e3ad3
BA
125 pieces(color, x, y) {
126 const targets = {
127 's': {"class": "target-pawn", moves: []},
128 'u': {"class": "target-rook", moves: []},
129 'o': {"class": "target-knight", moves: []},
130 'c': {"class": "target-bishop", moves: []},
131 't': {"class": "target-queen", moves: []},
132 'l': {"class": "target-king", moves: []}
133 };
65cf1690
BA
134 return Object.assign({ 'g': {"class": "target", moves: []} },
135 targets, super.pieces(color, x, y));
0a36d31a
BA
136 }
137
138 atLeastOneMove() {
139 // Since there are no checks this seems true (same as for Magnetic...)
140 return true;
141 }
142
143 filterValid(moves) {
144 return moves;
145 }
146
f31de5e4
BA
147 isKing(x, y, p) {
148 if (!p)
149 p = this.getPiece(x, y);
150 return ['k', 'l'].includes(p);
554e3ad3
BA
151 }
152
0a36d31a
BA
153 getCurrentScore() {
154 // This function is only called at subTurn 1
554e3ad3 155 const color = C.GetOppCol(this.turn);
f3e90e30 156 if (this.searchKingPos(color).length == 0)
554e3ad3 157 return (color == 'w' ? "0-1" : "1-0");
0a36d31a
BA
158 return "*";
159 }
160
554e3ad3
BA
161 postPlay(move) {
162 const color = this.turn;
f3e90e30 163 if (this.subTurn == 2 || this.searchKingPos(color).length == 0) {
554e3ad3 164 this.turn = C.GetOppCol(color);
0a36d31a
BA
165 this.movesCount++;
166 }
554e3ad3 167 this.subTurn = 3 - this.subTurn;
0a36d31a
BA
168 }
169
170};