Search code examples
c#unity-game-enginechess

Unity chess game problem with friendly piece collision


Hi im building a chess game in Unity and my issue is that the queen can move above a friendly piece.

When a piece is selected, an array of legal moves on the board is generated

legalMoves = piece.Move();

I chose to work with vectors here so any move within the list is a 2d Vector.

Then in a loop, I check if any of the moves are within the boundaries of the board and if the move would place the piece on another friendly piece. If it does, then discard that move but my problem is that it should discard all the moves within that direction.

For example: if the queen is on (3,3) and there is a pawn on (3,5), then all the moves (3,6), (3,7) ... should be discarded but not (3,4).

Similarly, if the black queen is on (7,7) and a pawn is on (7,5) then all moves (7,4), (7,3), (7,2) .. should be discarded but not (7,6).

My intuition here was that when a vector has a friendly piece on it, check the direction and the length of all my legal moves against it:

if (dir.normalized.Equals(temp[j].normalized) && dir.SqrMagnitude() < temp[j].SqrMagnitude())

The idea was to remove all the vectors from the legalmoves with the same direction but with greater length, however this doesn't really seem to work because the normalized vectors will not be equal.

Here is the relevant code

foreach (var dir in legalMoves)
{
    if (0 <= dir.x && dir.x <= 7 && 0 <= dir.y && dir.y <= 7)
    {
        //TODO shrink this to 1d array search
        if (board[(int) dir.x, (int) dir.y].getPiece() == null)
        {

           Instantiate(trail, dir, Quaternion.identity);
        }
        else
        {
            List<Vector2> temp = legalMoves.ToList();
            GameObject[] trails = GameObject.FindGameObjectsWithTag("bullet");

            for (int j = 0; j< temp.Count; j++)
            {
                if (  dir.normalized.Equals(temp[j].normalized) &&   dir.SqrMagnitude() < temp[j].SqrMagnitude())
                {
                    foreach(var t in trails)
                    {
                        // remove trail 
                        if (t.transform.position.Equals(temp[j])) Destroy(t);
                    }
                    // remove the move with the same direction
                    temp.Remove(temp[j]);
                }
            }
            
            temp.Remove(dir);
            
            legalMoves = temp.ToArray();
        }
    }
}

here is my problem visualized chess collision issue


Solution

  • Ok, maybe there could be a better solution, however, the way I managed to do it is the following:

    Our queen = q is at (3,0) , obstructed piece = k is at (3,6),

    If we calculate the offset from k to q we always get an axis which is 0 (either x or y ) in this case it is x.

    Since we know an axis is 0 we can check which one is 0 using a boolean, in this case it is x, and simply discard all the legal moves which are on x and above 6 or below 6 for black pieces.

    I haven't thought about how to do it if a piece obstructs horizontally, however I'm sure its just a matter of adding/ substracting the right coordinates as above.