Commit | Line | Data |
---|---|---|
0a36d31a | 1 | import ChessRules from "/base_rules.js"; |
554e3ad3 | 2 | import GiveawayRules from "/variants/Giveaway/class.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 | ||
25 | genRandInitFen(seed) { | |
554e3ad3 BA |
26 | const options = Object.assign({mode: "suicide"}, this.options); |
27 | const gr = new GiveawayRules({options: options, genFenOnly: true}); | |
0a36d31a BA |
28 | return gr.genRandInitFen(seed); |
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 => { | |
554e3ad3 BA |
58 | if (m.vanish.length == 1) { |
59 | m.appear[0].c = 'a'; //a-color | |
60 | m.appear[0].p = V.GOAL; | |
61 | } | |
62 | else { | |
63 | m.appear[0].p = V.TARGET_CODE[m.vanish[1].p]; | |
64 | m.appear[0].c = oppCol; | |
65 | } | |
0a36d31a BA |
66 | m.vanish.shift(); |
67 | return m; | |
68 | }) | |
69 | ); | |
70 | } | |
554e3ad3 | 71 | // At subTurn == 1, play a targeted move for the opponent. |
0a36d31a | 72 | // Search for target (we could also have it in a stack...) |
554e3ad3 BA |
73 | let target = {x: -1, y: -1}; |
74 | outerLoop: for (let i = 0; i < this.size.x; i++) { | |
75 | for (let j = 0; j < this.size.y; j++) { | |
76 | if (this.board[i][j] != "") { | |
77 | const piece = this.getPiece(i, j); | |
0a36d31a BA |
78 | if ( |
79 | piece == V.GOAL || | |
80 | Object.keys(V.TARGET_DECODE).includes(piece) | |
81 | ) { | |
554e3ad3 | 82 | target = {x: i, y:j}; |
0a36d31a BA |
83 | break outerLoop; |
84 | } | |
85 | } | |
86 | } | |
87 | } | |
554e3ad3 | 88 | const moves = super.getPotentialMovesFrom([x, y], oppCol); |
0a36d31a BA |
89 | return moves.filter(m => m.end.x == target.x && m.end.y == target.y); |
90 | } | |
91 | ||
92 | canIplay(x, y) { | |
93 | const color = this.getColor(x, y); | |
94 | return ( | |
95 | (this.subTurn == 1 && ![this.turn, this.playerColor].includes(color)) || | |
96 | (this.subTurn == 2 && super.canIplay(x, y)) | |
97 | ); | |
98 | } | |
99 | ||
100 | // Code for empty square target | |
101 | static get GOAL() { | |
102 | return 'g'; | |
103 | } | |
104 | ||
105 | static get TARGET_DECODE() { | |
106 | return { | |
107 | 's': 'p', | |
108 | 't': 'q', | |
109 | 'u': 'r', | |
110 | 'o': 'n', | |
111 | 'c': 'b', | |
112 | 'l': 'k' | |
113 | }; | |
114 | } | |
115 | ||
116 | static get TARGET_CODE() { | |
117 | return { | |
118 | 'p': 's', | |
119 | 'q': 't', | |
120 | 'r': 'u', | |
121 | 'n': 'o', | |
122 | 'b': 'c', | |
123 | 'k': 'l' | |
124 | }; | |
125 | } | |
126 | ||
554e3ad3 BA |
127 | pieces(color, x, y) { |
128 | const targets = { | |
129 | 's': {"class": "target-pawn", moves: []}, | |
130 | 'u': {"class": "target-rook", moves: []}, | |
131 | 'o': {"class": "target-knight", moves: []}, | |
132 | 'c': {"class": "target-bishop", moves: []}, | |
133 | 't': {"class": "target-queen", moves: []}, | |
134 | 'l': {"class": "target-king", moves: []} | |
135 | }; | |
136 | return Object.assign( | |
137 | { 'g': {"class": "target"} }, targets, super.pieces(color, x, y)); | |
0a36d31a BA |
138 | } |
139 | ||
140 | atLeastOneMove() { | |
141 | // Since there are no checks this seems true (same as for Magnetic...) | |
142 | return true; | |
143 | } | |
144 | ||
145 | filterValid(moves) { | |
146 | return moves; | |
147 | } | |
148 | ||
554e3ad3 BA |
149 | isKing(symbol) { |
150 | return ['k', 'l'].includes(symbol); | |
151 | } | |
152 | ||
0a36d31a BA |
153 | getCurrentScore() { |
154 | // This function is only called at subTurn 1 | |
554e3ad3 BA |
155 | const color = C.GetOppCol(this.turn); |
156 | const kingPos = this.searchKingPos(color); | |
157 | if (kingPos[0] < 0) | |
158 | return (color == 'w' ? "0-1" : "1-0"); | |
0a36d31a BA |
159 | return "*"; |
160 | } | |
161 | ||
554e3ad3 BA |
162 | postPlay(move) { |
163 | const color = this.turn; | |
164 | if (this.subTurn == 2 || this.searchKingPos(color)[0] < 0) { | |
165 | this.turn = C.GetOppCol(color); | |
0a36d31a BA |
166 | this.movesCount++; |
167 | } | |
554e3ad3 | 168 | this.subTurn = 3 - this.subTurn; |
0a36d31a BA |
169 | } |
170 | ||
171 | }; |