Commit | Line | Data |
---|---|---|
f0a812b7 BA |
1 | import { ChessRules } from "@/base_rules"; |
2 | ||
3 | export class IceageRules extends ChessRules { | |
4 | ||
5 | static get IgnoreRepetition() { | |
6 | return true; | |
7 | } | |
8 | ||
9 | static get ICECUBE() { | |
10 | return "cc"; | |
11 | } | |
12 | ||
13 | static board2fen(b) { | |
14 | if (b[0] == 'c') return 'c'; | |
15 | return ChessRules.board2fen(b); | |
16 | } | |
17 | ||
18 | static fen2board(f) { | |
19 | if (f == 'c') return V.ICECUBE; | |
20 | return ChessRules.fen2board(f); | |
21 | } | |
22 | ||
23 | getPpath(b) { | |
24 | if (b[0] == 'c') return "Iceage/icecube"; | |
25 | return b; | |
26 | } | |
27 | ||
28 | static IsGoodPosition(position) { | |
29 | if (position.length == 0) return false; | |
30 | const rows = position.split("/"); | |
31 | if (rows.length != V.size.x) return false; | |
32 | let kings = { "k": 0, "K": 0 }; | |
33 | for (let row of rows) { | |
34 | let sumElts = 0; | |
35 | for (let i = 0; i < row.length; i++) { | |
36 | if (['K','k'].includes(row[i])) kings[row[i]]++; | |
37 | if (['c'].concat(V.PIECES).includes(row[i].toLowerCase())) sumElts++; | |
38 | else { | |
39 | const num = parseInt(row[i], 10); | |
40 | if (isNaN(num)) return false; | |
41 | sumElts += num; | |
42 | } | |
43 | } | |
44 | if (sumElts != V.size.y) return false; | |
45 | } | |
46 | if (Object.values(kings).some(v => v != 1)) return false; | |
47 | return true; | |
48 | } | |
49 | ||
4313762d BA |
50 | static GenRandInitFen(options) { |
51 | return ChessRules.GenRandInitFen(options).replace(/8/g, "cccccccc"); | |
f0a812b7 BA |
52 | } |
53 | ||
54 | play(move) { | |
55 | const iceAgeAfterMove = (this.movesCount % 40 == 39); | |
56 | if (iceAgeAfterMove) | |
57 | // Next ice age after this move: | |
58 | move.state = JSON.stringify(this.board); | |
59 | super.play(move); | |
60 | if (iceAgeAfterMove) { | |
61 | for (let i=0; i<8; i++) { | |
62 | for (let j=0; j<8; j++) { | |
63 | if (this.board[i][j] == V.EMPTY) { | |
64 | const surrounded = V.steps[V.ROOK].every(s => { | |
65 | const [ii, jj] = [i + s[0], j + s[1]]; | |
66 | return ( | |
67 | !V.OnBoard(ii, jj) || | |
68 | ![V.EMPTY, V.ICECUBE].includes(this.board[ii][jj]) | |
69 | ); | |
70 | }); | |
71 | if (!surrounded) this.board[i][j] = V.ICECUBE; | |
72 | } | |
73 | else if (this.board[i][j] != V.ICECUBE) { | |
74 | const steps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]); | |
75 | const connected = steps.some(s => { | |
76 | const [ii, jj] = [i + s[0], j + s[1]]; | |
77 | return ( | |
78 | V.OnBoard(ii, jj) && | |
79 | ![V.EMPTY, V.ICECUBE].includes(this.board[ii][jj]) | |
80 | ); | |
81 | }); | |
82 | if (!connected) this.board[i][j] = V.ICECUBE; | |
83 | } | |
84 | } | |
85 | } | |
86 | // Update king position (no need to update flags: game over) | |
87 | const kp = this.kingPos; | |
88 | if (this.getPiece(kp['w'][0], kp['w'][1]) != V.KING) | |
89 | this.kingPos['w'] = [-1, -1]; | |
90 | if (this.getPiece(kp['b'][0], kp['b'][1]) != V.KING) | |
91 | this.kingPos['b'] = [-1, -1]; | |
92 | } | |
93 | } | |
94 | ||
95 | undo(move) { | |
96 | super.undo(move); | |
97 | if (!!move.state) { | |
98 | this.board = JSON.parse(move.state); | |
99 | if (this.kingPos['w'][0] < 0 || this.kingPos['b'][0] < 0) { | |
100 | for (let i=0; i<8; i++) { | |
101 | for (let j=0; j<8; j++) { | |
102 | if (this.board[i][j] != V.EMPTY && this.getPiece(i, j) == V.KING) | |
103 | this.kingPos[this.getColor(i, j)] = [i, j]; | |
104 | } | |
105 | } | |
106 | } | |
107 | } | |
108 | } | |
109 | ||
110 | getCheckSquares() { | |
111 | if (this.kingPos[this.turn][0] < 0) return []; | |
112 | return super.getCheckSquares(); | |
113 | } | |
114 | ||
115 | getCurrentScore() { | |
116 | const kingDisappear = { | |
117 | w: this.kingPos['w'][0] < 0, | |
118 | b: this.kingPos['b'][0] < 0 | |
119 | }; | |
120 | if (kingDisappear['w'] && kingDisappear['b']) return "1/2"; | |
121 | if (kingDisappear['w']) return "0-1"; | |
122 | if (kingDisappear['b']) return "1-0"; | |
123 | return super.getCurrentScore(); | |
124 | } | |
125 | ||
126 | static get SEARCH_DEPTH() { | |
127 | return 2; | |
128 | } | |
129 | ||
130 | evalPosition() { | |
131 | let evaluation = 0; | |
132 | for (let i = 0; i < V.size.x; i++) { | |
133 | for (let j = 0; j < V.size.y; j++) { | |
134 | if (![V.EMPTY,V.ICECUBE].includes(this.board[i][j])) { | |
135 | const sign = this.getColor(i, j) == "w" ? 1 : -1; | |
136 | evaluation += sign * V.VALUES[this.getPiece(i, j)]; | |
137 | } | |
138 | } | |
139 | } | |
140 | return evaluation; | |
141 | } | |
142 | ||
143 | }; |