1 import { ChessRules
} from "@/base_rules";
2 import { ArrayFun
} from "@/utils/array";
3 import { randInt
} from "@/utils/alea";
5 export const VariantRules
= class HiddenRules
extends ChessRules
{
6 static get HasFlags() {
10 static get HasEnpassant() {
14 // Analyse in Hidden mode makes no sense
15 static get CanAnalyze() {
19 // Moves are revealed only when game ends
20 static get ShowMoves() {
24 static get HIDDEN_DECODE() {
34 static get HIDDEN_CODE() {
46 return ChessRules
.PIECES
.concat(Object
.values(V
.HIDDEN_CODE
));
49 // Scan board for kings positions (no castling)
51 this.kingPos
= { w: [-1, -1], b: [-1, -1] };
52 const fenRows
= V
.ParseFen(fen
).position
.split("/");
53 for (let i
= 0; i
< fenRows
.length
; i
++) {
54 let k
= 0; //column index on board
55 for (let j
= 0; j
< fenRows
[i
].length
; j
++) {
56 switch (fenRows
[i
].charAt(j
)) {
59 this.kingPos
["b"] = [i
, k
];
63 this.kingPos
["w"] = [i
, k
];
66 const num
= parseInt(fenRows
[i
].charAt(j
));
67 if (!isNaN(num
)) k
+= num
- 1;
75 getPpath(b
, color
, score
) {
76 if (Object
.keys(V
.HIDDEN_DECODE
).includes(b
[1])) {
77 // Supposed to be hidden.
78 if (score
== "*" && (!color
|| color
!= b
[0]))
79 return "Hidden/" + b
[0] + "p";
80 // Else: condition OK to show the piece
81 return b
[0] + V
.HIDDEN_DECODE
[b
[1]];
83 // The piece is already not supposed to be hidden:
87 //getPotentialMovesFrom: TODO: write
89 // TODO: bishops on different colors, a1 --> h1, h2 --> a2 ?
90 static GenRandInitFen() {
91 let pieces
= { w: new Array(8), b: new Array(8) };
92 // Shuffle pieces + pawns on two first ranks
93 for (let c
of ["w", "b"]) {
94 let positions
= ArrayFun
.range(16);
96 // Get random squares for bishops
97 let randIndex
= 2 * randInt(8);
98 const bishop1Pos
= positions
[randIndex
];
99 // The second bishop must be on a square of different color
100 let randIndex_tmp
= 2 * randInt(8) + 1;
101 const bishop2Pos
= positions
[randIndex_tmp
];
102 // Remove chosen squares
103 positions
.splice(Math
.max(randIndex
, randIndex_tmp
), 1);
104 positions
.splice(Math
.min(randIndex
, randIndex_tmp
), 1);
106 // Get random squares for knights
107 randIndex
= randInt(14);
108 const knight1Pos
= positions
[randIndex
];
109 positions
.splice(randIndex
, 1);
110 randIndex
= randInt(13);
111 const knight2Pos
= positions
[randIndex
];
112 positions
.splice(randIndex
, 1);
114 // Get random square for queen
115 randIndex
= randInt(12);
116 const queenPos
= positions
[randIndex
];
117 positions
.splice(randIndex
, 1);
119 // Get random squares for pawns
122 // Rooks and king positions are now fixed,
123 // because of the ordering rook-king-rook
124 const rook1Pos
= positions
[0];
125 const kingPos
= positions
[1];
126 const rook2Pos
= positions
[2];
128 // Finally put the shuffled pieces in the board array
129 pieces
[c
][rook1Pos
] = "r";
130 pieces
[c
][knight1Pos
] = "n";
131 pieces
[c
][bishop1Pos
] = "b";
132 pieces
[c
][queenPos
] = "q";
133 pieces
[c
][kingPos
] = "k";
134 pieces
[c
][bishop2Pos
] = "b";
135 pieces
[c
][knight2Pos
] = "n";
136 pieces
[c
][rook2Pos
] = "r";
139 pieces
["b"].join("") +
140 "/pppppppp/8/8/8/8/PPPPPPPP/" +
141 pieces
["w"].join("").toUpperCase() +
150 updateVariables(move) {
151 super.updateVariables(move);
153 move.vanish
.length
>= 2 &&
154 [V
.KING
,V
.HIDDEN_CODE
[V
.KING
]].includes(move.vanish
[1].p
)
156 // We took opponent king
157 this.kingPos
[this.turn
] = [-1, -1];
161 unupdateVariables(move) {
162 super.unupdateVariables(move);
163 const c
= move.vanish
[0].c
;
164 const oppCol
= V
.GetOppCol(c
);
165 if (this.kingPos
[oppCol
][0] < 0)
166 // Last move took opponent's king:
167 this.kingPos
[oppCol
] = [move.vanish
[1].x
, move.vanish
[1].y
];
171 const color
= this.turn
;
172 const kp
= this.kingPos
[color
];
175 return color
== "w" ? "0-1" : "1-0";
176 // Assume that stalemate is impossible:
181 // Just return a random move. TODO: something smarter...
182 const moves
= this.getAllValidMoves();
183 return moves
[randInt(moves
.length
)];