Esempio n. 1
0
    /// <summary>
    /// Make an additional special move from the latest snapshot (Without generating the next snapshot)
    /// </summary>
    /// <param name="specialRule">The special rule used</param>
    /// <param name="position">The specified piece's data</param>
    /// <param name="resultPositions">The returning result of positions</param>
    /// <returns>
    /// TRUE if move is valid.
    /// </returns>
    private bool AdditionalMove(ChessPieceSpecialRule specialRule, ChessPosition position, out ChessPosition[] resultPositions)
    {
        resultPositions = null;

        if (specialRule == ChessPieceSpecialRule.CastlingLeft || specialRule == ChessPieceSpecialRule.CastlingRight)
        {
            int xFromCoord = position.coord.x;
            int xToCoord   = position.coord.x;

            if (specialRule == ChessPieceSpecialRule.CastlingLeft)
            {
                xFromCoord = 0;
                xToCoord  -= 1;
            }
            else if (specialRule == ChessPieceSpecialRule.CastlingRight)
            {
                xFromCoord = ChessSettings.boardSize - 1;
                xToCoord  += 1;
            }

            ChessCoordinate rookFromCoord = new ChessCoordinate(xFromCoord, position.coord.y);
            ChessCoordinate rookToCoord   = new ChessCoordinate(xToCoord, position.coord.y);

            return(Move(rookFromCoord, rookToCoord, out resultPositions));
        }

        return(true);
    }
Esempio n. 2
0
    /// <summary>
    /// Check whether the special rule is matching for the specific piece
    /// </summary>
    /// <param name="specialRule">The special rule used</param>
    /// <param name="position">The specified piece's data</param>
    /// <param name="from">The specified piece's coordinate</param>
    /// <param name="to">The destination's coordinate</param>
    /// <returns>
    /// TRUE if move is valid regarding special rule.
    /// </returns>
    public bool IsValidSpecialRule(ChessPieceSpecialRule specialRule, ChessPosition position, ChessCoordinate from, ChessCoordinate to)
    {
        if (specialRule == ChessPieceSpecialRule.None)
        {
            return(true);
        }

        // Pawn - Move 2 square when starting from initial position
        if (specialRule == ChessPieceSpecialRule.Pawn2Squares)
        {
            if (position.hasMoved)
            {
                return(false);
            }

            return(true);
        }

        if (specialRule == ChessPieceSpecialRule.CastlingLeft || specialRule == ChessPieceSpecialRule.CastlingRight)
        {
            if (position.hasMoved)
            {
                return(false);
            }

            int xCoord = position.coord.x;

            if (specialRule == ChessPieceSpecialRule.CastlingLeft)
            {
                xCoord = 0;
            }
            else if (specialRule == ChessPieceSpecialRule.CastlingRight)
            {
                xCoord = ChessSettings.boardSize - 1;
            }

            int rookCoord = new ChessCoordinate(xCoord, position.coord.y).ToArrayCoord();

            if (!piecesDict.ContainsKey(rookCoord))
            {
                return(false);
            }

            if (!piecesDict[rookCoord].Type.IsRook())
            {
                return(false);
            }

            if (piecesDict[rookCoord].HasMoved)
            {
                return(false);
            }

            return(true);
        }

        return(false);
    }
Esempio n. 3
0
    /// <summary>
    /// Check whether it's a valid move for the specified piece
    /// </summary>
    /// <param name="position">The specified piece's data</param>
    /// <param name="from">The specified piece's coordinate</param>
    /// <param name="to">The destination's coordinate</param>
    /// <param name="specialRule">The special rule used</param>
    /// <returns>
    /// TRUE if move is valid.
    /// </returns>
    public bool IsValidMove(ChessPosition position, ChessCoordinate from, ChessCoordinate to, out ChessPieceSpecialRule specialRule)
    {
        specialRule = ChessPieceSpecialRule.None;
        ChessPieceMove[] possibleMoves = profilesDict[position.type].possibleMoves;
        for (int i = 0; i < possibleMoves.Length; i++)
        {
            specialRule = possibleMoves[i].specialRule;
            if (!IsValidSpecialRule(possibleMoves[i].specialRule, position, from, to))
            {
                continue;
            }

            ChessCoordinate temp = from + possibleMoves[i].move;
            int             j    = 0;

            while
            (
                temp.IsWithinRange() &&
                (possibleMoves[i].repeatTimes < 0 || j < possibleMoves[i].repeatTimes)
            )
            {
                if (temp == to)
                {
                    if (possibleMoves[i].pattern == ChessPieceMovePattern.Normal)
                    {
                        if (piecesDict.ContainsKey(temp.ToArrayCoord()))
                        {
                            if (piecesDict[temp.ToArrayCoord()].Type.IsSameTeamAs(position.type))
                            {
                                break;
                            }
                        }

                        return(true);
                    }
                    else if (possibleMoves[i].pattern == ChessPieceMovePattern.MoveOnly)
                    {
                        if (piecesDict.ContainsKey(temp.ToArrayCoord()))
                        {
                            break;
                        }

                        return(true);
                    }
                    else if (possibleMoves[i].pattern == ChessPieceMovePattern.CaptureOnly)
                    {
                        if (!piecesDict.ContainsKey(temp.ToArrayCoord()))
                        {
                            break;
                        }

                        if (piecesDict[temp.ToArrayCoord()].Type.IsSameTeamAs(position.type))
                        {
                            break;
                        }

                        return(true);
                    }
                }
                else
                {
                    if (piecesDict.ContainsKey(temp.ToArrayCoord()))
                    {
                        break;
                    }
                }

                temp += possibleMoves[i].move;
                j++;
            }
        }

        return(false);
    }
Esempio n. 4
0
    /// <summary>
    /// Make a move from the latest snapshot (Without generating the next snapshot)
    /// </summary>
    /// <param name="from">Current position's coordinate</param>
    /// <param name="to">Destination position's coordinate</param>
    /// <param name="resultPositions">The returning result of positions</param>
    /// <returns>
    /// TRUE if move is valid.
    /// </returns>
    private bool Move(ChessCoordinate from, ChessCoordinate to, out ChessPosition[] resultPositions)
    {
        resultPositions = null;

        if (!from.IsWithinRange())
        {
            Debug.LogWarning("Failed to execute Move.\nReason: (" + from.x + ", " + from.y + ") is not within RANGE.");
            return(false);
        }

        if (!to.IsWithinRange())
        {
            Debug.LogWarning("Failed to execute Move.\nReason: (" + to.x + ", " + to.y + ") is not within RANGE.");
            return(false);
        }

        if (!piecesDict.ContainsKey(from.ToArrayCoord()))
        {
            Debug.LogWarning("Failed to execute Move.\nReason: (" + from.x + ", " + from.y + ") is EMPTY.");
            return(false);
        }

        ChessPieceScript      selectedPiece = piecesDict[from.ToArrayCoord()];
        ChessPieceSpecialRule specialRule   = ChessPieceSpecialRule.None;

        ChessPosition[] castlingPositions;

        if
        (
            !IsValidMove(selectedPiece.Position, from, to, out specialRule) ||
            !AdditionalMove(specialRule, selectedPiece.Position, out castlingPositions)
        )
        {
            Debug.LogWarning("Failed to execute Move.\nReason: " + selectedPiece.Type + " (" + from.x + ", " + from.y + ") --> (" + to.x + ", " + to.y + ") is INVALID.");
            return(false);
        }

        selectedPiece.Coord    = to;
        selectedPiece.HasMoved = true;

        // Pawn Promotion
        if (selectedPiece.Type.IsPawn())
        {
            if
            (
                selectedPiece.Type == ChessPieceType.WhitePawn &&
                selectedPiece.Coord.y == 0
            )
            {
                selectedPiece.Type = ChessPieceType.WhiteQueen;
            }
            else if
            (
                selectedPiece.Type == ChessPieceType.BlackPawn &&
                selectedPiece.Coord.y == 7
            )
            {
                selectedPiece.Type = ChessPieceType.BlackQueen;
            }
        }

        if (piecesDict.ContainsKey(to.ToArrayCoord()))
        {
            Destroy(piecesDict[to.ToArrayCoord()].gameObject);
        }

        piecesDict.Remove(from.ToArrayCoord());
        piecesDict.Remove(to.ToArrayCoord());
        piecesDict.Add(to.ToArrayCoord(), selectedPiece);

        List <ChessPosition> resultPositionsList = new List <ChessPosition>()
        {
            new ChessPosition(ChessPieceType.None, from),
            new ChessPosition(selectedPiece.Type, to)
        };

        if (castlingPositions != null)
        {
            for (int i = 0; i < castlingPositions.Length; i++)
            {
                resultPositionsList.Add(castlingPositions[i]);
            }
        }

        resultPositions = resultPositionsList.ToArray();

        Debug.Log("Succeeded to execute Move.\n" + selectedPiece.Type + " (" + from.x + ", " + from.y + ") --> (" + to.x + ", " + to.y + ").");

        return(true);
    }