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 // Also init reserves (used by the interface to show landable pieces)
47 V
.ParseFen(fen
).reserve
.split("").map(x
=> parseInt(x
, 10));
52 [V
.BISHOP
]: reserve
[2],
53 [V
.GOLD_G
]: reserve
[3],
54 [V
.SILVER_G
]: reserve
[4]
59 [V
.BISHOP
]: reserve
[7],
60 [V
.GOLD_G
]: reserve
[8],
61 [V
.SILVER_G
]: reserve
[9]
67 return { x: 5, y: 5 };
70 static get RESERVE_PIECES() {
72 [V
.PAWN
, V
.ROOK
, V
.BISHOP
, V
.GOLD_G
, V
.SILVER_G
]
76 getReserveMoves([x
, y
]) {
77 const color
= this.turn
;
78 const p
= V
.RESERVE_PIECES
[y
];
80 var oppCol
= V
.GetOppCol(color
);
82 [...Array(5).keys()].filter(j
=>
83 [...Array(5).keys()].every(i
=> {
85 this.board
[i
][j
] == V
.EMPTY
||
86 this.getColor(i
, j
) != color
||
87 this.getPiece(i
, j
) != V
.PAWN
92 if (this.reserve
[color
][p
] == 0) return [];
94 const forward
= color
== 'w' ? -1 : 1;
95 const lastRank
= color
== 'w' ? 0 : 4;
96 for (let i
= 0; i
< V
.size
.x
; i
++) {
97 if (p
== V
.PAWN
&& i
== lastRank
) continue;
98 for (let j
= 0; j
< V
.size
.y
; j
++) {
100 this.board
[i
][j
] == V
.EMPTY
&&
101 (p
!= V
.PAWN
|| allowedFiles
.includes(j
))
113 start: { x: x
, y: y
}, //a bit artificial...
117 // Do not drop on checkmate:
119 const res
= (this.underCheck(oppCol
) && !this.atLeastOneMove());
130 getSlideNJumpMoves([x
, y
], steps
, options
) {
131 options
= options
|| {};
132 const color
= this.turn
;
133 const oneStep
= options
.oneStep
;
134 const forcePromoteOnLastRank
= options
.force
;
135 const promoteInto
= options
.promote
;
136 const lastRank
= (color
== 'w' ? 0 : 4);
138 outerLoop: for (let step
of steps
) {
141 while (V
.OnBoard(i
, j
) && this.board
[i
][j
] == V
.EMPTY
) {
142 if (i
!= lastRank
|| !forcePromoteOnLastRank
)
143 moves
.push(this.getBasicMove([x
, y
], [i
, j
]));
144 if (i
== lastRank
&& !!promoteInto
) {
147 [x
, y
], [i
, j
], { c: color
, p: promoteInto
})
150 if (oneStep
) continue outerLoop
;
154 if (V
.OnBoard(i
, j
) && this.canTake([x
, y
], [i
, j
])) {
155 if (i
!= lastRank
|| !forcePromoteOnLastRank
)
156 moves
.push(this.getBasicMove([x
, y
], [i
, j
]));
157 if (i
== lastRank
&& !!promoteInto
) {
160 [x
, y
], [i
, j
], { c: color
, p: promoteInto
})
168 static get SEARCH_DEPTH() {