1 class CrazyhouseRules
extends ChessRules
5 super.initVariables(fen
);
6 // Also init reserves (used by the interface to show landing pieces)
26 this.promoted
= doubleArray(V
.size
.x
, V
.size
.y
, false);
27 // May be a continuation: adjust numbers of pieces in reserve + promoted pieces
28 this.moves
.forEach(m
=> { this.updateVariables(m
); });
34 return (i
==V
.size
.x
? "w" : "b");
35 return this.board
[i
][j
].charAt(0);
40 return V
.RESERVE_PIECES
[j
];
41 return this.board
[i
][j
].charAt(1);
44 // Used by the interface:
45 getReservePpath(color
, index
)
47 return color
+ V
.RESERVE_PIECES
[index
];
50 // Ordering on reserve pieces
51 static get RESERVE_PIECES() {
52 return [V
.PAWN
,V
.ROOK
,V
.KNIGHT
,V
.BISHOP
,V
.QUEEN
];
55 getReserveMoves([x
,y
])
57 const color
= this.turn
;
58 const p
= V
.RESERVE_PIECES
[y
];
59 if (this.reserve
[color
][p
] == 0)
62 const pawnShift
= (p
==V
.PAWN
? 1 : 0);
63 for (let i
=pawnShift
; i
<V
.size
.x
-pawnShift
; i
++)
65 for (let j
=0; j
<V
.size
.y
; j
++)
67 if (this.board
[i
][j
] == V
.EMPTY
)
79 start: {x:x
, y:y
}, //a bit artificial...
89 getPotentialMovesFrom([x
,y
])
93 // Reserves, outside of board: x == sizeX(+1)
94 return this.getReserveMoves([x
,y
]);
97 return super.getPotentialMovesFrom([x
,y
]);
102 let moves
= super.getAllValidMoves();
103 const color
= this.turn
;
104 for (let i
=0; i
<V
.RESERVE_PIECES
.length
; i
++)
105 moves
= moves
.concat(this.getReserveMoves([V
.size
.x
+(color
=="w"?0:1),i
]));
106 return this.filterValid(moves
);
111 if (!super.atLeastOneMove())
113 const color
= this.turn
;
114 // Search one reserve move
115 for (let i
=0; i
<V
.RESERVE_PIECES
.length
; i
++)
117 let moves
= this.filterValid(
118 this.getReserveMoves([V
.size
.x
+(this.turn
=="w"?0:1), i
]) );
119 if (moves
.length
> 0)
127 updateVariables(move)
129 super.updateVariables(move);
130 if (move.vanish
.length
== 2 && move.appear
.length
== 2)
131 return; //skip castle
132 const color
= this.turn
;
133 if (move.vanish
.length
== 0)
135 this.reserve
[color
][move.appear
[0].p
]--;
138 move.movePromoted
= this.promoted
[move.start
.x
][move.start
.y
];
139 move.capturePromoted
= this.promoted
[move.end
.x
][move.end
.y
]
140 this.promoted
[move.start
.x
][move.start
.y
] = false;
141 this.promoted
[move.end
.x
][move.end
.y
] = move.movePromoted
142 || (move.vanish
[0].p
== V
.PAWN
&& move.appear
[0].p
!= V
.PAWN
);
143 if (move.capturePromoted
)
144 this.reserve
[color
][V
.PAWN
]++;
145 else if (move.vanish
.length
== 2)
146 this.reserve
[color
][move.vanish
[1].p
]++;
149 unupdateVariables(move)
151 super.unupdateVariables(move);
152 if (move.vanish
.length
== 2 && move.appear
.length
== 2)
154 const color
= this.turn
;
155 if (move.vanish
.length
== 0)
157 this.reserve
[color
][move.appear
[0].p
]++;
160 if (move.movePromoted
)
161 this.promoted
[move.start
.x
][move.start
.y
] = true;
162 this.promoted
[move.end
.x
][move.end
.y
] = move.capturePromoted
;
163 if (move.capturePromoted
)
164 this.reserve
[color
][V
.PAWN
]--;
165 else if (move.vanish
.length
== 2)
166 this.reserve
[color
][move.vanish
[1].p
]--;
169 static get SEARCH_DEPTH() { return 2; } //high branching factor
173 let evaluation
= super.evalPosition();
175 for (let i
=0; i
<V
.RESERVE_PIECES
.length
; i
++)
177 const p
= V
.RESERVE_PIECES
[i
];
178 evaluation
+= this.reserve
["w"][p
] * V
.VALUES
[p
];
179 evaluation
-= this.reserve
["b"][p
] * V
.VALUES
[p
];
186 if (move.vanish
.length
> 0)
187 return super.getNotation(move);
190 (move.appear
[0].p
!= V
.PAWN
? move.appear
[0].p
.toUpperCase() : "");
192 String
.fromCharCode(97 + move.end
.y
) + (V
.size
.x
-move.end
.x
);
193 return piece
+ "@" + finalSquare
;
196 getLongNotation(move)
198 if (move.vanish
.length
> 0)
199 return super.getLongNotation(move);
201 String
.fromCharCode(97 + move.end
.y
) + (V
.size
.x
-move.end
.x
);
202 return "@" + finalSquare
;