1 import { ChessRules
, PiPo
, Move
} from "@/base_rules";
2 import { ArrayFun
} from "@/utils/array";
4 export default class ClorangeRules
extends ChessRules
{
12 static GenRandInitFen(options
) {
13 // Capturing and non-capturing reserves:
14 return ChessRules
.GenRandInitFen(options
) + " 00000000000000000000";
18 return super.getFen() + " " + this.getReserveFen();
22 return super.getFenForRepeat() + "_" + this.getReserveFen();
27 Object
.keys(this.reserve
).map(
28 c
=> Object
.values(this.reserve
[c
]).join("")).join("")
32 getEpSquare(moveOrSquare
) {
33 if (!moveOrSquare
) return undefined;
34 if (typeof moveOrSquare
=== "string") {
35 const square
= moveOrSquare
;
36 if (square
== "-") return undefined;
37 return V
.SquareToCoords(square
);
39 const move = moveOrSquare
;
44 Math
.abs(s
.x
- e
.x
) == 2 &&
45 move.vanish
.length
> 0 && ['p', 's'].includes(move.vanish
[0].p
)
55 setOtherVariables(fen
) {
56 super.setOtherVariables(fen
);
57 // Also init reserves (used by the interface to show landable pieces)
59 V
.ParseFen(fen
).reserve
.split("").map(x
=> parseInt(x
, 10));
89 if (i
>= V
.size
.x
) return i
== V
.size
.x
? "w" : "b";
90 return this.board
[i
][j
].charAt(0);
94 if (i
>= V
.size
.x
) return V
.RESERVE_PIECES
[j
];
95 return this.board
[i
][j
].charAt(1);
99 return (V
.NON_VIOLENT
.includes(b
[1]) ? "Clorange/" : "") + b
;
102 getReservePpath(index
, color
) {
104 (V
.NON_VIOLENT
.includes(V
.RESERVE_PIECES
[index
]) ? "Clorange/" : "");
105 return prefix
+ color
+ V
.RESERVE_PIECES
[index
];
108 static get NON_VIOLENT() {
109 return ['s', 'u', 'o', 'c', 't'];
112 static get PIECES() {
113 return ChessRules
.PIECES
.concat(V
.NON_VIOLENT
);
116 // Ordering on reserve pieces
117 static get RESERVE_PIECES() {
118 return V
.PIECES
.filter(p
=> p
!= 'k');
121 getReserveMoves([x
, y
]) {
122 const color
= this.turn
;
123 const p
= V
.RESERVE_PIECES
[y
];
124 if (this.reserve
[color
][p
] == 0) return [];
127 let rank2
= V
.size
.x
- 1;
128 if (['p', 's'].includes(p
)) {
129 if (color
== 'w') rank1
++;
132 for (let i
= rank1
; i
<= rank2
; i
++) {
133 for (let j
= 0; j
< V
.size
.y
; j
++) {
134 if (this.board
[i
][j
] == V
.EMPTY
) {
145 start: { x: x
, y: y
}, //a bit artificial...
155 getPotentialMovesFrom([x
, y
]) {
157 // Reserves, outside of board: x == sizeX(+1)
158 return this.getReserveMoves([x
, y
]);
160 switch (this.getPiece(x
, y
)) {
161 case 's': return this.getPotentialPawnMoves([x
, y
]);
162 case 'u': return super.getPotentialRookMoves([x
, y
]);
163 case 'o': return super.getPotentialKnightMoves([x
, y
]);
164 case 'c': return super.getPotentialBishopMoves([x
, y
]);
165 case 't': return super.getPotentialQueenMoves([x
, y
]);
166 default: return super.getPotentialMovesFrom([x
, y
]);
168 return []; //never reached
171 getPotentialPawnMoves(sq
) {
172 let moves
= super.getPotentialPawnMoves(sq
);
173 if (moves
.length
> 0 && moves
[0].vanish
[0].p
== 's') {
174 // Remove captures for non-violent pawns:
175 moves
= moves
.filter(m
=> m
.vanish
.length
== 1);
177 if (m
.appear
[0].p
!= 's') {
178 // Promotion pieces should be non-violent as well:
179 const pIdx
= ChessRules
.PIECES
.findIndex(p
=> p
== m
.appear
[0].p
)
180 m
.appear
[0].p
= V
.NON_VIOLENT
[pIdx
];
187 canTake([x1
, y1
], [x2
, y2
]) {
189 this.getColor(x1
, y1
) !== this.getColor(x2
, y2
) &&
190 ChessRules
.PIECES
.includes(this.getPiece(x1
, y1
))
195 let moves
= super.getAllPotentialMoves();
196 const color
= this.turn
;
197 for (let i
= 0; i
< V
.RESERVE_PIECES
.length
; i
++) {
198 moves
= moves
.concat(
199 this.getReserveMoves([V
.size
.x
+ (color
== "w" ? 0 : 1), i
])
202 return this.filterValid(moves
);
206 if (!super.atLeastOneMove()) {
207 // Search one reserve move
208 for (let i
= 0; i
< V
.RESERVE_PIECES
.length
; i
++) {
209 let moves
= this.filterValid(
210 this.getReserveMoves([V
.size
.x
+ (this.turn
== "w" ? 0 : 1), i
])
212 if (moves
.length
> 0) return true;
222 if (move.vanish
.length
== 2 && move.appear
.length
== 2) return;
223 const color
= this.turn
;
224 if (move.vanish
.length
== 0) this.reserve
[color
][move.appear
[0].p
]--;
225 else if (move.vanish
.length
== 2) {
227 const normal
= ChessRules
.PIECES
.includes(move.vanish
[1].p
);
230 ? ChessRules
.PIECES
.findIndex(p
=> p
== move.vanish
[1].p
)
231 : V
.NON_VIOLENT
.findIndex(p
=> p
== move.vanish
[1].p
);
232 const rPiece
= (normal
? V
.NON_VIOLENT : ChessRules
.PIECES
)[pIdx
];
233 this.reserve
[move.vanish
[1].c
][rPiece
]++;