Implemented and tested DarkChess. Berolina, Upsidedown should be OK. Marseille: TODO
[vchess.git] / public / javascripts / variants / Dark.js
CommitLineData
388e4c40 1class DarkRules extends ChessRules
375ecdd1
BA
2{
3 // Standard rules, in the shadow
4 setOtherVariables(fen)
5 {
6 super.setOtherVariables(fen);
388e4c40 7 const [sizeX,sizeY] = [V.size.x,V.size.y];
375ecdd1 8 this.enlightened = {
388e4c40
BA
9 "w": doubleArray(sizeX,sizeY),
10 "b": doubleArray(sizeX,sizeY)
375ecdd1 11 };
388e4c40
BA
12 // Setup enlightened: squares reachable by each side
13 // (TODO: one side would be enough ?)
14 this.updateEnlightened();
375ecdd1
BA
15 }
16
388e4c40 17 updateEnlightened()
375ecdd1 18 {
388e4c40
BA
19 // Initialize with pieces positions (which are seen)
20 for (let i=0; i<V.size.x; i++)
21 {
22 for (let j=0; j<V.size.y; j++)
23 {
24 this.enlightened["w"][i][j] = false;
25 this.enlightened["b"][i][j] = false;
26 if (this.board[i][j] != V.EMPTY)
27 this.enlightened[this.getColor(i,j)][i][j] = true;
28 }
29 }
30 const currentTurn = this.turn;
31 this.turn = "w";
32 const movesWhite = this.getAllValidMoves();
33 this.turn = "b";
34 const movesBlack = this.getAllValidMoves();
35 this.turn = currentTurn;
36 for (let move of movesWhite)
37 this.enlightened["w"][move.end.x][move.end.y] = true;
38 for (let move of movesBlack)
39 this.enlightened["b"][move.end.x][move.end.y] = true;
375ecdd1
BA
40 }
41
42 atLeastOneMove()
43 {
44 if (this.kingPos[this.turn][0] < 0)
45 return false;
46 return true; //TODO: is it right?
47 }
48
49 underCheck(move)
50 {
51 return false; //there is no check
52 }
53
54 getCheckSquares(move)
55 {
56 const c = this.getOppCol(this.turn); //opponent
57 const saveKingPos = this.kingPos[c]; //king might be taken
58 this.play(move);
59 // The only way to be "under check" is to have lost the king (thus game over)
60 let res = this.kingPos[c][0] < 0
61 ? [JSON.parse(JSON.stringify(saveKingPos))]
62 : [];
63 this.undo(move);
64 return res;
65 }
66
388e4c40
BA
67 updateVariables(move)
68 {
69 // Update kings positions
70 const piece = move.vanish[0].p;
71 const c = move.vanish[0].c;
72 if (piece == V.KING && move.appear.length > 0)
73 {
74 this.kingPos[c][0] = move.appear[0].x;
75 this.kingPos[c][1] = move.appear[0].y;
76 }
77 if (move.vanish.length >= 2 && move.vanish[1].p == V.KING)
78 {
79 // We took opponent king !
80 const oppCol = this.getOppCol(c);
81 this.kingPos[oppCol] = [-1,-1];
82 }
83
84 // Update moves for both colors:
85 this.updateEnlightened();
86 }
87
88 unupdateVariables(move)
89 {
90 super.unupdateVariables(move);
91 const c = move.vanish[0].c;
92 const oppCol = this.getOppCol(c);
93 if (this.kingPos[oppCol][0] < 0)
94 {
95 // Last move took opponent's king
96 for (let psq of move.vanish)
97 {
98 if (psq.p == 'k')
99 {
100 this.kingPos[oppCol] = [psq.x, psq.y];
101 break;
102 }
103 }
104 }
105
106 // Update moves for both colors:
107 this.updateEnlightened();
108 }
375ecdd1
BA
109
110 checkGameEnd()
111 {
112 // No valid move: our king disappeared
113 return this.turn == "w" ? "0-1" : "1-0";
114 }
115
116 static get THRESHOLD_MATE()
117 {
118 return 500; //checkmates evals may be slightly below 1000
119 }
120}
121
122const VariantRules = DarkRules;