/// <summary> /// Check if object is elegable for en passant /// </summary> /// <returns>True if it can, False if it can not, Null if error</returns> protected bool IsEnPassant() { int direction = 1; bool isBlack = GetIsBlack(); if (isBlack) { direction = -1; } Vector2Int chessCoords = Coord_Manager.ConvertCoordsToChessUnits(transform.localPosition) - new Vector2Int(0, direction); Transform obj = Coord_Manager.GetTransformAt(chessCoords); try { if (obj.tag == "Pawn") { if (obj.parent != transform.parent) { if (obj.GetComponent <Pawn_Piece>().canBePassanted) { Kill(obj.name); return(true); } } } return(false); } catch (NullReferenceException) { return(false); } }
/// <summary> /// Gets location of king in board units /// </summary> /// <param name="Black">Black King or White King</param> /// <param name="main">Main Board or Temp Board</param> /// <returns>Board units of selected king</returns> public Vector2Int GetKingPosition(bool Black, bool main = false) { string kingName = Black ? blackKingName : whiteKingName; print(Black + " : " + kingName); return(Coord_Manager.GetCoordPosition(kingName, main)); }
public Move(string name, string type, Vector2Int newMoveOffset, Vector2Int finalPos) { this.name = name; this.type = type; this.newMoveOffset = newMoveOffset; this.finalPos = finalPos; this.finalPosRaw = Coord_Manager.ConvertChessUnitsToCoords(finalPos); }
/// <summary> /// Checks if the last move was valid /// </summary> /// <returns>Validity of last move</returns> public bool IsValidMove(Move move) { //is the piece on the board? if (!IsInBounds(move)) { Debug.LogWarning("Out of Bounds"); Feedback.SetText("Out of Bounds"); return(false); } //is it your turn to go? if (!team.hasTurn) { Debug.LogWarning("Not your turn"); Feedback.SetText("Not your turn"); return(false); } moveDelta = move.newMoveOffset; Debug.Log(moveDelta); if (moveDelta == Vector2Int.zero) { Feedback.SetText("Oops, dropped your piece"); return(false); } CollisionInfo = Coord_Manager.CheckCollitionAt(move.finalPos, GetIsBlack() ? "Black" : "White"); bool isCollidingWithOwnTeam = CollisionInfo.isCollidingWithOwnTeam; //is the piece trying to kill it's own team? if (isCollidingWithOwnTeam) { Feedback.SetText("Can't kill your own piece"); return(false); } //is the piece making a move that particular piece is able to do? if (!middleMan.IsPieceSpecificMoveValid()) { return(false); } CF = Coord_Manager.GetCheckInfoAt(middleMan.GetKingPosition(team.isBlack), team.isBlack); if (CF.isInCheck) { Feedback.SetText("King In Check"); return(false); } return(true); }
/// <summary> /// Executes Castle /// </summary> /// <param name="ShortCastle">True for short side castle, False, for long side</param> void Castle(bool ShortCastle) { if (GetIsBlack()) { if (ShortCastle) { Transform rook = Coord_Manager.GetTransformObject("Black_Rook_2"); Chess_Piece rook_CP = Coord_Manager.GetPiece("Black_Rook_2"); Vector3 targetPos = Coord_Manager.ConvertChessUnitsToCoords(new Vector2Int(6, 8)); rook.localPosition = targetPos; rook_CP.CenterPiece(); Coord_Manager.UpdatePosition(rook.name, targetPos); } else { Transform rook = Coord_Manager.GetTransformObject("Black_Rook_1"); Chess_Piece rook_CP = Coord_Manager.GetPiece("Black_Rook_1"); Vector3 targetPos = Coord_Manager.ConvertChessUnitsToCoords(new Vector2Int(4, 8)); rook.localPosition = targetPos; rook_CP.CenterPiece(); Coord_Manager.UpdatePosition(rook.name, targetPos); } } else { if (ShortCastle) { Transform rook = Coord_Manager.GetTransformObject("White_Rook_2"); Chess_Piece rook_CP = Coord_Manager.GetPiece("White_Rook_2"); Vector3 targetPos = Coord_Manager.ConvertChessUnitsToCoords(new Vector2Int(6, 1)); rook.localPosition = targetPos; rook_CP.CenterPiece(); Coord_Manager.UpdatePosition(rook.name, targetPos); } else { Transform rook = Coord_Manager.GetTransformObject("White_Rook_1"); Chess_Piece rook_CP = Coord_Manager.GetPiece("White_Rook_1"); Vector3 targetPos = Coord_Manager.ConvertChessUnitsToCoords(new Vector2Int(4, 1)); rook.localPosition = targetPos; rook_CP.CenterPiece(); Coord_Manager.UpdatePosition(rook.name, targetPos); } } }
/// <summary> /// Checks if this move is valid for a bishop /// </summary> /// <returns>Validity of move</returns> public bool IsValidBishopMove() { Vector2Int lastMove = CP.moveDelta; ColInfo flags = CP.CollisionInfo; if (Mathf.Abs(lastMove.x) != Mathf.Abs(lastMove.y)) { return(false); } Vector2Int currentCoord = Coord_Manager.ConvertCoordsToChessUnits(transform.localPosition); for (int i = 1; i < Mathf.Abs(lastMove.y); i++) { Vector2Int checkedCoord = currentCoord; if (lastMove.y > 0) { checkedCoord = new Vector2Int(checkedCoord.x, checkedCoord.y - i); } if (lastMove.y < 0) { checkedCoord = new Vector2Int(checkedCoord.x, checkedCoord.y + i); } if (lastMove.x > 0) { checkedCoord = new Vector2Int(checkedCoord.x - i, checkedCoord.y); } if (lastMove.x < 0) { checkedCoord = new Vector2Int(checkedCoord.x + i, checkedCoord.y); } if (Coord_Manager.GetNameAt(checkedCoord) != null) { return(false); } } if (flags.isColliding) { if (flags.isCollidingWithOwnTeam) { return(false); } Kill(flags.nameOfColObject); } return(true); }
/// <summary> /// Checks if this move is valid for a bishop /// </summary> /// <returns>Validity of move</returns> public bool IsValidPawnMove(bool isBlack = false) { Vector2Int lastMove = CP.moveDelta; ColInfo flags = CP.CollisionInfo; if (isBlack) { lastMove = new Vector2Int(lastMove.x, lastMove.y * -1); } if (lastMove.x != 0) //if there was a horizontal move { if (Mathf.Abs(lastMove.x) == 1 && lastMove.y == 1) //was it one of (1,1) or (-1,1)? { if (!flags.isCollidingWithKing) //make sure you didn't try to kill a king { if (flags.isColliding) //make sure you actually are colliding with something { Kill(flags.nameOfColObject); return(true); //if all these were true, then the move is valid } } if (IsEnPassant()) { return(true); } } return(false); //if there was a horizontal move and any of these conditions are false, then this move was invalid } if (lastMove.y >= 2 || lastMove.y < 0) //if you tried to move more than 1 space forward { if (lastMove.y == 2 && totalMoves == 0) //is this your first move? { Vector2Int currentCoord = Coord_Manager.ConvertCoordsToChessUnits(transform.localPosition); Debug.Log(currentCoord.y - (isBlack ? -1 : 1)); if (Coord_Manager.GetNameAt(new Vector2Int(currentCoord.x, currentCoord.y - (isBlack ? -1 : 1))) == null) { main.RequestPawnToBeAddedToPassantList(this, 2); return(true); //if so, then this move is valid } } return(false); //otherwise it isn't } if (lastMove.y == 1 && flags.isColliding) //can't move forward when there is a piece infront of you as a pawn { return(false); } return(true); //all other moves are fine }
/// <summary> /// End piece move, calculate move made and execute it /// </summary> void DropPiece() { Debug.LogWarning("timestart: " + Time.time); mouseIsClicked = false; Mouse_Manager.ResetMouseDelta(); CenterPiece(); Coord_Manager.UpdatePosition(transform.name, transform.localPosition); Move move = new Move(name, tag, Coord_Manager.GetPositionDifference(), transform.localPosition); if (!IsValidMove(move)) { transform.position = startPos; Coord_Manager.RevertMove(ref moveDelta); } else { if (team.isBlack) { main.blackInCheck = false; } else { main.whiteInCheck = false; } main.KillPieceMarkedForDeath(); Coord_Manager.CommitPositionUpdate(); CurrentChessCoord = Coord_Manager.ConvertCoordsToChessUnits(transform.localPosition); middleMan.EndTurn(); team.checkFlags = CF; team.EndTurn(); CF = Coord_Manager.GetCheckInfoAt(middleMan.GetKingPosition(!team.isBlack), !team.isBlack); if (CF.isInCheck) { Feedback.SetText("CHECK!"); if (team.isBlack) { main.whiteInCheck = true; } else { main.blackInCheck = true; } } } Debug.LogWarning("timeend: " + Time.time); }
/// <summary> /// Check if Object type exists at coord /// </summary> /// <param name="pos">Target position</param> /// <param name="type">Target type</param> /// <returns>True if type found at location, false otherwise</returns> public bool IsTypeAtCoord(Vector2Int pos, string type, bool lookForWhite, bool main = false) { Transform obj = Coord_Manager.GetTransformAt(pos, main); if (obj != null && obj.name != "Empty") { //bool temp = !obj.GetComponent<Chess_Piece>().team.isBlack; //if (temp == lookForWhite) if (obj.parent.name == "White" == lookForWhite) { return(obj.CompareTag(type)); } } return(false); }
// Start is called before the first frame update void Start() { middleMan = transform.GetComponent <Piece_Middle_manager>(); team = transform.parent.GetComponent <Team_Manager>(); main = GameObject.Find("MainCode").GetComponent <Main>(); SpawnPos = transform.position; isDead = false; //On start, make sure all the pieces are center CenterPiece(); CurrentChessCoord = Coord_Manager.ConvertCoordsToChessUnits(transform.localPosition); }
/// <summary> /// Function called by other pieces when this piece is being killed /// </summary> public void GetKilled() { Coord_Manager.KillPiece(transform.name); isDead = true; if (CompareTag("Rook")) { print(tag); if (transform.localPosition.x > 0) { team.canCastleShort = false; } else { team.canCastleLong = false; } } transform.localPosition = team.isBlack ? Death_Manager.GetBlackCoord() : Death_Manager.GetWhiteCoord(); }
/// <summary> /// Support method to make the Bishop check smaller /// </summary> /// <param name="target">Target Coord</param> /// <returns>1 if found, -1 if null, 0 if empty space</returns> static int BishopStep(Vector2Int target, bool isBlack, bool main = false) { if (helper.IsTypeAtCoord(target, "Bishop", isBlack, main)) { return(1); } if (helper.IsTypeAtCoord(target, "Queen", isBlack, main)) { return(1); } Transform transformBeingLookedAt = Coord_Manager.GetTransformAt(target); if (transformBeingLookedAt == null) { return(-1); } if (transformBeingLookedAt.name == "Empty") { return(0); } return(-1); }
/// <summary> /// Checks if this move is valid for a King /// </summary> /// <returns>Validity of move</returns> public bool IsValidKingMove() { Vector2Int lastMove = CP.moveDelta; ColInfo flags = CP.CollisionInfo; //If king moves more than 2 spaces, then invalid if (Mathf.Abs(lastMove.x) > 1 || Mathf.Abs(lastMove.y) > 1) { if (Mathf.Abs(lastMove.x) == 2) //check if king moved 2 squares left or right { if ((GetIsBlack() && !main.blackInCheck) || (!GetIsBlack() && !main.whiteInCheck)) { if (canCastle) //check if king can castle { if (totalMoves > 0) //double check if king can really castle { canCastle = false; //update check if can't team.canCastleShort = false; team.canCastleLong = false; } else { if (lastMove.x > 0) { if (team.canCastleShort) { if (Coord_Manager.GetNameAt(new Vector2Int(6, GetIsBlack() ? 8 : 1)) != null) { Feedback.SetText("Can't Castle With Piece In The Way"); return(false); //check for empty space for rook } if (Coord_Manager.GetCheckInfoAt(new Vector2Int(6, GetIsBlack() ? 8 : 1), GetIsBlack()).isInCheck) { Feedback.SetText("Can't Castle Through Check"); return(false); //make sure king isn't moving through check } } else { Feedback.SetText("Can't Castle King Side"); return(false); } } else { if (team.canCastleLong) { if (Coord_Manager.GetNameAt(new Vector2Int(4, GetIsBlack() ? 8 : 1)) != null || Coord_Manager.GetNameAt(new Vector2Int(2, GetIsBlack() ? 8 : 1)) != null) { Feedback.SetText("Can't Castle With Piece In The Way"); return(false); //check for empty piece for rook } if (Coord_Manager.GetCheckInfoAt(new Vector2Int(4, GetIsBlack() ? 8 : 1), GetIsBlack()).isInCheck) { Feedback.SetText("Can't Castle Through Check"); return(false); //make sure king isn't moving through check } } else { Feedback.SetText("Can't Castle Queen Side"); return(false); } } //Coord_Manager.GetNameAt() Castle(lastMove.x > 0); //Castle and return valid move return(true); } } Feedback.SetText("Can't Castle"); return(false); } Feedback.SetText("Can't Castle From Check"); return(false); } Feedback.SetText("Invalid Move for King"); return(false); } if (flags.isColliding) { if (flags.isCollidingWithOwnTeam) { return(false); } Kill(flags.nameOfColObject); } return(true); }
public List <Move> GetValidMoves() { List <Move> validMoves = new List <Move>(); List <Move> moves = new List <Move>(); //Debug.LogWarning(name); switch (PieceTypeID) { case 1: foreach (Vector2Int delta in PawnDeltas_W) { moves.Add(new Move(name, tag, delta, piece.CurrentChessCoord + delta)); } break; case 7: foreach (Vector2Int delta in PawnDeltas_B) { moves.Add(new Move(name, tag, delta, piece.CurrentChessCoord + delta)); } break; case 2: case 8: foreach (Vector2Int delta in RookDeltas) { moves.Add(new Move(name, tag, delta, piece.CurrentChessCoord + delta)); } break; case 3: case 9: foreach (Vector2Int delta in BishopDeltas) { moves.Add(new Move(name, tag, delta, piece.CurrentChessCoord + delta)); } break; case 4: case 10: foreach (Vector2Int delta in HorseDeltas) { moves.Add(new Move(name, tag, delta, piece.CurrentChessCoord + delta)); } break; case 5: case 11: foreach (Vector2Int delta in RookDeltas) { moves.Add(new Move(name, tag, delta, piece.CurrentChessCoord + delta)); } foreach (Vector2Int delta in BishopDeltas) { moves.Add(new Move(name, tag, delta, piece.CurrentChessCoord + delta)); } break; case 6: case 12: foreach (Vector2Int delta in KingDeltas) { moves.Add(new Move(name, tag, delta, piece.CurrentChessCoord + delta)); } break; } string temp = Feedback.GetText(); foreach (Move move in moves) { try { //Debug.Log(move.name); if (piece.IsValidMove(move)) { //Debug.Log(move.name + " accepted"); validMoves.Add(move); } else { //Debug.Log(move.name + " rejected"); } Coord_Manager.RevertMove(ref piece.moveDelta); } catch { Coord_Manager.RevertMove(ref piece.moveDelta); } } Feedback.SetText(temp); return(validMoves); }