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