2

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.

enter image description here

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);
peterh
  • 11,875
  • 18
  • 85
  • 108
Alen.Toma
  • 4,684
  • 2
  • 14
  • 31

1 Answers1

5

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:

  1. Obviously, you should parameterize dx and dy to loop over all the +1 and -1 combinations, so that you don't repeat the above code four times.
  2. 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 x and y for correctness every single time. For example, if white is to move and you pad the matrix with white pawns, then you can remove onBoard all together; the loop will terminate when samePiece becomes true. This does increase your board from 64 squares to 100, which can be significant once you add transposition tables.
  3. Better yet, consider having a look at rotated bitboards, which is a completely different, and much faster, approach for move generation.
Cătălin Frâncu
  • 1,179
  • 8
  • 15
  • 1
    Just as a side note: bitboards (rotated or not) require 64-bit bitwise operations, which vanilla JS is lacking. Although it's possible to do an implementation in 32-bit, it's going to be slower and maybe not worth the effort compared to easier methods. That said, we now have [BigInt](https://developers.google.com/web/updates/2018/05/bigint)'s to the rescue and I'd be curious to know how fast the bitboard logic would work with them. – Arnauld Feb 20 '19 at 17:09