Commit | Line | Data |
---|---|---|
737a5daf BA |
1 | import { ChessRules } from "@/base_rules"; |
2 | import { randInt } from "@/utils/alea"; | |
3 | ||
4 | export class ProgressiveRules extends ChessRules { | |
5 | static get HasEnpassant() { | |
6 | return false; | |
7 | } | |
8 | ||
9 | setOtherVariables(fen) { | |
10 | super.setOtherVariables(fen); | |
11 | this.subTurn = 1; | |
12 | } | |
13 | ||
14 | filterValid(moves) { | |
15 | if (moves.length == 0) return []; | |
16 | const color = this.turn; | |
17 | return moves.filter(m => { | |
18 | // Not using this.play() (would result ininfinite recursive calls) | |
19 | V.PlayOnBoard(this.board, m); | |
20 | if (m.appear[0].p == V.KING) | |
21 | this.kingPos[color] = [m.appear[0].x, m.appear[0].y]; | |
22 | const res = !this.underCheck(color); | |
23 | V.UndoOnBoard(this.board, m); | |
24 | if (m.appear[0].p == V.KING) | |
25 | this.kingPos[color] = [m.vanish[0].x, m.vanish[0].y]; | |
26 | return res; | |
27 | }); | |
28 | } | |
29 | ||
30 | play(move) { | |
31 | move.flags = JSON.stringify(this.aggregateFlags()); | |
32 | const color = this.turn; | |
33 | const oppCol = V.GetOppCol(color); | |
34 | move.turn = [color, this.subTurn]; | |
35 | V.PlayOnBoard(this.board, move); | |
36 | if ( | |
37 | this.subTurn > this.movesCount || | |
38 | this.underCheck(oppCol) || | |
39 | !this.atLeastOneMove() | |
40 | ) { | |
41 | this.turn = oppCol; | |
42 | this.subTurn = 1; | |
43 | this.movesCount++; | |
44 | } | |
45 | else this.subTurn++; | |
46 | this.postPlay(move); | |
47 | } | |
48 | ||
49 | postPlay(move) { | |
50 | const c = move.turn[0]; | |
51 | const piece = move.vanish[0].p; | |
52 | const firstRank = c == "w" ? V.size.x - 1 : 0; | |
53 | ||
54 | if (piece == V.KING && move.appear.length > 0) { | |
55 | this.kingPos[c][0] = move.appear[0].x; | |
56 | this.kingPos[c][1] = move.appear[0].y; | |
57 | this.castleFlags[c] = [V.size.y, V.size.y]; | |
58 | return; | |
59 | } | |
60 | const oppCol = V.GetOppCol(c); | |
61 | const oppFirstRank = V.size.x - 1 - firstRank; | |
62 | if ( | |
63 | move.start.x == firstRank && //our rook moves? | |
64 | this.castleFlags[c].includes(move.start.y) | |
65 | ) { | |
66 | const flagIdx = (move.start.y == this.castleFlags[c][0] ? 0 : 1); | |
67 | this.castleFlags[c][flagIdx] = V.size.y; | |
68 | } | |
69 | if ( | |
70 | move.end.x == oppFirstRank && //we took opponent rook? | |
71 | this.castleFlags[oppCol].includes(move.end.y) | |
72 | ) { | |
73 | const flagIdx = (move.end.y == this.castleFlags[oppCol][0] ? 0 : 1); | |
74 | this.castleFlags[oppCol][flagIdx] = V.size.y; | |
75 | } | |
76 | } | |
77 | ||
78 | undo(move) { | |
79 | this.disaggregateFlags(JSON.parse(move.flags)); | |
80 | V.UndoOnBoard(this.board, move); | |
81 | if (this.turn != move.turn[0]) this.movesCount--; | |
82 | this.turn = move.turn[0]; | |
83 | this.subTurn = move.turn[1]; | |
84 | super.postUndo(move); | |
85 | } | |
86 | ||
87 | static get VALUES() { | |
88 | return { | |
89 | p: 1, | |
90 | r: 5, | |
91 | n: 3, | |
92 | b: 3, | |
93 | q: 7, //slightly less than in orthodox game | |
94 | k: 1000 | |
95 | }; | |
96 | } | |
97 | ||
98 | // Random moves (too high branching factor otherwise). TODO | |
99 | getComputerMove() { | |
100 | let res = []; | |
101 | const color = this.turn; | |
102 | while (this.turn == color) { | |
103 | const moves = this.getAllValidMoves(); | |
104 | const m = moves[randInt(moves.length)]; | |
105 | res.push(m); | |
106 | this.play(m); | |
107 | } | |
108 | for (let i=res.length - 1; i>= 0; i--) this.undo(res[i]); | |
109 | return res; | |
110 | } | |
111 | }; |