Keep Getting Index Out of Range Error

So I’m working on a variation of chess. I’m trying to get a basic Chess A.I going, I already have the Human vs Human part complete. I should also mention that this is my first game so I’m not experienced. Right now I’m doing a Random A.I, then I’m going to flesh it out from there. I keep getting an Index out of range error. Basically whenever the AI tries to move a piece that doesn’t have any available moves I get an error. I tried to remedy this by removing all pieces that has no movement, nut it doesn’t seem to be working. Any suggestions?

public void AiRandomMove()
    {
        GameObject randomPiece;
        GameObject pieceToCapture;
        Vector2Int gridPoint;
        Vector2Int placeToMove;
        Piece tempPiece;
        List<Vector2Int> moveLocations = new List<Vector2Int>();

        randomPiece = AiGetRandomPiece(GameManager.instance.currentPlayer.pieces);
        gridPoint = GameManager.instance.GridForPiece(randomPiece);
        tempPiece = randomPiece.GetComponent<Piece>();
        moveLocations = GameManager.instance.MovesForPiece(randomPiece);
        placeToMove = AiGetRandomMoveLocation(randomPiece, gridPoint);
        pieceToCapture = GameManager.instance.PieceAtGrid(placeToMove);

        GameManager.instance.currentPlayer.pieces.RemoveAll(piece => piece == null); //remove all null items from list
        GameManager.instance.otherPlayer.pieces.RemoveAll(piece => piece == null); //remove all null items from list

        if (!moveLocations.Contains(placeToMove))
        {
            return;
        }

       

       
        if (GameManager.instance.PieceAtGrid(placeToMove) == null)
        {
            //Move Piece//

            GameManager.instance.Move(randomPiece, placeToMove);

            //PROMOTION//

            if (randomPiece.GetComponent<Piece>().type == PieceType.Pawn && placeToMove.y == 9 || randomPiece.GetComponent<Piece>().type == PieceType.Pawn && placeToMove.y == 1)
            {
                GameManager.instance.StartCo(placeToMove);
                Destroy(randomPiece);
            }
        }

        //CASTLING//

        else if (GameManager.instance.currentPlayer.pieces.Contains(pieceToCapture))
        {
            Vector2Int movePiecePoint = GameManager.instance.GridForPiece(randomPiece);
            GameManager.instance.Castle(randomPiece, pieceToCapture, movePiecePoint, placeToMove);
        }
        else
        {
            //Capture Piece//

            GameManager.instance.CapturePieceAt(placeToMove);
            GameManager.instance.Move(randomPiece, placeToMove);

            //Promotion//

            if (randomPiece.GetComponent<Piece>().type == PieceType.Pawn && placeToMove.y == 9 || randomPiece.GetComponent<Piece>().type == PieceType.Pawn && placeToMove.y == 1)
            {
                GameManager.instance.StartCo(gridPoint);
                Destroy(randomPiece);
            }

            //King Me//

            if (pieceToCapture.GetComponent<Piece>().type == PieceType.Crown || pieceToCapture.GetComponent<Piece>().type == PieceType.King)
            {
                Destroy(randomPiece);
                GameManager.instance.KingMe(placeToMove);
            }
        }

        GameManager.instance.NextPlayer();
        Debug.Log("AI RUNNING");
    }

    public GameObject AiGetRandomPiece(List<GameObject> aiPieces)
    {
        aiPieces = RemovePiecesWithNoMovement(aiPieces);

        List<GameObject> tempList = aiPieces;
        tempList.RemoveAll(nullPiece => nullPiece == null); //remove all null items from list
        tempList.RemoveAll(goal => IsGoal(goal));//Remove all goals

        GameObject piece = tempList[Random.Range(0, tempList.Count)];
        Piece tempPiece = piece.GetComponent<Piece>();
        Vector2Int gridPoint = GameManager.instance.GridForPiece(piece);
        List<Vector2Int>  moveLocations = tempPiece.MoveLocations(gridPoint);


        Debug.Log("Random Piece = " + piece);
        return piece;
    }

    private bool IsGoal(GameObject piece)
    {
        Piece tempPiece = piece.GetComponent<Piece>();
        if(tempPiece.type == PieceType.Goal)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    private List<GameObject> RemovePiecesWithNoMovement(List<GameObject> aiPieces)
    {
        aiPieces.RemoveAll(nullPiece => nullPiece == null); //remove all null items from list
        List<GameObject> tempList = new List<GameObject>();

        foreach (GameObject piece in aiPieces)
        {
            Vector2Int gridPoint = GameManager.instance.GridForPiece(piece);
            Piece tempPiece = piece.GetComponent<Piece>();

            if(tempPiece.MoveLocations(gridPoint) == null)
            {
                continue;
            }
            else
            {
                tempList.Add(piece);
            }
        }
        return tempList;
    }
    private bool noMoves(GameObject piece, Vector2Int gridPoint)
    {
        Piece tempPiece = piece.GetComponent<Piece>();
        if (tempPiece.MoveLocations(gridPoint) == null)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public Vector2Int AiGetRandomMoveLocation(GameObject piece, Vector2Int gridPoint)
    {
        List<Vector2Int> moveLocations;
        Piece tempPiece = piece.GetComponent<Piece>();
        gridPoint = GameManager.instance.GridForPiece(piece);
        moveLocations = tempPiece.MoveLocations(gridPoint);
        Vector2Int randomMoveLocation = moveLocations[Random.Range(0, moveLocations.Count)]; //If null do something.....FUCK YOU NULL!!!!!!

        return randomMoveLocation;
    }

Sorry here’s the code. I never used the NoMove method above. Still not working right.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ChessAI : MonoBehaviour
{
    public static ChessAI instance;
    private GameObject lastPieceMoved;
    private List<Vector2Int> aiMoveLocations;
    private List<Vector2Int> playerMoveLocations;

    //void Start(){}
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.J))
        {
            AiRandomMove();
        }
    }

    public void AiRandomMove()
    {
        GameObject randomPiece;
        GameObject pieceToCapture;
        Vector2Int gridPoint;
        Vector2Int placeToMove;
        Piece tempPiece;
        List<Vector2Int> moveLocations = new List<Vector2Int>();

        randomPiece = AiGetRandomPiece(GameManager.instance.currentPlayer.pieces);
        gridPoint = GameManager.instance.GridForPiece(randomPiece);
        tempPiece = randomPiece.GetComponent<Piece>();
        moveLocations = GameManager.instance.MovesForPiece(randomPiece);
        placeToMove = AiGetRandomMoveLocation(randomPiece, gridPoint);
        pieceToCapture = GameManager.instance.PieceAtGrid(placeToMove);

        GameManager.instance.currentPlayer.pieces.RemoveAll(piece => piece == null); //remove all null items from list
        GameManager.instance.otherPlayer.pieces.RemoveAll(piece => piece == null); //remove all null items from list

        if (!moveLocations.Contains(placeToMove))
        {
            return;
        }

       

       
        if (GameManager.instance.PieceAtGrid(placeToMove) == null)
        {
            //Move Piece//

            GameManager.instance.Move(randomPiece, placeToMove);

            //PROMOTION//

            if (randomPiece.GetComponent<Piece>().type == PieceType.Pawn && placeToMove.y == 9 || randomPiece.GetComponent<Piece>().type == PieceType.Pawn && placeToMove.y == 1)
            {
                GameManager.instance.StartCo(placeToMove);
                Destroy(randomPiece);
            }
        }

        //CASTLING//

        else if (GameManager.instance.currentPlayer.pieces.Contains(pieceToCapture))
        {
            Vector2Int movePiecePoint = GameManager.instance.GridForPiece(randomPiece);
            GameManager.instance.Castle(randomPiece, pieceToCapture, movePiecePoint, placeToMove);
        }
        else
        {
            //Capture Piece//

            GameManager.instance.CapturePieceAt(placeToMove);
            GameManager.instance.Move(randomPiece, placeToMove);

            //Promotion//

            if (randomPiece.GetComponent<Piece>().type == PieceType.Pawn && placeToMove.y == 9 || randomPiece.GetComponent<Piece>().type == PieceType.Pawn && placeToMove.y == 1)
            {
                GameManager.instance.StartCo(gridPoint);
                Destroy(randomPiece);
            }

            //King Me//

            if (pieceToCapture.GetComponent<Piece>().type == PieceType.Crown || pieceToCapture.GetComponent<Piece>().type == PieceType.King)
            {
                Destroy(randomPiece);
                GameManager.instance.KingMe(placeToMove);
            }
        }

        GameManager.instance.NextPlayer();
        Debug.Log("AI RUNNING");
    }

    public GameObject AiGetRandomPiece(List<GameObject> aiPieces)
    {
        aiPieces = RemovePiecesWithNoMovement(aiPieces);

        List<GameObject> tempList = aiPieces;
        tempList.RemoveAll(nullPiece => nullPiece == null); //remove all null items from list
        tempList.RemoveAll(goal => IsGoal(goal));//Remove all goals

        GameObject piece = tempList[Random.Range(0, tempList.Count)];
        Piece tempPiece = piece.GetComponent<Piece>();
        Vector2Int gridPoint = GameManager.instance.GridForPiece(piece);
        List<Vector2Int>  moveLocations = tempPiece.MoveLocations(gridPoint);


        Debug.Log("Random Piece = " + piece);
        return piece;
    }

    private bool IsGoal(GameObject piece)
    {
        Piece tempPiece = piece.GetComponent<Piece>();
        if(tempPiece.type == PieceType.Goal)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    private List<GameObject> RemovePiecesWithNoMovement(List<GameObject> aiPieces)
    {
        aiPieces.RemoveAll(nullPiece => nullPiece == null); //remove all null items from list
        List<GameObject> tempList = new List<GameObject>();

        foreach (GameObject piece in aiPieces)
        {
            Vector2Int gridPoint = GameManager.instance.GridForPiece(piece);
            Piece tempPiece = piece.GetComponent<Piece>();

            if(tempPiece.MoveLocations(gridPoint) == null || NoMoves(piece, gridPoint))
            {
                continue;
            }
            else
            {
                tempList.Add(piece);
            }
        }
        return tempList;
    }
    private bool NoMoves(GameObject piece, Vector2Int gridPoint)
    {
        Piece tempPiece = piece.GetComponent<Piece>();
        if (tempPiece.MoveLocations(gridPoint) == null)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public Vector2Int AiGetRandomMoveLocation(GameObject piece, Vector2Int gridPoint)
    {
        List<Vector2Int> moveLocations;
        Piece tempPiece = piece.GetComponent<Piece>();
        gridPoint = GameManager.instance.GridForPiece(piece);
        moveLocations = tempPiece.MoveLocations(gridPoint);
        Vector2Int randomMoveLocation = moveLocations[Random.Range(0, moveLocations.Count)]; //If null do something.....FUCK YOU NULL!!!!!!

        return randomMoveLocation;
    }

    /*private void AiGenerateMoveLocations(List<GameObject> pieces)
    {
        foreach (GameObject piece in pieces)
        {
            Piece tempPiece = piece.GetComponent<Piece>();
            Vector2Int gridPoint = GameManager.instance.GridForPiece(piece);
            List<Vector2Int> locations = tempPiece.MoveLocations(gridPoint);
        }
    }*/
}

Nevermind, I fixed the problem. Had a bunch of redundant code and I guess somewhere in there it messed things up.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ChessAI : MonoBehaviour
{
    public static ChessAI instance;

    //void Start(){}
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.J))
        {
            AiRandomMove();
        }
    }

    public void AiRandomMove()
    {
        GameObject randomPiece = AiGetRandomPiece(GameManager.instance.currentPlayer.pieces);
        Vector2Int gridPoint = GameManager.instance.GridForPiece(randomPiece);
        List<Vector2Int> moveLocations = GameManager.instance.MovesForPiece(randomPiece);
        Vector2Int placeToMove = AiGetRandomMoveLocation(randomPiece);
        GameObject pieceToCapture = GameManager.instance.PieceAtGrid(placeToMove);

        if (!moveLocations.Contains(placeToMove))
        {
            return;
        }

        if (GameManager.instance.PieceAtGrid(placeToMove) == null)
        {
            //Move Piece//

            GameManager.instance.Move(randomPiece, placeToMove);

            //PROMOTION//

            if (randomPiece.GetComponent<Piece>().type == PieceType.Pawn && placeToMove.y == 9 || randomPiece.GetComponent<Piece>().type == PieceType.Pawn && placeToMove.y == 1)
            {
                GameManager.instance.StartCo(placeToMove);
                Destroy(randomPiece);
            }
        }

        //CASTLING//

        else if (GameManager.instance.currentPlayer.pieces.Contains(pieceToCapture))
        {
            Vector2Int movePiecePoint = GameManager.instance.GridForPiece(randomPiece);
            GameManager.instance.Castle(randomPiece, pieceToCapture, movePiecePoint, placeToMove);
        }
        else
        {
            //Capture Piece//

            GameManager.instance.CapturePieceAt(placeToMove);
            GameManager.instance.Move(randomPiece, placeToMove);

            //Promotion//

            if (randomPiece.GetComponent<Piece>().type == PieceType.Pawn && placeToMove.y == 9 || randomPiece.GetComponent<Piece>().type == PieceType.Pawn && placeToMove.y == 1)
            {
                GameManager.instance.StartCo(gridPoint);
                Destroy(randomPiece);
            }

            //King Me//

            if (pieceToCapture.GetComponent<Piece>().type == PieceType.Crown || pieceToCapture.GetComponent<Piece>().type == PieceType.King)
            {
                Destroy(randomPiece);
                GameManager.instance.KingMe(placeToMove);
            }
        }

        GameManager.instance.NextPlayer();
    }

    public GameObject AiGetRandomPiece(List<GameObject> aiPieces)
    {
        aiPieces = RemovePiecesWithNoMovement(aiPieces);
        List<GameObject> tempList = aiPieces;
        tempList.RemoveAll(nullPiece => nullPiece == null); //remove all null items from list
        tempList.RemoveAll(goal => IsGoal(goal));//Remove all goals
        GameObject piece = tempList[Random.Range(0, tempList.Count)];
        List<Vector2Int>  moveLocations = GameManager.instance.MovesForPiece(piece);

        return piece;
    }

    private bool IsGoal(GameObject piece)
    {
        Piece tempPiece = piece.GetComponent<Piece>();
        if(tempPiece.type == PieceType.Goal)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    private List<GameObject> RemovePiecesWithNoMovement(List<GameObject> aiPieces)
    {
        aiPieces.RemoveAll(nullPiece => nullPiece == null); //remove all null items from list
        List<GameObject> tempList = new List<GameObject>();
        List<Vector2Int> moveLocations = new List<Vector2Int>();

        foreach (GameObject piece in aiPieces)
        {
            moveLocations = GameManager.instance.MovesForPiece(piece);

            if(moveLocations.Count > 0)
            {
                tempList.Add(piece);
            }
        }

        return tempList;
    }

    public Vector2Int AiGetRandomMoveLocation(GameObject piece)
    {
        List<Vector2Int> moveLocations;
        moveLocations = GameManager.instance.MovesForPiece(piece);
        Vector2Int randomMoveLocation = moveLocations[Random.Range(0, moveLocations.Count)]; //If null do something

        return randomMoveLocation;
    }
}

Glad you got it sorted. For the next people coming along, these errors are VERY simple to figure out:

Here are some notes on IndexOutOfRangeException and ArgumentOutOfRangeException:

http://plbm.com/?p=236

1 Like