1 import { ChessRules
, PiPo
, Move
} from "@/base_rules";
2 import { ShogiRules
} from "@/variants/Shogi";
4 export class MinishogiRules
extends ShogiRules
{
5 static IsGoodFen(fen
) {
6 if (!ChessRules
.IsGoodFen(fen
)) return false;
7 const fenParsed
= V
.ParseFen(fen
);
9 if (!fenParsed
.reserve
|| !fenParsed
.reserve
.match(/^[0-9]{10,10}$/))
30 static GenRandInitFen() {
31 return "rbsgk/4p/5/P4/KGSBR w 0 0000000000";
35 let counts
= new Array(10);
36 for (let i
= 0; i
< V
.RESERVE_PIECES
.length
; i
++) {
37 counts
[i
] = this.reserve
["w"][V
.RESERVE_PIECES
[i
]];
38 counts
[5 + i
] = this.reserve
["b"][V
.RESERVE_PIECES
[i
]];
40 return counts
.join("");
43 setOtherVariables(fen
) {
44 super.setOtherVariables(fen
);
45 const fenParsed
= V
.ParseFen(fen
);
46 // Also init reserves (used by the interface to show landable pieces)
49 [V
.PAWN
]: parseInt(fenParsed
.reserve
[0]),
50 [V
.ROOK
]: parseInt(fenParsed
.reserve
[1]),
51 [V
.BISHOP
]: parseInt(fenParsed
.reserve
[2]),
52 [V
.GOLD_G
]: parseInt(fenParsed
.reserve
[3]),
53 [V
.SILVER_G
]: parseInt(fenParsed
.reserve
[4])
56 [V
.PAWN
]: parseInt(fenParsed
.reserve
[5]),
57 [V
.ROOK
]: parseInt(fenParsed
.reserve
[6]),
58 [V
.BISHOP
]: parseInt(fenParsed
.reserve
[7]),
59 [V
.GOLD_G
]: parseInt(fenParsed
.reserve
[8]),
60 [V
.SILVER_G
]: parseInt(fenParsed
.reserve
[9])
66 return { x: 5, y: 5 };
69 static get RESERVE_PIECES() {
71 [V
.PAWN
, V
.ROOK
, V
.BISHOP
, V
.GOLD_G
, V
.SILVER_G
]
75 getReserveMoves([x
, y
]) {
76 const color
= this.turn
;
77 const p
= V
.RESERVE_PIECES
[y
];
79 var oppCol
= V
.GetOppCol(color
);
81 [...Array(5).keys()].filter(j
=>
82 [...Array(5).keys()].every(i
=> {
84 this.board
[i
][j
] == V
.EMPTY
||
85 this.getColor(i
, j
) != color
||
86 this.getPiece(i
, j
) != V
.PAWN
91 if (this.reserve
[color
][p
] == 0) return [];
93 const forward
= color
== 'w' ? -1 : 1;
94 const lastRank
= color
== 'w' ? 0 : 4;
95 for (let i
= 0; i
< V
.size
.x
; i
++) {
96 if (p
== V
.PAWN
&& i
== lastRank
) continue;
97 for (let j
= 0; j
< V
.size
.y
; j
++) {
99 this.board
[i
][j
] == V
.EMPTY
&&
100 (p
!= V
.PAWN
|| allowedFiles
.includes(j
))
112 start: { x: x
, y: y
}, //a bit artificial...
116 // Do not drop on checkmate:
118 const res
= (this.underCheck(oppCol
) && !this.atLeastOneMove());
129 getSlideNJumpMoves([x
, y
], steps
, options
) {
130 options
= options
|| {};
131 const color
= this.turn
;
132 const oneStep
= options
.oneStep
;
133 const forcePromoteOnLastRank
= options
.force
;
134 const promoteInto
= options
.promote
;
135 const lastRank
= (color
== 'w' ? 0 : 4);
137 outerLoop: for (let step
of steps
) {
140 while (V
.OnBoard(i
, j
) && this.board
[i
][j
] == V
.EMPTY
) {
141 if (i
!= lastRank
|| !forcePromoteOnLastRank
)
142 moves
.push(this.getBasicMove([x
, y
], [i
, j
]));
143 if (i
== lastRank
&& !!promoteInto
) {
146 [x
, y
], [i
, j
], { c: color
, p: promoteInto
})
149 if (oneStep
) continue outerLoop
;
153 if (V
.OnBoard(i
, j
) && this.canTake([x
, y
], [i
, j
])) {
154 if (i
!= lastRank
|| !forcePromoteOnLastRank
)
155 moves
.push(this.getBasicMove([x
, y
], [i
, j
]));
156 if (i
== lastRank
&& !!promoteInto
) {
159 [x
, y
], [i
, j
], { c: color
, p: promoteInto
})
167 static get SEARCH_DEPTH() {