610dd2574ddf6249d14d5932410fe73b1c30f713
1 import { ChessRules
} from "@/base_rules";
2 import { ArrayFun
} from "@/utils/array";
3 import { randInt
} from "@/utils/alea";
5 export const VariantRules
= class AntikingRules
extends ChessRules
9 return b
[1]=='a' ? "Antiking/"+b : b
;
12 static get ANTIKING() { return 'a'; }
16 return ChessRules
.PIECES
.concat([V
.ANTIKING
]);
19 setOtherVariables(fen
)
21 super.setOtherVariables(fen
);
22 this.antikingPos
= {'w':[-1,-1], 'b':[-1,-1]};
23 const rows
= V
.ParseFen(fen
).position
.split("/");
24 for (let i
=0; i
<rows
.length
; i
++)
27 for (let j
=0; j
<rows
[i
].length
; j
++)
29 switch (rows
[i
].charAt(j
))
32 this.antikingPos
['b'] = [i
,k
];
35 this.antikingPos
['w'] = [i
,k
];
38 const num
= parseInt(rows
[i
].charAt(j
));
47 canTake([x1
,y1
], [x2
,y2
])
49 const piece1
= this.getPiece(x1
,y1
);
50 const piece2
= this.getPiece(x2
,y2
);
51 const color1
= this.getColor(x1
,y1
);
52 const color2
= this.getColor(x2
,y2
);
53 return piece2
!= "a" &&
54 ((piece1
!= "a" && color1
!= color2
) || (piece1
== "a" && color1
== color2
));
57 getPotentialMovesFrom([x
,y
])
59 switch (this.getPiece(x
,y
))
62 return this.getPotentialAntikingMoves([x
,y
]);
64 return super.getPotentialMovesFrom([x
,y
]);
68 getPotentialAntikingMoves(sq
)
70 return this.getSlideNJumpMoves(sq
,
71 V
.steps
[V
.ROOK
].concat(V
.steps
[V
.BISHOP
]), "oneStep");
74 isAttacked(sq
, colors
)
76 return (super.isAttacked(sq
, colors
) || this.isAttackedByAntiking(sq
, colors
));
79 isAttackedByKing([x
,y
], colors
)
81 if (this.getPiece(x
,y
) == V
.ANTIKING
)
82 return false; //antiking is not attacked by king
83 return this.isAttackedBySlideNJump([x
,y
], colors
, V
.KING
,
84 V
.steps
[V
.ROOK
].concat(V
.steps
[V
.BISHOP
]), "oneStep");
87 isAttackedByAntiking([x
,y
], colors
)
89 if ([V
.KING
,V
.ANTIKING
].includes(this.getPiece(x
,y
)))
90 return false; //(anti)king is not attacked by antiking
91 return this.isAttackedBySlideNJump([x
,y
], colors
, V
.ANTIKING
,
92 V
.steps
[V
.ROOK
].concat(V
.steps
[V
.BISHOP
]), "oneStep");
97 const oppCol
= V
.GetOppCol(color
);
98 let res
= this.isAttacked(this.kingPos
[color
], [oppCol
])
99 || !this.isAttacked(this.antikingPos
[color
], [oppCol
]);
103 getCheckSquares(color
)
105 let res
= super.getCheckSquares(color
);
106 if (!this.isAttacked(this.antikingPos
[color
], [V
.GetOppCol(color
)]))
107 res
.push(JSON
.parse(JSON
.stringify(this.antikingPos
[color
])));
111 updateVariables(move)
113 super.updateVariables(move);
114 const piece
= move.vanish
[0].p
;
115 const c
= move.vanish
[0].c
;
116 // Update antiking position
117 if (piece
== V
.ANTIKING
)
119 this.antikingPos
[c
][0] = move.appear
[0].x
;
120 this.antikingPos
[c
][1] = move.appear
[0].y
;
124 unupdateVariables(move)
126 super.unupdateVariables(move);
127 const c
= move.vanish
[0].c
;
128 if (move.vanish
[0].p
== V
.ANTIKING
)
129 this.antikingPos
[c
] = [move.start
.x
, move.start
.y
];
134 if (this.atLeastOneMove()) // game not over
137 const color
= this.turn
;
138 const oppCol
= V
.GetOppCol(color
);
139 if (!this.isAttacked(this.kingPos
[color
], [oppCol
])
140 && this.isAttacked(this.antikingPos
[color
], [oppCol
]))
144 return color
== "w" ? "0-1" : "1-0";
147 static get VALUES() {
148 return Object
.assign(
154 static GenRandInitFen()
156 let pieces
= { "w": new Array(8), "b": new Array(8) };
157 let antikingPos
= { "w": -1, "b": -1 };
158 for (let c
of ["w","b"])
160 let positions
= ArrayFun
.range(8);
162 // Get random squares for bishops, but avoid corners; because,
163 // if an antiking blocks a cornered bishop, it can never be checkmated
164 let randIndex
= 2 * randInt(1,4);
165 const bishop1Pos
= positions
[randIndex
];
166 let randIndex_tmp
= 2 * randInt(3) + 1;
167 const bishop2Pos
= positions
[randIndex_tmp
];
168 positions
.splice(Math
.max(randIndex
,randIndex_tmp
), 1);
169 positions
.splice(Math
.min(randIndex
,randIndex_tmp
), 1);
171 randIndex
= randInt(6);
172 const knight1Pos
= positions
[randIndex
];
173 positions
.splice(randIndex
, 1);
174 randIndex
= randInt(5);
175 const knight2Pos
= positions
[randIndex
];
176 positions
.splice(randIndex
, 1);
178 randIndex
= randInt(4);
179 const queenPos
= positions
[randIndex
];
180 positions
.splice(randIndex
, 1);
182 const rook1Pos
= positions
[0];
183 const kingPos
= positions
[1];
184 const rook2Pos
= positions
[2];
186 // Random squares for antikings
187 antikingPos
[c
] = randInt(8);
189 pieces
[c
][rook1Pos
] = 'r';
190 pieces
[c
][knight1Pos
] = 'n';
191 pieces
[c
][bishop1Pos
] = 'b';
192 pieces
[c
][queenPos
] = 'q';
193 pieces
[c
][kingPos
] = 'k';
194 pieces
[c
][bishop2Pos
] = 'b';
195 pieces
[c
][knight2Pos
] = 'n';
196 pieces
[c
][rook2Pos
] = 'r';
198 const ranks23_black
= "pppppppp/" + (antikingPos
["w"]>0?antikingPos
["w"]:"")
199 + "A" + (antikingPos
["w"]<7?7-antikingPos
["w"]:"");
200 const ranks23_white
= (antikingPos
["b"]>0?antikingPos
["b"]:"") + "a"
201 + (antikingPos
["b"]<7?7-antikingPos
["b"]:"") + "/PPPPPPPP";
202 return pieces
["b"].join("") + "/" + ranks23_black
+
204 ranks23_white
+ "/" + pieces
["w"].join("").toUpperCase() +