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