1 import { ChessRules
} from "@/base_rules";
2 import { CoregalRules
} from "@/variants/Coregal";
4 export class TwokingsRules
extends CoregalRules
{
6 static get PawnSpecs() {
10 { promotions: ChessRules
.PawnSpecs
.promotions
.concat([V
.KING
]) }
14 static IsGoodPosition(position
) {
15 if (position
.length
== 0) return false;
16 const rows
= position
.split("/");
17 if (rows
.length
!= V
.size
.x
) return false;
18 let kings
= { 'K': 0, 'k': 0 };
19 for (let row
of rows
) {
21 for (let i
= 0; i
< row
.length
; i
++) {
22 if (['K','k'].includes(row
[i
])) kings
[row
[i
]]++;
23 if (V
.PIECES
.includes(row
[i
].toLowerCase())) sumElts
++;
25 const num
= parseInt(row
[i
], 10);
26 if (isNaN(num
)) return false;
30 if (sumElts
!= V
.size
.y
) return false;
32 // Two kings (at least) per side should be present:
33 if (Object
.values(kings
).some(v
=> v
< 2)) return false;
37 // Not scanning king positions. In this variant, scan the board everytime.
41 const color
= this.turn
;
43 const oppCol
= V
.GetOppCol(color
);
44 for (let i
=0; i
<V
.size
.x
; i
++) {
45 for (let j
=0; j
<V
.size
.y
; j
++) {
47 this.getColor(i
, j
) == color
&&
48 this.getPiece(i
, j
) == V
.KING
&&
49 this.isAttacked([i
, j
], oppCol
)
58 static GenRandInitFen(options
) {
59 if (options
.randomness
== 0)
60 return "rnqkkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNQKKBNR w 0 adehadeh -";
62 const replaceBishop
= (fen
, first
, ch1
, ch2
) => {
63 // Remove and re-add final part:
64 const suffix
= fen
.substr(-15);
65 fen
= fen
.slice(0, -15);
66 if (first
) fen
= fen
.replace(ch1
, ch2
);
69 fen
.split("").reverse().join("")
71 .split("").reverse().join("")
76 const sameIndexReplace
= (fen
) => {
77 const first
= (Math
.random() < 0.5);
79 replaceBishop(fen
, first
, 'B', 'Q'),
87 CoregalRules
.GenRandInitFen(options
)
88 .replace("q", "k").replace("Q", "K");
89 // Now replace a bishop by the queen,
90 // so that bishops are of different colors:
91 if (randomness
== 1) return sameIndexReplace(fen
);
92 const wOdd
= fen
.indexOf('B') % 2;
93 const bOdd
= fen
.indexOf('b') % 2;
94 // Since there are 7 slashes, different oddities means symmetric
95 if (wOdd
!= bOdd
) return sameIndexReplace(fen
);
96 const wFirst
= (Math
.random() < 0.5);
98 replaceBishop(fen
, wFirst
, 'B', 'Q'),
105 getPotentialQueenMoves(sq
) {
106 return this.getSlideNJumpMoves(sq
,
107 V
.steps
[V
.ROOK
].concat(V
.steps
[V
.BISHOP
]));
111 const oppCol
= V
.GetOppCol(color
);
112 for (let i
=0; i
<V
.size
.x
; i
++) {
113 for (let j
=0; j
<V
.size
.y
; j
++) {
115 this.getColor(i
, j
) == color
&&
116 this.getPiece(i
, j
) == V
.KING
&&
117 this.isAttacked([i
, j
], oppCol
)
127 const piece
= move.vanish
[0].p
;
128 super.updateCastleFlags(move, piece
, "twoKings");