Commit | Line | Data |
---|---|---|
22053c2c BA |
1 | import { ChessRules, Move, PiPo } from "@/base_rules"; |
2 | import { randInt } from "@/utils/alea"; | |
3 | ||
4 | export class HamiltonRules extends ChessRules { | |
7e8a7ea1 | 5 | |
4313762d BA |
6 | static get Options() { |
7 | return null; | |
8 | } | |
9 | ||
22053c2c BA |
10 | static get HasFlags() { |
11 | return false; | |
12 | } | |
13 | ||
14 | static get HasEnpassant() { | |
15 | return false; | |
16 | } | |
17 | ||
f709e12f BA |
18 | get showFirstTurn() { |
19 | return true; | |
20 | } | |
21 | ||
22053c2c BA |
22 | static get HOLE() { |
23 | return "xx"; | |
24 | } | |
25 | ||
26 | static board2fen(b) { | |
27 | if (b[0] == 'x') return 'x'; | |
28 | return ChessRules.board2fen(b); | |
29 | } | |
30 | ||
31 | static fen2board(f) { | |
32 | if (f == 'x') return V.HOLE; | |
33 | return ChessRules.fen2board(f); | |
34 | } | |
35 | ||
36 | getPpath(b) { | |
37 | if (b[0] == 'x') return "Hamilton/hole"; | |
38 | return b; | |
39 | } | |
40 | ||
41 | static get PIECES() { | |
42 | return [ChessRules.KNIGHT]; | |
43 | } | |
44 | ||
45 | static IsGoodPosition(position) { | |
46 | if (position.length == 0) return false; | |
47 | const rows = position.split("/"); | |
48 | if (rows.length != V.size.x) return false; | |
49 | for (let row of rows) { | |
50 | let sumElts = 0; | |
51 | for (let i = 0; i < row.length; i++) { | |
52 | if (['x'].concat(V.PIECES).includes(row[i].toLowerCase())) sumElts++; | |
53 | else { | |
e50a8025 | 54 | const num = parseInt(row[i], 10); |
22053c2c BA |
55 | if (isNaN(num)) return false; |
56 | sumElts += num; | |
57 | } | |
58 | } | |
59 | if (sumElts != V.size.y) return false; | |
60 | } | |
61 | return true; | |
62 | } | |
63 | ||
64 | static GenRandInitFen() { | |
65 | return "8/8/8/8/8/8/8/8 w 0"; | |
66 | } | |
67 | ||
68 | canIplay(side, [x, y]) { | |
69 | return side == this.turn; | |
70 | } | |
71 | ||
e9437f4b BA |
72 | hoverHighlight() { |
73 | return this.movesCount == 0; | |
74 | } | |
75 | ||
22053c2c BA |
76 | // Initiate the game by choosing a square for the knight: |
77 | doClick(square) { | |
78 | if (this.movesCount > 0) return null; | |
79 | return new Move({ | |
80 | appear: [ | |
81 | new PiPo({ x: square[0], y: square[1], c: 'w', p: V.KNIGHT }) | |
82 | ], | |
83 | vanish: [], | |
84 | start: { x: -1, y: -1 } | |
85 | }); | |
86 | } | |
87 | ||
88 | getAllPotentialMoves() { | |
89 | if (this.movesCount == 0) { | |
90 | return [...Array(64).keys()].map(k => { | |
91 | const i = k % 8; | |
92 | const j = (k - i) / 8; | |
e9437f4b | 93 | return this.doClick([i, j]); |
22053c2c BA |
94 | }); |
95 | } | |
96 | for (let i=0; i<8; i++) { | |
97 | for (let j=0; j<8; j++) { | |
98 | if (!([V.EMPTY, V.HOLE].includes(this.board[i][j]))) | |
99 | return this.getPotentialKnightMoves([i, j]); | |
100 | } | |
101 | } | |
102 | return []; | |
103 | } | |
104 | ||
105 | getPotentialKnightMoves([x, y]) { | |
106 | return ( | |
107 | V.steps[V.KNIGHT].filter( | |
108 | s => { | |
109 | const [i, j] = [x + s[0], y + s[1]]; | |
110 | return (V.OnBoard(i, j) && this.board[i][j] != V.HOLE); | |
111 | } | |
112 | ).map(s => { | |
113 | return this.getBasicMove([x, y], [x + s[0], y + s[1]]); | |
114 | }) | |
115 | ); | |
116 | } | |
117 | ||
118 | atLeastOneMove() { | |
119 | if (this.movesCount == 0) return true; | |
120 | for (let i=0; i<8; i++) { | |
121 | for (let j=0; j<8; j++) { | |
122 | if (!([V.EMPTY, V.HOLE].includes(this.board[i][j]))) | |
123 | return this.getPotentialKnightMoves([i, j]).length > 0; | |
124 | } | |
125 | } | |
126 | return false; | |
127 | } | |
128 | ||
129 | filterValid(moves) { | |
130 | return moves; | |
131 | } | |
132 | ||
133 | static PlayOnBoard(board, move) { | |
134 | if (move.vanish.length > 0) | |
135 | board[move.vanish[0].x][move.vanish[0].y] = V.HOLE; | |
136 | for (let psq of move.appear) board[psq.x][psq.y] = psq.c + psq.p; | |
137 | } | |
138 | ||
27cb34b5 BA |
139 | postPlay() {} |
140 | postUndo() {} | |
141 | ||
22053c2c BA |
142 | getCheckSquares() { |
143 | return []; | |
144 | } | |
145 | ||
146 | getCurrentScore() { | |
147 | if (this.atLeastOneMove()) return "*"; | |
148 | // No valid move: I lose | |
149 | return this.turn == "w" ? "0-1" : "1-0"; | |
150 | } | |
151 | ||
152 | getComputerMove() { | |
153 | const moves = this.getAllValidMoves(); | |
154 | // Just a random mover for now... | |
155 | return moves[randInt(moves.length)]; | |
156 | } | |
157 | ||
158 | getNotation(move) { | |
159 | if (move.vanish.length > 0) return super.getNotation(move); | |
160 | // First game move: | |
161 | return "N@" + V.CoordsToSquare(move.end); | |
162 | } | |
7e8a7ea1 | 163 | |
22053c2c | 164 | }; |