Update TODO
[vchess.git] / client / src / variants / Progressive.js
CommitLineData
737a5daf
BA
1import { ChessRules } from "@/base_rules";
2import { randInt } from "@/utils/alea";
3
4export 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};