1 import { ChessRules
, Move
, PiPo
} from "@/base_rules";
2 import { randInt
} from "@/utils/alea";
4 export class KonaneRules
extends ChessRules
{
6 static get HasFlags() {
10 static get HasEnpassant() {
14 static get ReverseColors() {
26 static IsGoodPosition(position
) {
27 if (position
.length
== 0) return false;
28 const rows
= position
.split("/");
29 if (rows
.length
!= V
.size
.x
) return false;
30 for (let row
of rows
) {
32 for (let i
= 0; i
< row
.length
; i
++) {
33 if (row
[i
].toLowerCase() == V
.PAWN
) sumElts
++;
35 const num
= parseInt(row
[i
], 10);
36 if (isNaN(num
) || num
<= 0) return false;
40 if (sumElts
!= V
.size
.y
) return false;
45 static GenRandInitFen() {
47 "PpPpPpPp/pPpPpPpP/PpPpPpPp/pPpPpPpP/" +
48 "PpPpPpPp/pPpPpPpP/PpPpPpPp/pPpPpPpP w 0"
52 hoverHighlight([x
, y
], side
) {
54 if (this.movesCount
>= 2 || (!!side
&& side
!= c
)) return false;
55 if (c
== 'w') return (x
== y
&& [0, 3, 4, 7].includes(x
));
56 // "Black": search for empty square and allow nearby
57 for (let i
of [0, 3, 4, 7]) {
58 if (this.board
[i
][i
] == V
.EMPTY
)
59 return (Math
.abs(x
- i
) + Math
.abs(y
- i
) == 1)
65 this.movesCount
<= 1 ||
66 // TODO: next line theoretically shouldn't be required...
67 (this.movesCount
== 2 && this.getColor(x
, y
) != this.turn
)
72 if (this.movesCount
>= 2) return null;
73 const color
= this.turn
;
75 if (x
!= y
|| ![0, 3, 4, 7].includes(x
)) return null;
78 vanish: [ new PiPo({ x: x
, y: y
, c: color
, p: V
.PAWN
}) ],
82 // "Black": search for empty square and allow nearby
83 for (let i
of [0, 3, 4, 7]) {
84 if (this.board
[i
][i
] == V
.EMPTY
) {
85 if (Math
.abs(x
- i
) + Math
.abs(y
- i
) != 1) return null;
88 vanish: [ new PiPo({ x: x
, y: y
, c: color
, p: V
.PAWN
}) ],
95 getPotentialMovesFrom([x
, y
]) {
96 if (this.movesCount
<= 1) {
97 const mv
= this.doClick([x
, y
]);
98 return (!!mv
? [mv
] : []);
100 const color
= this.turn
;
101 const oppCol
= V
.GetOppCol(color
);
103 for (let s
of V
.steps
[V
.ROOK
]) {
104 let curmv
= new Move({
105 appear: [ new PiPo({ x: -1, y: -1, c: color
, p: V
.PAWN
}) ],
106 vanish: [ new PiPo({ x: x
, y: y
, c: color
, p: V
.PAWN
}) ]
108 for (let mult
= 2; ; mult
+= 2) {
109 let [i
, j
] = [x
+ mult
* s
[0], y
+ mult
* s
[1]];
112 this.board
[i
][j
] == V
.EMPTY
&&
113 this.board
[i
- s
[0]][j
- s
[1]] != V
.EMPTY
&&
114 this.getColor(i
- s
[0], j
- s
[1]) == oppCol
117 new PiPo({ x: i
- s
[0], y: j
- s
[1], c: oppCol
, p: V
.PAWN
}));
118 let mv
= JSON
.parse(JSON
.stringify(curmv
));
121 mv
.end
= { x: i
, y: j
};
139 if (this.atLeastOneMove()) return "*";
140 return (this.turn
== "w" ? "0-1" : "1-0");
143 static get SEARCH_DEPTH() {
148 if (this.movesCount
<= 1) return V
.CoordsToSquare(move.start
) + "X";
149 if (move.vanish
.length
== 0) return "end";
150 return V
.CoordsToSquare(move.start
) + V
.CoordsToSquare(move.end
);