1 import { ChessRules
} from "@/base_rules";
3 export class ShatranjRules
extends ChessRules
{
5 static get HasFlags() {
9 static get HasEnpassant() {
13 static get Monochrome() {
17 static get Notoodark() {
21 static get PawnSpecs() {
33 if (b
[1] == 'b') return "Shatranj/" + b
;
37 static get ElephantSteps() {
46 static GenRandInitFen(options
) {
47 // Remove castle flags and en-passant indication
48 return ChessRules
.GenRandInitFen(options
).slice(0, -7);
51 getPotentialBishopMoves(sq
) {
52 let moves
= this.getSlideNJumpMoves(sq
, V
.ElephantSteps
, 1);
53 // Complete with "repositioning moves": like a queen, without capture
54 let repositioningMoves
=
55 this.getSlideNJumpMoves(sq
, V
.steps
[V
.BISHOP
], 1)
56 .filter(m
=> m
.vanish
.length
== 1);
57 return moves
.concat(repositioningMoves
);
60 getPotentialQueenMoves(sq
) {
61 // Diagonal capturing moves
63 this.getSlideNJumpMoves(sq
, V
.steps
[V
.BISHOP
], 1)
64 .filter(m
=> m
.vanish
.length
== 2);
65 return captures
.concat(
66 // Orthogonal non-capturing moves
67 this.getSlideNJumpMoves(sq
, V
.steps
[V
.ROOK
], 1)
68 .filter(m
=> m
.vanish
.length
== 1)
72 isAttackedByBishop(sq
, color
) {
73 return this.isAttackedBySlideNJump(
74 sq
, color
, V
.BISHOP
, V
.ElephantSteps
, 1);
77 isAttackedByQueen(sq
, color
) {
78 return this.isAttackedBySlideNJump(
79 sq
, color
, V
.QUEEN
, V
.steps
[V
.BISHOP
], 1);
83 const color
= this.turn
;
84 const getScoreLost
= () => {
86 return color
== "w" ? "0-1" : "1-0";
88 if (!this.atLeastOneMove())
89 // No valid move: I lose (this includes checkmate)
90 return getScoreLost();
91 // Win if the opponent has no pieces left (except king),
92 // and cannot bare king on the next move.
94 // No need to remember all pieces' squares:
95 // variable only used if just one remaining piece.
96 "w": {count: 0, square: null},
97 "b": {count: 0, square: null}
99 outerLoop: for (let i
=0; i
<V
.size
.x
; i
++) {
100 for (let j
=0; j
<V
.size
.y
; j
++) {
101 if (this.board
[i
][j
] != V
.EMPTY
&& this.getPiece(i
,j
) != V
.KING
) {
102 const sqCol
= this.getColor(i
,j
);
103 piecesLeft
[sqCol
].count
++;
104 piecesLeft
[sqCol
].square
= [i
,j
];
108 if (Object
.values(piecesLeft
).every(v
=> v
.count
> 0))
110 // No pieces left for some side: if both kings are bare, it's a draw
111 if (Object
.values(piecesLeft
).every(v
=> v
.count
== 0))
113 if (piecesLeft
[color
].count
> 0)
114 // He could have drawn, but didn't take my last piece...
115 return color
== "w" ? "1-0" : "0-1";
116 const oppCol
= V
.GetOppCol(color
);
117 if (piecesLeft
[oppCol
].count
>= 2)
118 // 2 enemy units or more: I lose
119 return getScoreLost();
120 // I don't have any piece, my opponent have one: can I take it?
121 if (this.isAttacked(piecesLeft
[oppCol
].square
, color
))
122 // Yes! But I still need to take it
125 return getScoreLost();
128 static get VALUES() {