List<Vector2> IsTheKingPutInCheck(List<Vector2> moves, Piece piece) { //In this method I am going to simulate the board state and then //Move the piece in question to see if its movement will open //an attack route to the king, if it does the move will be prohibited. List<Vector2> allowedMoves = new List<Vector2>(); Tile[,] clonedTiles = MakeVirtualTiles(tiles); Piece[] clonedPieces = MakeVirtualPieces(pieces); Piece pieceClone = new Piece(); //Deep Clones the Peice so I can move it around. foreach (Piece clonedPiece in clonedPieces) { if (clonedPiece.MyCoordinates() == piece.MyCoordinates()) { pieceClone = clonedPiece; } } Vector2 origin = piece.MyCoordinates(); foreach (Vector2 move in moves) { pieceClone.MovePosition(move); //These did not help clonedTiles[(int)origin.x, (int)origin.y].occupied = false; clonedTiles[(int)move.x, (int)move.y].occupied = true; ThreatCheck(clonedTiles, clonedPieces); if (!CheckCheck(pieceClone.player, clonedPieces, clonedTiles)) { allowedMoves.Add(move); } pieceClone.MovePosition(origin); clonedTiles[(int)origin.x, (int)origin.y].occupied = true; clonedTiles[(int)move.x, (int)move.y].occupied = false; } return allowedMoves; }
List<Vector2> GetOutOfCheck(List<Vector2> moves, Piece piece) { //NOTE problem with pawns captureing other pawns to remove the king from check //By the time I get here I get 6 make Virtual Piece calls gotta fix that. (Should be 4) TODO // The way I do this will be horribly inneficent I think. If performance becomes an issue //I should head here first. Most notably if I pass a list instead of a single peice when //Used to determin checkmate it will reduce the generation of virtual stuff to once //Instead of once per piece. //TODO we gotta add captures to the equation. List<Vector2> allowedMoves = new List<Vector2>(); Tile[,] virtualTiles = MakeVirtualTiles(tiles); Piece[] virtualPieces = MakeVirtualPieces(pieces); Piece virtualPiece = new Piece(); //Clones the piece in question foreach (Piece vPiece in virtualPieces) { if (piece.MyCoordinates() == vPiece.MyCoordinates()) { virtualPiece = vPiece; } } Vector2 origin = virtualPiece.MyCoordinates(); Debug.Log(moves.Count + " moves to check"); foreach (Vector2 move in moves) { foreach (Piece vPiece in virtualPieces) { if (vPiece.MyCoordinates() == move) { Debug.Log("Captured @ " + move); vPiece.captured = true; } } virtualPiece.MovePosition(move); UpdateTileOccupation(virtualTiles, virtualPieces); ClearThreats(virtualTiles); ThreatCheck(virtualTiles, virtualPieces); if (!CheckCheck(virtualPiece.player, virtualPieces, virtualTiles)) { allowedMoves.Add(move); } //Return Peice to location and try next move. virtualPiece.MovePosition(origin); } return allowedMoves; }
void PromotionLogic(Piece piece, Piece.Type type) { //Going to instansiate a new game object and then clone a peice to it. //I will simply place the new peice in the pawns index. //CreateNewPiece(); Debug.Log("type is " + type + " formerly a " + piece.type) ; for (int ii = 0; ii < pieces.Length; ii++) { if (pieces[ii] == piece) { pieces[ii] = ClonePieceAndPromote(piece, type); } } Debug.Log("Piece for player " + piece.player + " set to " + piece.type + " At pos " + piece.MyCoordinates()); }
public void KingStuff(Piece piece) { //Removes the king momentarily from the board to // Accurately check if his move would put him in check // Namely if he retreats along a line of attack. Piece[] virtualPieces = MakeVirtualPieces(pieces); Tile[,] virtualTiles = MakeVirtualTiles(tiles); int x = (int)piece.MyCoordinates().x; int y = (int)piece.MyCoordinates().y; //Remove the king in question for check check reasons. virtualTiles[x, y].occupied = false; ThreatCheck(virtualTiles, virtualPieces); virtualTiles[x, y].occupied = true; }
void LeftClickLogic(RaycastHit hit) { string tagPiece = "Piece"; string tagTile = "Tile"; if (hit.collider.gameObject.tag == tagPiece) { Piece clickedPiece = new Piece(); //Find out what kind of piece I clicked in the list of pieces that exist. foreach (Piece piece in pieces) { if (hit.collider.gameObject.transform.position == piece.gameObject.transform.position) { clickedPiece = piece; //Debug.Log("Cliecked " + clickedPiece.type); } } StorePiece(clickedPiece); //Make sure the piece is owned by the player. if (clickedPiece.player != whatPlayerAmI) { int x = (int)clickedPiece.gameObject.transform.position.x / 3; int y = (int)clickedPiece.gameObject.transform.position.z / 3; clickTile(x, y); } if (clickedPiece.player == whatPlayerAmI && !clickedPiece.moved) { ClearHighlights(); origin = clickedPiece.MyCoordinates(); //Determin where that peice may move / attack List<Vector2> possibleMoves = new List<Vector2>(); //TODO so right here I think all the non King Pieces need a filter //That will run with their moves and the kings COORDs to see if they //Put him in check. switch (clickedPiece.type) { case Piece.Type.PAWN: possibleMoves = ClickedPieceMoves(clickedPiece); break; case Piece.Type.BISHOP: possibleMoves = ClickedPieceMoves(clickedPiece); break; case Piece.Type.KNIGHT: possibleMoves = ClickedPieceMoves(clickedPiece); break; case Piece.Type.ROOK: possibleMoves = ClickedPieceMoves(clickedPiece); break; case Piece.Type.QUEEN: possibleMoves = ClickedPieceMoves(clickedPiece); break; case Piece.Type.KING: KingStuff(clickedPiece); possibleMoves = ClickedPieceMoves(clickedPiece); break; default: Debug.Log("Something wrong in piece type"); break; }//Piece selection if (whatPlayerAmI == 1 && p1Check) { HighlightMoves(GetOutOfCheck(possibleMoves, clickedPiece)); } if (whatPlayerAmI == 1 && !p1Check) { HighlightMoves(IsTheKingPutInCheck(possibleMoves, clickedPiece)); } if (whatPlayerAmI == 2 && p2Check) { HighlightMoves(GetOutOfCheck(possibleMoves, clickedPiece)); } if (whatPlayerAmI == 2 && !p2Check) { HighlightMoves(IsTheKingPutInCheck(possibleMoves, clickedPiece)); } }//Ownership Check }//Clicked a Piece if (hit.collider.gameObject.tag == tagTile) { int x = (int)hit.collider.gameObject.transform.position.x / 3; int y = (int)hit.collider.gameObject.transform.position.z / 3; clickTile(x, y); }//Shoot tile. }