我正在为一个个人项目(用 Java)开发国际象棋机器人,对于我的一生,我无法弄清楚如何查看棋子是否可以阻止检查。这是设置:
Board:包含一个二维方块数组、棋盘上的所有方块以及所有棋子。所有这些字段都是静态的,所以我不必创建 80 个 getter。还包含这些 ArrayLists:白棋的合法棋子、黑棋的合法棋子、白棋的所有棋子、黑棋的所有棋子、白棋的所有棋子和黑棋的所有棋子。
Square:容纳碎片。
Piece(及其子类):有两个 ArrayLists:moveset(它可以从当前位置移动到空板上的所有方块,这就是我要处理引脚的方式)和 seen 方块(所有它可以移动到的方块而不会碰到它自己颜色的一块)。 King 有一个布尔值 inCheck 字段。
Move:拿一个棋子和一个方块,有一个 play() 方法来处理实际移动棋子的逻辑,设置方块的新棋子等
Logic:棋盘的 vision() 方法在每次移动后都会被调用。这会更新所有棋子的移动集和可见方块,并设置国王的 inCheck 字段。然后它将所有可能的移动添加到所有移动 ArrayLists。然后它应该将所有合法移动(考虑检查)添加到合法移动 ArrayLists.
支票会计是我遇到麻烦的地方。的第一部分很简单:遍历白棋的所有着法,如果王被将下,王就可以下棋,所以将其添加到合法列表中。所有阻止检查的移动也将被添加(除非该部分被固定),并且在国王离开检查之前其他一切都是非法的。
但是我如何查看一块是否可以阻止支票?这是我真正开始研究机器人逻辑之前必须做的最后一件事,这是我真正兴奋的部分。
我试过:
-查看白方棋子中的一个是否与检查的棋子看到相同的正方形(我认为这是正确的方法,我只是不知道该怎么做)。
-我做了一个方法,它返回一个 ArrayList 的支票,但也没有任何结果。
感谢您阅读本文!我知道这是一本小说,哈哈,我只是想确保我提供了所有相关信息。
这里是视觉方法和获取检查件的方法:
public static void vision() {
//updateBoardVision is an overridden method in all of the
//Piece subclasses. It reevaluates all theoretically possible moves
//from the current square and all the squares it can move to
for (Piece p : whitePieces) {
p.updateBoardVision();
}
for (Piece p : blackPieces) {
p.updateBoardVision();
}
//if a white piece can see the square the black king is on,
//the black king is in check
for (Piece p : whitePieces) {
if (p.seenSquares.contains(Board.bK.square)) {
Board.bK.setInCheck(true);
}
}
//and vice versa
for (Piece p : blackPieces) {
if (p.seenSquares.contains(Board.wK.square)) {
Board.wK.setInCheck(true);
}
}
//all possible moves, discounting checks
for (Piece p : whitePieces) {
for (Square s : p.seenSquares) {
Move m = new Move(p, s);
allWhiteMoves.add(m);
}
}
for (Piece p : blackPieces) {
for (Square s : p.seenSquares) {
Move m = new Move(p, s);
allBlackMoves.add(m);
}
}
//set every move to invalid
for (Move wm : allWhiteMoves) {
wm.setValid(false);
}
for (Move bm : allBlackMoves) {
bm.setValid(false);
}
for (Move aWhiteMove : allWhiteMoves) {
//if the king is in check
if (wK.isInCheck()) {
//then we can move it
if (aWhiteMove.getPiece().equals(wK)) {
aWhiteMove.setValid(true);
}
//if there is a white piece, in white moves, that
//sees the same square as a checking piece, it can
//block the check so it's valid,
//but I also need to account for double checks.
//and then i need to do the same for black
//this whole part is where I'm confused
}
}
//after that i'll add all of the legal moves
for (Move r : allWhiteMoves) {
if (r.isValid()) {
whiteLegalMoves.add(r);
}
}
for (Move s : allBlackMoves) {
if (s.isValid()) {
blackLegalMoves.add(s);
}
}
}
//this is where i see what piece(s) is/are giving the check
//it's an arraylist not a piece to account for multiple
//pieces giving a check at the same time
public static ArrayList<Piece> findCheckPieceWhite() {
ArrayList<Piece> checkPieces = new ArrayList();
for (Piece p : blackPieces) {
if (p.seenSquares.contains(wK.square)) {
checkPieces.add(p);
}
}
return checkPieces;
}
public static ArrayList<Piece> findCheckPieceBlack() {
ArrayList<Piece> checkPieces = new ArrayList();
for (Piece p : whitePieces) {
if (p.seenSquares.contains(bK.square)) {
checkPieces.add(p);
}
}
return checkPieces;
}
您需要确定图形可以移动到的所有字段。 如果其中一个敌人人物可以移动到您国王的领域,则检查处于活动状态(您有
seenSquares()
)。
接下来了解需要阻止哪些字段以防止这种情况。此列表取决于启动检查的图形的位置和类型。这包括那个人物的领域(一匹马只有那个领域才能取消支票)。
接下来检查,你的哪些数字可以访问这样的字段。从这些经过评估的动作中选择最合适的。 不要忘记比较将您的国王也从检查状态中移出。
但这一切都是算法,与java无关。