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