1 import { ChessRules
, Move
, PiPo
} from "@/base_rules";
2 import { randInt
} from "@/utils/alea";
4 export class KonaneRules
extends ChessRules
{
10 static get HasFlags() {
14 static get HasEnpassant() {
18 static get ReverseColors() {
30 static IsGoodPosition(position
) {
31 if (position
.length
== 0) return false;
32 const rows
= position
.split("/");
33 if (rows
.length
!= V
.size
.x
) return false;
34 for (let row
of rows
) {
36 for (let i
= 0; i
< row
.length
; i
++) {
37 if (row
[i
].toLowerCase() == V
.PAWN
) sumElts
++;
39 const num
= parseInt(row
[i
], 10);
40 if (isNaN(num
) || num
<= 0) return false;
44 if (sumElts
!= V
.size
.y
) return false;
49 static GenRandInitFen() {
51 "PpPpPpPp/pPpPpPpP/PpPpPpPp/pPpPpPpP/" +
52 "PpPpPpPp/pPpPpPpP/PpPpPpPp/pPpPpPpP w 0"
56 hoverHighlight([x
, y
], side
) {
58 if (this.movesCount
>= 2 || (!!side
&& side
!= c
)) return false;
59 if (c
== 'w') return (x
== y
&& [0, 3, 4, 7].includes(x
));
60 // "Black": search for empty square and allow nearby
61 for (let i
of [0, 3, 4, 7]) {
62 if (this.board
[i
][i
] == V
.EMPTY
)
63 return (Math
.abs(x
- i
) + Math
.abs(y
- i
) == 1)
69 this.movesCount
<= 1 ||
70 // TODO: next line theoretically shouldn't be required...
71 (this.movesCount
== 2 && this.getColor(x
, y
) != this.turn
)
76 if (this.movesCount
>= 2) return null;
77 const color
= this.turn
;
79 if (x
!= y
|| ![0, 3, 4, 7].includes(x
)) return null;
82 vanish: [ new PiPo({ x: x
, y: y
, c: color
, p: V
.PAWN
}) ],
86 // "Black": search for empty square and allow nearby
87 for (let i
of [0, 3, 4, 7]) {
88 if (this.board
[i
][i
] == V
.EMPTY
) {
89 if (Math
.abs(x
- i
) + Math
.abs(y
- i
) != 1) return null;
92 vanish: [ new PiPo({ x: x
, y: y
, c: color
, p: V
.PAWN
}) ],
99 getPotentialMovesFrom([x
, y
]) {
100 if (this.movesCount
<= 1) {
101 const mv
= this.doClick([x
, y
]);
102 return (!!mv
? [mv
] : []);
104 const color
= this.turn
;
105 const oppCol
= V
.GetOppCol(color
);
107 for (let s
of V
.steps
[V
.ROOK
]) {
108 let curmv
= new Move({
109 appear: [ new PiPo({ x: -1, y: -1, c: color
, p: V
.PAWN
}) ],
110 vanish: [ new PiPo({ x: x
, y: y
, c: color
, p: V
.PAWN
}) ]
112 for (let mult
= 2; ; mult
+= 2) {
113 let [i
, j
] = [x
+ mult
* s
[0], y
+ mult
* s
[1]];
116 this.board
[i
][j
] == V
.EMPTY
&&
117 this.board
[i
- s
[0]][j
- s
[1]] != V
.EMPTY
&&
118 this.getColor(i
- s
[0], j
- s
[1]) == oppCol
121 new PiPo({ x: i
- s
[0], y: j
- s
[1], c: oppCol
, p: V
.PAWN
}));
122 let mv
= JSON
.parse(JSON
.stringify(curmv
));
125 mv
.end
= { x: i
, y: j
};
143 if (this.atLeastOneMove()) return "*";
144 return (this.turn
== "w" ? "0-1" : "1-0");
147 static get SEARCH_DEPTH() {
152 if (this.movesCount
<= 1) return V
.CoordsToSquare(move.start
) + "X";
153 if (move.vanish
.length
== 0) return "end";
154 return V
.CoordsToSquare(move.start
) + V
.CoordsToSquare(move.end
);