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