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