Beispiel #1
0
 /// <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);
        }
Beispiel #3
0
        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;
        }
Beispiel #10
0
 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");
            }
        }
Beispiel #15
0
        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;
        }
Beispiel #16
0
        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;
        }
Beispiel #18
0
        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);
                    }
                }
            }
        }
Beispiel #19
0
        /// <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());
 }
Beispiel #27
0
        /// <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);
        }
Beispiel #28
0
        /// <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);
        }