1 import { ChessRules
, PiPo
, Move
} from "@/base_rules";
2 import { ShogiRules
} from "@/variants/Shogi"
4 export class MinishogiRules
extends ShogiRules
{
6 static IsGoodFen(fen
) {
7 if (!ChessRules
.IsGoodFen(fen
)) return false;
8 const fenParsed
= V
.ParseFen(fen
);
10 if (!fenParsed
.reserve
|| !fenParsed
.reserve
.match(/^[0-9]{10,10}$/))
31 static GenRandInitFen() {
32 return "rbsgk/4p/5/P4/KGSBR w 0 0000000000";
36 let counts
= new Array(10);
37 for (let i
= 0; i
< V
.RESERVE_PIECES
.length
; i
++) {
38 counts
[i
] = this.reserve
["w"][V
.RESERVE_PIECES
[i
]];
39 counts
[5 + i
] = this.reserve
["b"][V
.RESERVE_PIECES
[i
]];
41 return counts
.join("");
44 setOtherVariables(fen
) {
45 super.setOtherVariables(fen
);
46 // Also init reserves (used by the interface to show landable pieces)
48 V
.ParseFen(fen
).reserve
.split("").map(x
=> parseInt(x
, 10));
53 [V
.BISHOP
]: reserve
[2],
54 [V
.GOLD_G
]: reserve
[3],
55 [V
.SILVER_G
]: reserve
[4]
60 [V
.BISHOP
]: reserve
[7],
61 [V
.GOLD_G
]: reserve
[8],
62 [V
.SILVER_G
]: reserve
[9]
68 return { x: 5, y: 5 };
71 static get RESERVE_PIECES() {
73 [V
.PAWN
, V
.ROOK
, V
.BISHOP
, V
.GOLD_G
, V
.SILVER_G
]
77 getReserveMoves([x
, y
]) {
78 const color
= this.turn
;
79 const p
= V
.RESERVE_PIECES
[y
];
81 var oppCol
= V
.GetOppCol(color
);
83 [...Array(5).keys()].filter(j
=>
84 [...Array(5).keys()].every(i
=> {
86 this.board
[i
][j
] == V
.EMPTY
||
87 this.getColor(i
, j
) != color
||
88 this.getPiece(i
, j
) != V
.PAWN
93 if (this.reserve
[color
][p
] == 0) return [];
95 const forward
= color
== 'w' ? -1 : 1;
96 const lastRank
= color
== 'w' ? 0 : 4;
97 for (let i
= 0; i
< V
.size
.x
; i
++) {
98 if (p
== V
.PAWN
&& i
== lastRank
) continue;
99 for (let j
= 0; j
< V
.size
.y
; j
++) {
101 this.board
[i
][j
] == V
.EMPTY
&&
102 (p
!= V
.PAWN
|| allowedFiles
.includes(j
))
114 start: { x: x
, y: y
}, //a bit artificial...
118 // Do not drop on checkmate:
120 const res
= (this.underCheck(oppCol
) && !this.atLeastOneMove());
131 getSlideNJumpMoves_opt([x
, y
], steps
, options
) {
132 options
= options
|| {};
133 const color
= this.turn
;
134 const oneStep
= options
.oneStep
;
135 const forcePromoteOnLastRank
= options
.force
;
136 const promoteInto
= options
.promote
;
137 const lastRank
= (color
== 'w' ? 0 : 4);
139 outerLoop: for (let step
of steps
) {
142 while (V
.OnBoard(i
, j
) && this.board
[i
][j
] == V
.EMPTY
) {
143 if (i
!= lastRank
|| !forcePromoteOnLastRank
)
144 moves
.push(this.getBasicMove([x
, y
], [i
, j
]));
145 if (i
== lastRank
&& !!promoteInto
) {
148 [x
, y
], [i
, j
], { c: color
, p: promoteInto
})
151 if (oneStep
) continue outerLoop
;
155 if (V
.OnBoard(i
, j
) && this.canTake([x
, y
], [i
, j
])) {
156 if (i
!= lastRank
|| !forcePromoteOnLastRank
)
157 moves
.push(this.getBasicMove([x
, y
], [i
, j
]));
158 if (i
== lastRank
&& !!promoteInto
) {
161 [x
, y
], [i
, j
], { c: color
, p: promoteInto
})
169 static get SEARCH_DEPTH() {