/// <summary> /// Changes the piece mat. /// </summary> /// <param name="white">The new white piece material.</param> /// <param name="black">The new black piece material.</param> private void ChangePieceMat(Material white, Material black) { foreach (GameObject piece in boardInfo.GetPieceAvailable()) { PieceInformation pieceInfo = piece.GetComponent <PieceInformation>(); if (pieceInfo.colour == 0) { piece.GetComponent <MeshRenderer>().material = white; } else { piece.GetComponent <MeshRenderer>().material = black; } piece.GetComponent <HighlightChessPiece>().ChangeStartColour(); } foreach (GameObject piece in MoveHistory.Instance.EliminatedObjects) { PieceInformation pieceInfo = piece.GetComponent <PieceInformation>(); if (pieceInfo.colour == 0) { piece.GetComponent <MeshRenderer>().material = white; } else { piece.GetComponent <MeshRenderer>().material = black; } piece.GetComponent <HighlightChessPiece>().ChangeStartColour(); } }
/// <summary> /// Checks if at least one piece can block the path or eliminate the piece checking the king - if in check /// Or /// Checks to see if the opponent can play a move - for stalemate condition /// </summary> /// <returns> True if checkmate/stalemate </returns> static bool CheckmateStalemate(int colour, BoardInformation boardInfo) { foreach (GameObject pieceOnBoard in boardInfo.GetPieceAvailable()) { PieceInformation pieceOnBoardInfo = pieceOnBoard.GetComponent <PieceInformation>(); // skip if not opponent's piece if ((int)pieceOnBoardInfo.colour == colour) { continue; } pieceOnBoardInfo.GetMoves(); List <string> allowedPositions = pieceOnBoardInfo.GetPossibleMoves(); // Break out early if at least one piece can be moved if (allowedPositions.Count != 0) { string spots = ""; for (int i = 0; i < allowedPositions.Count; i++) { spots += allowedPositions[i] + " "; } return(false); } } return(true); }
void CheckCondition() { // Check the board state for win conditions GetMoves(); GameObject king; // Obtain the opponent's king if (colour == Colour.White) { king = boardInfo.GetBlackKing(); } else { king = boardInfo.GetWhiteKing(); } boardInfo.NextTurn(); PieceInformation kingInfo = king.GetComponent <PieceInformation>(); String kingPosition = kingInfo.CurrentXPosition + " " + kingInfo.CurrentZPosition; if (WinRules.CheckForCheck(possibleMoves, GetComponent <PieceInformation>(), boardInfo, kingPosition)) { return; } // Check Draw Conditions if (WinRules.CheckDraw((int)colour, boardInfo)) { return; } }
/// <summary> /// Checks if opponent's knight has control over the tile /// </summary> /// <returns> true if knight found </returns> bool KnightHelperMethod(int newXPosition, int newZPosition, GameObject[,] board, int colour) { // Check if x and z positions are outside bounds if (newXPosition > 7 || newXPosition < 0 || newZPosition > 7 || newZPosition < 0) { return(false); } GameObject piece = board[newZPosition, newXPosition]; // Check if no piece at location if (piece == null) { return(false); } PieceInformation pieceInformation = piece.GetComponent <PieceInformation>(); // if player's piece, return false if ((int)pieceInformation.colour == colour) { return(false); } // If knight, opponent's knight has control over the tile. // King cannot move to this location. if ((int)pieceInformation.type == 1) { return(true); } // Knight not found. King is probable to move to this location return(false); }
/// <summary> /// Check's if knight can move to the new position given in the argument /// </summary> /// <param name="newXPosition"> x Position knight can move to </param> /// <param name="newZPosition"> z Position knight can move to </param> /// <returns></returns> bool TwoStepsDisplacement(int newXPosition, int newZPosition) { // Check if newXPosition and newZPosition are within bounds of the 2D board // Invalid if outside the bounds, return false; if (newXPosition > 7 || newXPosition < 0 || newZPosition > 7 || newZPosition < 0) { return(false); } // If position is empty, knight can move to position if (board[newZPosition, newXPosition] == null) { return(true); } // Checks if piece in the new location is the player's piece // If true, not a valid move, return false GameObject pieceObject = board[newZPosition, newXPosition]; PieceInformation pieceInformation = pieceObject.GetComponent <PieceInformation>(); if ((int)pieceInformation.colour == colour) { return(false); } // Opponent's piece in location. Valid move. return(true); }
/// <summary> /// Checks if king can be castled in the direction provided. /// Occurs when neither the king nor the rook have moved /// </summary> /// <param name="position"> King's position </param> /// <param name="direction"> Direction we're checking for castling </param> /// <param name="colour"> Colour of the king </param> /// <returns> true if king can be castled in that direction </returns> public bool Castling(Vector3 position, Vector3 direction, int colour) { LayerMask layer = whiteMask; if (colour == 1) { layer = blackMask; } RaycastHit hit; if (Physics.Raycast(position, direction, out hit, 1f, layer)) { GameObject pieceCollided = hit.collider.gameObject; PieceInformation piece = pieceCollided.GetComponent <PieceInformation>(); // Check if player's rook in the direction if ((int)piece.type == 0 && (int)piece.colour == colour) { // Check if rook has been moved. if (!piece.HasMoved()) { return(true); } } } return(false); }
private IEnumerator PieceDown(GameObject changedPiece = null, bool checkValidity = false) { Vector3 piecePosition = pieceSelected.transform.localPosition; Vector3 down = new Vector3(piecePosition.x, 0, piecePosition.z); float time = 0; while (time <= duration) { time += Time.deltaTime; float blend = Mathf.Clamp01(time / duration); pieceSelected.transform.localPosition = Vector3.Lerp(piecePosition, down, blend); yield return(null); } // If the player changes the piece they want to move if (changedPiece != null) { ChangePiece(changedPiece); } // Check if chosen position is valid if (checkValidity) { pieceInformation.GetMoves(); pieceInformation.Moved(); } pieceSelected.GetComponent <Rigidbody>().detectCollisions = true; pieceSelected.GetComponent <Rigidbody>().isKinematic = false; pieceSelected = null; pieceInformation = null; }
/// <summary> /// Selects the piece the user is gazing on. /// Called when user says "select" /// </summary> public void SelectPiece() { if (InputSystem?.GazeProvider == null) { return; } GameObject piece = InputSystem.GazeProvider.GazeTarget; // If "select" said twice, place the first piece back down if (pieceSelected != null) { StartCoroutine(PieceDown(changedPiece: piece)); } else if (piece == null || piece.tag != "pieces") { return; } else { pieceSelected = piece; pieceInformation = piece.GetComponent <PieceInformation>(); StartCoroutine(PieceFloat()); } }
/// <summary> /// Undo/Reset pawn promotion /// </summary> public void UndoPromotion(GameObject pawn) { PieceInformation pawnInfo = pawn.GetComponent <PieceInformation>(); pawnInfo.type = PieceInformation.Type.Pawn; pawn.GetComponent <MeshFilter>().mesh = pawnMesh; }
void MoveCompleted() { foreach (GameObject piece in boardInfo.GetPieceAvailable()) { PieceInformation pieceInfo = piece.GetComponent <PieceInformation>(); pieceInfo.pieceRigidBody.useGravity = false; } boardInfo.CanMove = true; }
static bool Impossibility(BoardInformation boardInfo) { // Two kings are left if (boardInfo.GetPieceAvailable().Count == 2) { return(true); } // Two kings and one bishop/knight if (boardInfo.GetPieceAvailable().Count == 3) { foreach (GameObject piece in boardInfo.GetPieceAvailable()) { PieceInformation pieceInfo = piece.GetComponent <PieceInformation>(); if ((int)pieceInfo.type == 1 || (int)pieceInfo.type == 2) { return(true); } } } // King and Bishop vs King and Bishop if (boardInfo.GetPieceAvailable().Count == 4) { int bishopCount = 0; PieceInformation[] bishops = new PieceInformation[2]; foreach (GameObject piece in boardInfo.GetPieceAvailable()) { PieceInformation pieceInfo = piece.GetComponent <PieceInformation>(); if ((int)pieceInfo.type == 2) { bishops[bishopCount] = pieceInfo; bishopCount++; } } if (bishopCount == 2) { // Cannot be the same colour if (bishops[0].colour == bishops[1].colour) { return(false); } // Must be on the same colour tile for it to be a draw if (bishops[0].GetOriginalX() != bishops[1].GetOriginalX()) { return(true); } } } return(false); }
/// <summary> /// Called when the pawn reaches the opposite side of the board. /// Pawn disappears and player has a chance to choose the piece they want to replace it with. /// </summary> public IEnumerator PromotePawn(PieceInformation pieceInfo) { GameObject pawn = pieceInfo.gameObject; pawnPromo.SetActive(true); string pawnPromotion = "PAWN PROMOTION!"; SetText(pawnPromotion); MoveHistory.Instance.Promoted(); whiteForfeitText.text = "Promotion Tile"; blackForfeitText.text = "Promotion Tile"; EndGameResult.SetActive(true); while (!Promoted) { if (MeshChosen) { int x = pieceInfo.CurrentXPosition; int z = pieceInfo.CurrentZPosition; pawn.GetComponent <MeshFilter>().mesh = Mesh; if (string.Compare(Mesh.name, "Rook") == 0) { pieceInfo.type = PieceInformation.Type.Rook; } else if (string.Compare(Mesh.name, "Queen") == 0) { pieceInfo.type = PieceInformation.Type.Queen; } else if (string.Compare(Mesh.name, "Bishop") == 0) { pieceInfo.type = PieceInformation.Type.Bishop; } else if (string.Compare(Mesh.name, "Knight") == 0) { pieceInfo.type = PieceInformation.Type.Knight; } Promoted = true; } yield return(null); } Promoted = false; MeshChosen = false; whiteForfeitText.text = "Forfeit Tile"; blackForfeitText.text = "Forfeit Tile"; pawnPromo.SetActive(false); EndGameResult.SetActive(false); pieceInfo.ContinueProcess(); }
/// <summary> /// Checks if the tile is being controlled by the enemy /// </summary> /// <param name="position"> Position being checked </param> /// <param name="direction"> direction being checked for opponent's piece </param> /// <param name="colour"> King's colour </param> /// <param name="type"> /// type being checked against. /// 0 if Rook and Queen /// 1 if Queen and Bishop /// 2 if Pawn /// 3 if King /// </param> /// <param name="range"> Optional parameter to change the raycast distance </param> /// <returns> true if tile is not controlled by the opponent's piece that is being checked </returns> bool ValidMove(Vector3 position, Vector3 direction, int colour, int type, float range = 1f) { LayerMask layer = whiteMask; if (colour == 1) { layer = blackMask; } RaycastHit hit; if (Physics.Raycast(position, direction, out hit, range, layer)) { GameObject pieceCollided = hit.collider.gameObject; PieceInformation piece = pieceCollided.GetComponent <PieceInformation>(); // If player's piece is controlling the tile, moving into position is plausible. if ((int)piece.colour == colour) { return(true); } // Obtains the piece type to check if the raycast piece was what was being checked int pieceType = (int)piece.type; // Checks to see if the opponent's being checked is controlling the tile // Not a valid location for king to move. Return false if (type == 0 && (pieceType == 0 || pieceType == 3)) { return(false); } if (type == 1 && (pieceType == 2 || pieceType == 3)) { return(false); } if (type == 2 && pieceType == 5) { return(false); } if (type == 3 && pieceType == 4) { return(false); } } // Piece being checked does not control the tile. return(true); }
// Start is called before the first frame update void Start() { pi = GetComponent <PieceInformation>(); if (!pi) { Debug.LogError("PieceInformation script not found"); } chessboard = GameObject.Find("Chessboard"); if (!chessboard) { Debug.LogError("chessboard gameobject not found"); } }
private void TiltForfeit(PieceInformation.Colour colour) { List <GameObject> pieces = boardInfo.GetPieceAvailable(); foreach (GameObject piece in pieces) { PieceInformation pieceInfo = piece.GetComponent <PieceInformation>(); if (pieceInfo.colour == colour) { StartCoroutine(pieceAction.FallDown(piece)); } } lossColour = colour; boardInfo.GameEnded = true; }
void FixPosition() { List <GameObject> availablePieces = boardInfo.GetPieceAvailable(); foreach (GameObject piece in availablePieces) { PieceInformation pieceInfo = piece.GetComponent <PieceInformation>(); Vector3 position = new Vector3(pieceInfo.CurrentXPosition, 0, pieceInfo.CurrentZPosition); if (!CheckSimilarity(piece.transform.localPosition, position)) { pieceAction.ChangePosition(piece, position, (int)pieceInfo.colour); } } Invoke("MoveCompleted", 1.5f); }
public void UpdateBoard(int prevX, int prevZ, int currentX, int currentZ, GameObject pieceParam = null) { GameObject piece = pieceParam; if (piece == null) { piece = Board[prevZ, prevX]; } Board[prevZ, prevX] = null; Board[currentZ, currentX] = piece; PieceInformation pieceInfo = piece.GetComponent <PieceInformation>(); pieceInfo.CurrentXPosition = currentX; pieceInfo.CurrentZPosition = currentZ; }
private void FixPieces() { List <GameObject> pieces = boardInfo.GetPieceAvailable(); foreach (GameObject piece in pieces) { PieceInformation pieceInfo = piece.GetComponent <PieceInformation>(); Vector3 position = new Vector3(pieceInfo.CurrentXPosition, 0, pieceInfo.CurrentZPosition); if (!CheckSimilarity(piece.transform.localPosition, position)) { if (pieceInfo.colour != lossColour) { pieceAction.ChangePosition(piece, position, (int)pieceInfo.colour); } } } }
/// <summary> /// Gets all the active pieces of the same colour and starts knock-down animation /// </summary> void KingForfeit() { boardInfo.GameEnded = true; List <GameObject> pieces = boardInfo.GetPieceAvailable(); // If piece is forfeited player's piece, make piece collapse foreach (GameObject piece in pieces) { PieceInformation thisPiece = piece.GetComponent <PieceInformation>(); if (thisPiece.type != type && thisPiece.colour == colour) { StartCoroutine(pieceAction.FallDown(piece)); } } // Display result boardInfo.Forfeit(); }
/// <summary> /// Reset/Restart from the Start Position /// </summary> public void ResetState() { Check = false; GameEnded = false; foreach (GameObject restorePiece in MoveHistory.Instance.EliminatedObjects) { if (restorePiece == null) { continue; } piecesOnBoard.Add(restorePiece); pieceAction.FadeIn(restorePiece); } foreach (GameObject piece in piecesOnBoard) { PieceInformation pieceInfo = piece.GetComponent <PieceInformation>(); if (pieceInfo.BeenPromoted) { pieceInfo.BeenPromoted = false; UndoPromotion(piece); } // Update board UpdateBoard(pieceInfo.CurrentXPosition, pieceInfo.CurrentZPosition, pieceInfo.GetOriginalX(), pieceInfo.GetOriginalZ(), piece); // Reset to piece's default values pieceInfo.CurrentXPosition = pieceInfo.GetOriginalX(); pieceInfo.CurrentZPosition = pieceInfo.GetOriginalZ(); pieceInfo.PieceMoves = 0; // Reset location Vector3 endPosition = new Vector3(pieceInfo.GetOriginalX(), 0, pieceInfo.GetOriginalZ()); pieceAction.ChangePosition(piece, endPosition, (int)pieceInfo.colour); } MoveHistory.Instance.Clear(); // Reset turn - White Start ResetTurn(); }
/// <summary> /// Checks if the king can move to the x and z position. /// Store location in list if allowed, that is, position is empty or has an enemy piece /// </summary> /// <returns> true if king can keep moving in this direction </returns> bool StorePosition(int x, int z) { // Empty position string position = x.ToString() + " " + z.ToString(); if (board[z, x] == null) { validPositions.Add(position); return(true); } // Position has a piece. Valid move if opponent's piece. Invalid if player's piece. GameObject piece = board[z, x]; PieceInformation pieceInformation = piece.GetComponent <PieceInformation>(); if (colour != (int)pieceInformation.colour) { validPositions.Add(position); } return(false); }
bool FindOpposite(Vector3 position, Vector3 direction, bool diagonal, int colour) { LayerMask layer = whiteMask; if (colour == 1) { layer = blackMask; } RaycastHit hit; if (Physics.Raycast(position, direction, out hit, 1f, layer)) { GameObject pieceCollided = hit.collider.gameObject; PieceInformation piece = pieceCollided.GetComponent <PieceInformation>(); // Moving the piece will not result in check if opposite is either // king, pawn, knight or player's piece if ((int)piece.type == 5 || (int)piece.type == 1 || (int)piece.type == 4 || (int)piece.colour == colour) { return(false); } // Rook or queen directly opposite to the king // Will compromise into a check if piece moved if (!diagonal && ((int)piece.type == 0 || (int)piece.type == 3)) { return(true); } // bishop or queen directly opposite to the king // Will compromise into a check if piece moved if (diagonal && ((int)piece.type == 3 || (int)piece.type == 2)) { return(true); } } return(false); }
/// <summary> /// Checks if the last move has checked the opponent's king /// </summary> /// <param name="pieceInfo"> Piece information for the piece checking the king </param> /// <param name="validMoves"> Positions piece can move from it's new location </param> /// <param name="colour"> Colour of the side that played the last move </param> public static bool CheckForCheck(List <string> validMoves, PieceInformation pieceInfo, BoardInformation boardInfo, string kingPos) { int type = (int)pieceInfo.type; int colour = (int)pieceInfo.colour; if (validMoves.Contains(kingPos)) { int historyIndex = MoveHistory.Instance.Index; MoveHistory.Instance.Check[historyIndex] = true; boardInfo.Check = true; StoreCheckPath(pieceInfo, kingPos); if (CheckmateStalemate(colour, boardInfo)) { boardInfo.Checkmate(colour); } else { boardInfo.CheckDisplay(); } return(true); } return(false); }
/// <summary> /// Raycasts to the direction provided from the location of the piece being manipulated /// If king found, check it's opposite side for queen/rook/bishop /// </summary> /// <param name="position"> position of the piece being manipulated </param> /// <param name="direction"> direction that needs to be checked for king </param> /// <param name="diagonal"> /// diagonal = true if checking the opposite is queen or bishop (diagonal cases) /// diagonal = false if checking the opposite is queen or rook (left/right, up/down cases) /// </param> /// <param name="colour"> colour of the piece being manipulated </param> /// <returns> true if moving the piece the player is manipulating will leave king compromised to a check </returns> bool KingHit(Vector3 position, Vector3 direction, bool diagonal, int colour) { LayerMask layer = whiteMask; if (colour == 1) { layer = blackMask; } RaycastHit hit; // Raycast onto chess pieces only - provided in the layer if (Physics.Raycast(position, direction, out hit, 1f, layer)) { GameObject pieceCollided = hit.collider.gameObject; PieceInformation piece = pieceCollided.GetComponent <PieceInformation>(); // If piece in direction is player's king, check its opposite. if ((int)piece.type == 4 && (int)piece.colour == colour) { return(FindOpposite(position, new Vector3(direction.x * -1, direction.y, direction.z * -1), diagonal, colour)); } } return(false); }
/// <summary> /// Checks if pawn can eliminate the opponent's pawn as per En Passant rule. /// </summary> /// <param name="position"> Position of the pawn </param> /// <param name="colour"> Colour of the pawn </param> /// <returns> True if pawn can be eliminated </returns> public bool EnPassant(Vector3 position, Vector3 direction, int colour) { LayerMask layer = whiteMask; if (colour == 1) { layer = blackMask; } RaycastHit hit; if (Physics.Raycast(position, direction, out hit, 0.055f, layer)) { GameObject pieceCollided = hit.collider.gameObject; PieceInformation piece = pieceCollided.GetComponent <PieceInformation>(); // Check if opponent's pawn in the direction provided. if ((int)piece.type == 5 && (int)piece.colour != colour) { // Check if the pawn is displaced two positions from its original position if (Math.Abs(piece.CurrentZPosition - piece.GetOriginalZ()) != 2) { return(false); } // Check if the pawn has only moved once. if (piece.PieceMoves != 1) { return(false); } return(true); } } return(false); }
private void ChangePiece(GameObject piece) { pieceSelected = piece; pieceInformation = pieceSelected.GetComponent <PieceInformation>(); StartCoroutine(PieceFloat()); }
/// <summary> /// Returns a list of positions the pawn can move. /// list contain strings => "xPosition yPosition" /// </summary> public List <string> RuleMove(Vector3 globalPosition, GameObject pieceObject, GameObject[,] boardState) { PieceInformation piece = pieceObject.GetComponent <PieceInformation>(); colour = (int)piece.colour; currentZPosition = piece.CurrentZPosition; currentXPosition = piece.CurrentXPosition; board = boardState; // Initialise new list validPositions = new List <string>(); // Check if king is compromised if moving top-right and bottom-left // Or top-left and bottom-right bool forwards = rules.DiagonalCheckBackward(globalPosition, colour); bool backwards = rules.DiagonalCheckForward(globalPosition, colour); // King will be left compromised if piece moves in any valid direction // return empty list if (rules.ColumnCheck(globalPosition, colour) || rules.RowCheck(globalPosition, colour)) { return(validPositions); } // Moving up-right or down-left will not leave the king compromised to a chec if (!forwards) { // Possible moves up-right for (int right = currentXPosition + 1, upwards = currentZPosition + 1; upwards <= 7 && right <= 7; upwards++, right++) { if (!StorePosition(right, upwards)) { break; } } // Possible moves bottom-left for (int left = currentXPosition - 1, downwards = currentZPosition - 1; downwards >= 0 && left >= 0; downwards--, left--) { if (!StorePosition(left, downwards)) { break; } } } // Moving up-left or down-right will not leave the king compromised to a check if (!backwards) { // Possible moves up-left for (int left = currentXPosition - 1, upwards = currentZPosition + 1; upwards <= 7 && left >= 0; upwards++, left--) { if (!StorePosition(left, upwards)) { break; } } // Possible moves bottom-right for (int right = currentXPosition + 1, downwards = currentZPosition - 1; downwards >= 0 && right <= 7; downwards--, right++) { if (!StorePosition(right, downwards)) { break; } } } return(validPositions); }
/// <summary> /// Returns a list of positions the pawn can move. /// list contain strings => "xPosition yPosition" /// </summary> public List <string> RuleMove(Vector3 globalPosition, GameObject pieceObject, GameObject[,] boardState) { PieceInformation piece = pieceObject.GetComponent <PieceInformation>(); colour = (int)piece.colour; currentZPosition = piece.CurrentZPosition; currentXPosition = piece.CurrentXPosition; board = boardState; // Initialise new list validPositions = new List <string>(); // Check if king is compromised if moving top-right and bottom-left // Or top-left and bottom-right bool forwards = rules.DiagonalCheckBackward(globalPosition, colour); bool backwards = rules.DiagonalCheckForward(globalPosition, colour); // Check if king is compromised if moving up and down // Or left and right bool rowMovement = rules.ColumnCheck(globalPosition, colour); bool columnMovement = rules.RowCheck(globalPosition, colour); // If compromised diagonally, cannot move up and down, or left and right if (!forwards && !backwards) { // Moving up or down will not leave the king compromised to a check if (!columnMovement) { // Possible moves upwards for (int upwards = currentZPosition + 1; upwards <= 7; upwards++) { if (!StorePosition(currentXPosition, upwards)) { break; } } // Possible moves downwards for (int downwards = currentZPosition - 1; downwards >= 0; downwards--) { if (!StorePosition(currentXPosition, downwards)) { break; } } } // Moving left or right will not leave the king compromised to a check if (!rowMovement) { // Possible moves left side for (int left = currentXPosition - 1; left >= 0; left--) { if (!StorePosition(left, currentZPosition)) { break; } } // Possible moves right side for (int right = currentXPosition + 1; right <= 7; right++) { if (!StorePosition(right, currentZPosition)) { break; } } } } // If compromised up/down or left/right, cannot move diagonally if (!rowMovement && !columnMovement) { // Moving up or down will not leave the king compromised to a check if (!forwards) { // Possible moves up-right for (int right = currentXPosition + 1, upwards = currentZPosition + 1; upwards <= 7 && right <= 7; upwards++, right++) { if (!StorePosition(right, upwards)) { break; } } // Possible moves bottom-left for (int left = currentXPosition - 1, downwards = currentZPosition - 1; downwards >= 0 && left >= 0; downwards--, left--) { if (!StorePosition(left, downwards)) { break; } } } // Moving up or down will not leave the king compromised to a check if (!backwards) { // Possible moves up-left for (int left = currentXPosition - 1, upwards = currentZPosition + 1; upwards <= 7 && left >= 0; upwards++, left--) { if (!StorePosition(left, upwards)) { break; } } // Possible moves bottom-right for (int right = currentXPosition + 1, downwards = currentZPosition - 1; downwards >= 0 && right <= 7; downwards--, right++) { if (!StorePosition(right, downwards)) { break; } } } } return(validPositions); }
/// <summary> /// Returns a list of positions the pawn can move. /// list contain strings => "xPosition yPosition" /// </summary> /// <param name="check"> States if the board state is in check. </param> public List <string> RuleMove(Vector3 position, GameObject pieceObject, GameObject[,] boardState, bool check) { PieceInformation piece = pieceObject.GetComponent <PieceInformation>(); colour = (int)piece.colour; currentZPosition = piece.CurrentZPosition; currentXPosition = piece.CurrentXPosition; board = boardState; // Initialise new list validPositions = new List <string>(); // Check if positions the king can move to will compromise the king to a check for (int xDisplacement = -1; xDisplacement <= 1; xDisplacement++) { for (int zDisplacement = -1; zDisplacement <= 1; zDisplacement++) { // Skip if checking current position if (xDisplacement == 0 && zDisplacement == 0) { continue; } // Skip if position out of bound if (currentXPosition + xDisplacement < 0 || currentXPosition + xDisplacement > 7 || currentZPosition + zDisplacement < 0 || currentZPosition + zDisplacement > 7) { continue; } /// <summary> /// Skip if player's piece in position /// </summary> GameObject pieceAtLocation = board[currentZPosition + zDisplacement, currentXPosition + xDisplacement]; if (pieceAtLocation != null) { PieceInformation pieceInformation = pieceAtLocation.GetComponent <PieceInformation>(); if ((int)pieceInformation.colour == colour) { continue; } } // Check if king can move to this position without getting compromised if (rules.KingMove(currentXPosition + xDisplacement, currentZPosition + zDisplacement, colour, board)) { StorePosition(currentXPosition + xDisplacement, currentZPosition + zDisplacement); } } } /// <summary> /// Add castling to valid move if allowed /// </summary> if (!check && !piece.HasMoved()) { // Check if king can castle left Vector3 left = new Vector3(-1, 0, 0); if (rules.Castling(position, left, colour)) { // Check if king's new position is controlled by the opponent // If not, add to list of valid moves if (rules.KingMove(currentXPosition - 2, currentZPosition, colour, board)) { StorePosition(currentXPosition - 2, currentZPosition); } } /// <summary> /// Check if king can castle right /// </summary> Vector3 right = new Vector3(1, 0, 0); if (rules.Castling(position, right, colour)) { // Check if king's new position is controlled by the opponent // If not, add to list of valid moves if (rules.KingMove(currentXPosition + 2, currentZPosition, colour, board)) { StorePosition(currentXPosition + 2, currentZPosition); } } } return(validPositions); }
/// <summary> /// Returns a list of positions the pawn can move. /// list contain strings => "xPosition yPosition" /// </summary> /// <param name="check"> States if the board state is in check. </param> public List <string> RuleMove(GameObject pieceObject, GameObject[,] boardState) { PieceInformation piece = pieceObject.GetComponent <PieceInformation>(); colour = (int)piece.colour; currentZPosition = piece.CurrentZPosition; currentXPosition = piece.CurrentXPosition; board = boardState; // Initialise new list validPositions = new List <string>(); // Cases: DDL, DDR, UUL, UUR int zDisplacement = 2; int xDisplacement = 1; // Check if valid position // Case: UUL if (TwoStepsDisplacement(currentXPosition - xDisplacement, currentZPosition + zDisplacement)) { StorePosition(currentXPosition - xDisplacement, currentZPosition + zDisplacement); } // Case: UUR if (TwoStepsDisplacement(currentXPosition + xDisplacement, currentZPosition + zDisplacement)) { StorePosition(currentXPosition + xDisplacement, currentZPosition + zDisplacement); } // Case: DDL if (TwoStepsDisplacement(currentXPosition - xDisplacement, currentZPosition - zDisplacement)) { StorePosition(currentXPosition - xDisplacement, currentZPosition - zDisplacement); } // Case: DDR if (TwoStepsDisplacement(currentXPosition + xDisplacement, currentZPosition - zDisplacement)) { StorePosition(currentXPosition + xDisplacement, currentZPosition - zDisplacement); } // Cases: LLU, LLD, RRU, RRD zDisplacement = 1; xDisplacement = 2; // Case: LLU if (TwoStepsDisplacement(currentXPosition - xDisplacement, currentZPosition + zDisplacement)) { StorePosition(currentXPosition - xDisplacement, currentZPosition + zDisplacement); } // Case: LLD if (TwoStepsDisplacement(currentXPosition - xDisplacement, currentZPosition - zDisplacement)) { StorePosition(currentXPosition - xDisplacement, currentZPosition - zDisplacement); } // Case: RRU if (TwoStepsDisplacement(currentXPosition + xDisplacement, currentZPosition + zDisplacement)) { StorePosition(currentXPosition + xDisplacement, currentZPosition + zDisplacement); } // Case: RRD if (TwoStepsDisplacement(currentXPosition + xDisplacement, currentZPosition - zDisplacement)) { StorePosition(currentXPosition + xDisplacement, currentZPosition - zDisplacement); } return(validPositions); }