Chess piece legal moves
Answer a question
I made a chess game with vue.js, and right now I am trying to figure out the possible moves of each piece. I was able to fix legal moves validation for knight, pawn and bishop.
While working with bishop validation, I meet a problem. It is to be able to validate, if there is a piece that stand before bishop.
Please see the image to understand more.

You see how the red figures goes over pawn and continue up. It is supposed to stop at pawn figure.
Here is my code for bishop calculation. And if it is possible, if you could also provide validation for the queen and the other pieces would be really helpful.
var el = { };
// sample Data
el.whiteMoves = [{"x":1,"y":1,"type":"Rook1","name":"1A","cleanType":"rook"},{"x":8,"y":1,"type":"Rook2","name":"1H","cleanType":"rook"},{"x":2,"y":1,"type":"Knight1","name":"1B","cleanType":"knight"},{"x":7,"y":1,"type":"Knight2","name":"1G","cleanType":"knight"},{"x":3,"y":1,"type":"Bishop1","name":"1C","cleanType":"bishop"},{"x":6,"y":1,"type":"Bishop2","name":"1F","cleanType":"bishop"},{"x":4,"y":1,"type":"Queen","name":"1D","cleanType":"queen"},{"x":5,"y":1,"type":"King","name":"1E","cleanType":"king"},{"x":1,"y":2,"type":"Pawn1","name":"2A","cleanType":"pawn"},{"x":2,"y":2,"type":"Pawn2","name":"2B","cleanType":"pawn"},{"x":3,"y":2,"type":"Pawn3","name":"2C","cleanType":"pawn"},{"x":4,"y":2,"type":"Pawn4","name":"2D","cleanType":"pawn"},{"x":5,"y":2,"type":"Pawn5","name":"2E","cleanType":"pawn"},{"x":6,"y":2,"type":"Pawn6","name":"2F","cleanType":"pawn"},{"x":7,"y":2,"type":"Pawn7","name":"2G","cleanType":"pawn"},{"x":8,"y":2,"type":"Pawn8","name":"2H","cleanType":"pawn"}];
el.blackMoves = [{"x":1,"y":8,"type":"Rook1","name":"8A","cleanType":"rook"},{"x":8,"y":8,"type":"Rook2","name":"8H","cleanType":"rook"},{"x":2,"y":8,"type":"Knight1","name":"8B","cleanType":"knight"},{"x":7,"y":8,"type":"Knight2","name":"8G","cleanType":"knight"},{"x":3,"y":8,"type":"Bishop1","name":"8C","cleanType":"bishop"},{"x":6,"y":8,"type":"Bishop2","name":"8F","cleanType":"bishop"},{"x":4,"y":8,"type":"Queen","name":"8D","cleanType":"queen"},{"x":5,"y":8,"type":"King","name":"8E","cleanType":"king"},{"x":1,"y":7,"type":"Pawn1","name":"7A","cleanType":"pawn"},{"x":2,"y":7,"type":"Pawn2","name":"7B","cleanType":"pawn"},{"x":3,"y":7,"type":"Pawn3","name":"7C","cleanType":"pawn"},{"x":4,"y":7,"type":"Pawn4","name":"7D","cleanType":"pawn"},{"x":5,"y":7,"type":"Pawn5","name":"7E","cleanType":"pawn"},{"x":6,"y":7,"type":"Pawn6","name":"7F","cleanType":"pawn"},{"x":7,"y":7,"type":"Pawn7","name":"7G","cleanType":"pawn"},{"x":8,"y":7,"type":"Pawn8","name":"7H","cleanType":"pawn"}]
el.rank = ["A", "B", "C", "D", "E", "F", "G", "H"];
var result = []
type = "white";
piece= "bishop";
var x = 5;
var y = 1;
var v = {
// the validation methods
bishop: function () {
var offSet = [];
for (var i = 1; i <= 8; i++) {
if (x + i < 8 && y + i < 8)
offSet.push({ x: x + i, y: y + i });
if (x + i < 8 && y - i < 8)
offSet.push({ x: x + i, y: y - i });
if (x - i < 8 && y + i < 8)
offSet.push({ x: x - i, y: y + i });
if (x - i < 8 && y - i < 8)
offSet.push({ x: x - i, y: y - i });
}
if (type == "white")
result = offSet.flatMap((item) => item.y + el.rank[item.x]).filter((item) => el.whiteMoves.filter((x) => x.name == item).length <= 0);
else result = offSet.flatMap((item) => item.y + el.rank[item.x]).filter((item) => el.blackMoves.filter((x) => x.name == item).length <= 0);
return result;
}
}
v[piece]();
// there is some invalid values like -5A or NaN but its not a problem these will be removed later on
console.log(result);
Answers
Your for loop simply doesn't include code to detect collisions. It goes all the way to the edge of the board. Consider breaking the loop into four separate for loops, each one terminating at the edge of the board OR when it detects a collision. The collision needs to be handled separately for a piece of the same color (illegal move) or of the opposite color (capture).
var dx = +1, dy = +1;
do {
x += dx;
y += dy;
// Running into any color piece terminates the loop.
// However, running into an opposite color piece adds one last legal move.
var onBoard = (x >= 0) && (x < 8) && (y >= 0) && (y < 8);
var samePiece = onBoard ? (detect_collision_with_same_color_piece) : false;
var oppPiece = onBoard ? (detect_collision_with_opp_color_piece) : false;
if (onBoard && !samePiece) {
offSet.push({ x: x, y: y });
}
} while (onBoard && !samePiece && !oppPiece);
It's hard to provide the exact collision detection code, so I left some placeholders there. Some additional thoughts:
- Obviously, you should parameterize
dxanddyto loop over all the +1 and -1 combinations, so that you don't repeat the above code four times. - If memory is not an issue, you can pad the matrix with some special values on all four sides so that you don't need to check
xandyfor correctness every single time. For example, if white is to move and you pad the matrix with white pawns, then you can removeonBoardall together; the loop will terminate whensamePiecebecomes true. This does increase your board from 64 squares to 100, which can be significant once you add transposition tables. - Better yet, consider having a look at rotated bitboards, which is a completely different, and much faster, approach for move generation.
更多推荐

所有评论(0)