Commit | Line | Data |
---|---|---|
d2af3400 | 1 | import { ChessRules, Move, PiPo } from "@/base_rules"; |
c11afcdf | 2 | import { randInt } from "@/utils/alea"; |
d2af3400 | 3 | |
d2af3400 BA |
4 | export class KonaneRules extends ChessRules { |
5 | ||
6 | static get HasFlags() { | |
7 | return false; | |
8 | } | |
9 | ||
10 | static get HasEnpassant() { | |
11 | return false; | |
12 | } | |
13 | ||
cbe95378 BA |
14 | static get ReverseColors() { |
15 | return true; | |
16 | } | |
17 | ||
cbe95378 BA |
18 | getPiece() { |
19 | return V.PAWN; | |
20 | } | |
21 | ||
d2af3400 BA |
22 | getPpath(b) { |
23 | return "Konane/" + b; | |
24 | } | |
25 | ||
26 | static IsGoodPosition(position) { | |
27 | if (position.length == 0) return false; | |
28 | const rows = position.split("/"); | |
29 | if (rows.length != V.size.x) return false; | |
30 | for (let row of rows) { | |
31 | let sumElts = 0; | |
32 | for (let i = 0; i < row.length; i++) { | |
cdab5663 | 33 | if (row[i].toLowerCase() == V.PAWN) sumElts++; |
d2af3400 BA |
34 | else { |
35 | const num = parseInt(row[i], 10); | |
36 | if (isNaN(num) || num <= 0) return false; | |
37 | sumElts += num; | |
38 | } | |
39 | } | |
40 | if (sumElts != V.size.y) return false; | |
41 | } | |
42 | return true; | |
43 | } | |
44 | ||
45 | static GenRandInitFen() { | |
46 | return ( | |
47 | "PpPpPpPp/pPpPpPpP/PpPpPpPp/pPpPpPpP/" + | |
48 | "PpPpPpPp/pPpPpPpP/PpPpPpPp/pPpPpPpP w 0" | |
49 | ); | |
50 | } | |
51 | ||
7c05a5f2 | 52 | hoverHighlight([x, y], side) { |
d2af3400 | 53 | const c = this.turn; |
7c05a5f2 | 54 | if (this.movesCount >= 2 || (!!side && side != c)) return false; |
d2af3400 BA |
55 | if (c == 'w') return (x == y && [0, 3, 4, 7].includes(x)); |
56 | // "Black": search for empty square and allow nearby | |
57 | for (let i of [0, 3, 4, 7]) { | |
58 | if (this.board[i][i] == V.EMPTY) | |
59 | return (Math.abs(x - i) + Math.abs(y - i) == 1) | |
60 | } | |
61 | } | |
62 | ||
63 | onlyClick([x, y]) { | |
64 | return ( | |
65 | this.movesCount <= 1 || | |
66 | // TODO: next line theoretically shouldn't be required... | |
67 | (this.movesCount == 2 && this.getColor(x, y) != this.turn) | |
68 | ); | |
69 | } | |
70 | ||
71 | doClick([x, y]) { | |
72 | if (this.movesCount >= 2) return null; | |
73 | const color = this.turn; | |
74 | if (color == 'w') { | |
75 | if (x != y || ![0, 3, 4, 7].includes(x)) return null; | |
76 | return new Move({ | |
77 | appear: [], | |
78 | vanish: [ new PiPo({ x: x, y: y, c: color, p: V.PAWN }) ], | |
79 | end: { x: x, y: y } | |
80 | }); | |
81 | } | |
82 | // "Black": search for empty square and allow nearby | |
83 | for (let i of [0, 3, 4, 7]) { | |
84 | if (this.board[i][i] == V.EMPTY) { | |
85 | if (Math.abs(x - i) + Math.abs(y - i) != 1) return null; | |
86 | return new Move({ | |
87 | appear: [], | |
88 | vanish: [ new PiPo({ x: x, y: y, c: color, p: V.PAWN }) ], | |
89 | end: { x: x, y: y } | |
90 | }); | |
91 | } | |
92 | } | |
93 | } | |
94 | ||
95 | getPotentialMovesFrom([x, y]) { | |
96 | if (this.movesCount <= 1) { | |
97 | const mv = this.doClick([x, y]); | |
98 | return (!!mv ? [mv] : []); | |
99 | } | |
d2af3400 BA |
100 | const color = this.turn; |
101 | const oppCol = V.GetOppCol(color); | |
d2af3400 | 102 | let moves = []; |
ee69c769 BA |
103 | for (let s of V.steps[V.ROOK]) { |
104 | let curmv = new Move({ | |
105 | appear: [ new PiPo({ x: -1, y: -1, c: color, p: V.PAWN }) ], | |
106 | vanish: [ new PiPo({ x: x, y: y, c: color, p: V.PAWN }) ] | |
107 | }); | |
108 | for (let mult = 2; ; mult += 2) { | |
109 | let [i, j] = [x + mult * s[0], y + mult * s[1]]; | |
d2af3400 BA |
110 | if ( |
111 | V.OnBoard(i, j) && | |
112 | this.board[i][j] == V.EMPTY && | |
113 | this.board[i - s[0]][j - s[1]] != V.EMPTY && | |
114 | this.getColor(i - s[0], j - s[1]) == oppCol | |
115 | ) { | |
ee69c769 BA |
116 | curmv.vanish.push( |
117 | new PiPo({ x: i - s[0], y: j - s[1], c: oppCol, p: V.PAWN })); | |
118 | let mv = JSON.parse(JSON.stringify(curmv)); | |
119 | mv.appear[0].x = i; | |
120 | mv.appear[0].y = j; | |
121 | mv.end = { x: i, y: j }; | |
122 | moves.push(mv); | |
d2af3400 | 123 | } |
ee69c769 | 124 | else break; |
d2af3400 BA |
125 | } |
126 | } | |
127 | return moves; | |
128 | } | |
129 | ||
130 | filterValid(moves) { | |
131 | return moves; | |
132 | } | |
133 | ||
134 | getCheckSquares() { | |
135 | return []; | |
136 | } | |
137 | ||
138 | getCurrentScore() { | |
139 | if (this.atLeastOneMove()) return "*"; | |
140 | return (this.turn == "w" ? "0-1" : "1-0"); | |
141 | } | |
142 | ||
ee69c769 BA |
143 | static get SEARCH_DEPTH() { |
144 | return 4; | |
d2af3400 BA |
145 | } |
146 | ||
147 | getNotation(move) { | |
148 | if (this.movesCount <= 1) return V.CoordsToSquare(move.start) + "X"; | |
149 | if (move.vanish.length == 0) return "end"; | |
ee69c769 | 150 | return V.CoordsToSquare(move.start) + V.CoordsToSquare(move.end); |
d2af3400 BA |
151 | } |
152 | ||
153 | }; |