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
 void RunMove()
 {
     if (GameManager.Instance.Move(from, to))
     {
         ChessCoordinate newTo = to - from;
         from.x = to.x;
         from.y = to.y;
         to.x  += newTo.x;
         to.y  += newTo.y;
     }
 }
Esempio n. 4
0
    /// <summary>
    /// Make a move from the latest snapshot
    /// </summary>
    /// <param name="from">Current position's coordinate</param>
    /// <param name="to">Destination position's coordinate</param>
    /// <returns>
    /// TRUE if move has successfully been executed.
    /// </returns>
    public bool Move(ChessCoordinate from, ChessCoordinate to)
    {
        ChessPosition[] resultPositions;

        if (Move(from, to, out resultPositions))
        {
            GenNextSnapshot(resultPositions);
            AIManager.Instance.MakeMove();
            return(true);
        }

        return(false);
    }
Esempio n. 5
0
 public void PlacePiece(PlayerType senderType, ChessCoordinate coordinate)
 {
     if (coordinate.XPosition < 0 || coordinate.XPosition > 14 || coordinate.YPosition < 0 || coordinate.YPosition > 14 ||
         Timer < 0.3f || chessStatus[coordinate.XPosition, coordinate.YPosition] != 0 || !ValidateTurn(senderType) || gameEnded)
     {
         return;
     }
     chessStatus[coordinate.XPosition, coordinate.YPosition] = (int)senderType;
     stackCoordinate.Push(coordinate);
     board.PlacePiece(coordinate, isOffensiveTurn);
     if (IsWin(coordinate))
     {
         board.ShowEnd(isOffensiveTurn);
         gameEnded = true;
     }
     isOffensiveTurn = !isOffensiveTurn;
     Timer           = 0;
 }
Esempio n. 6
0
    /// <summary>
    ///
    /// </summary>
    /// <param name="xPosition">以棋盘左下角为(0,0)点的X坐标</param>
    /// <param name="yPosition">以棋盘左下角为(0,0)点的Y坐标</param>
    /// <param name="isOffensiveTurn"></param>
    public void PlacePiece(ChessCoordinate coordinate, bool isOffensiveTurn)
    {
        int        xTransform = coordinate.XPosition - 7;
        int        yTransform = coordinate.YPosition - 7;
        GameObject newPiece   = Instantiate(isOffensiveTurn ? prefabBlackPiece : prefabWhitePiece,
                                            new Vector3(xTransform, yTransform), Quaternion.identity);

        pilotDot.position         = new Vector3(xTransform, yTransform);
        newPiece.transform.parent = transform;
        pieces.Push(new ExtendPiece()
        {
            XTransform = xTransform, YTransform = yTransform, Piece = newPiece
        });
        if (pieces.Count >= 2)
        {
            btnRetract.interactable = true;
        }
    }
Esempio n. 7
0
 bool IsWin(ChessCoordinate coordinate)
 {
     if (SamePiece(coordinate.XPosition, coordinate.YPosition, 1, 0) >= 5)
     {
         return(true);
     }
     if (SamePiece(coordinate.XPosition, coordinate.YPosition, 0, 1) >= 5)
     {
         return(true);
     }
     if (SamePiece(coordinate.XPosition, coordinate.YPosition, 1, 1) >= 5)
     {
         return(true);
     }
     if (SamePiece(coordinate.XPosition, coordinate.YPosition, 1, -1) >= 5)
     {
         return(true);
     }
     return(false);
 }
Esempio n. 8
0
    public ChessBoardSnapshot[] FindPossibleMoves(ChessBoardSnapshot boardSnapshot, ChessPlayerType playerType)
    {
        List <ChessBoardSnapshot>       ret       = new List <ChessBoardSnapshot>();
        Dictionary <int, ChessPosition> boardDict = boardSnapshot.ToDictionary();

        foreach (KeyValuePair <int, ChessPosition> kvp in boardDict)
        {
            ChessPosition position = kvp.Value;

            if (position.type.IsDifferentTeamAs(playerType))
            {
                continue;
            }

            ChessCoordinate from = position.coord;

            ChessPieceMove[] possibleMoves = GameManager.Instance.profilesDict[position.type].possibleMoves;

            for (int j = 0; j < possibleMoves.Length; j++)
            {
                ChessCoordinate to = from + possibleMoves[j].move;
                int             k  = 1;

                while
                (
                    to.IsWithinRange() &&
                    (possibleMoves[j].repeatTimes < 0 || k <= possibleMoves[j].repeatTimes)
                )
                {
                    if (GameManager.Instance.IsValidSpecialRule(possibleMoves[j].specialRule, position, from, to))
                    {
                        // When there are only finite amount of moves, set only when reached destination
                        if (possibleMoves[j].repeatTimes < 0 || k == possibleMoves[j].repeatTimes)
                        {
                            bool isLastMove = false;

                            if (possibleMoves[j].pattern == ChessPieceMovePattern.Normal)
                            {
                                if (boardDict.ContainsKey(to.ToArrayCoord()))
                                {
                                    if (boardDict[to.ToArrayCoord()].type.IsSameTeamAs(position.type))
                                    {
                                        break;
                                    }

                                    isLastMove = true;
                                }
                            }
                            else if (possibleMoves[j].pattern == ChessPieceMovePattern.MoveOnly)
                            {
                                if (boardDict.ContainsKey(to.ToArrayCoord()))
                                {
                                    break;
                                }
                            }
                            else if (possibleMoves[j].pattern == ChessPieceMovePattern.CaptureOnly)
                            {
                                if (!boardDict.ContainsKey(to.ToArrayCoord()))
                                {
                                    break;
                                }

                                if (boardDict[to.ToArrayCoord()].type.IsSameTeamAs(position.type))
                                {
                                    break;
                                }
                            }

                            // Pawn Promotion
                            if (position.type.IsPawn())
                            {
                                if
                                (
                                    position.type == ChessPieceType.WhitePawn &&
                                    position.coord.y == 0
                                )
                                {
                                    position.type = ChessPieceType.WhiteQueen;
                                }
                                else if
                                (
                                    position.type == ChessPieceType.BlackPawn &&
                                    position.coord.y == 7
                                )
                                {
                                    position.type = ChessPieceType.BlackQueen;
                                }
                            }

                            ret.Add(GameManager.Instance.AdjustBoard
                                    (
                                        boardSnapshot,
                                        position.type.ToIcon() + " " + from.x + "," + from.y + "-->" + to.x + "," + to.y,
                                        new ChessPosition(ChessPieceType.None, from, true),
                                        new ChessPosition(position.type, to, true)
                                    ));

                            if (isLastMove)
                            {
                                break;
                            }
                        }
                        else
                        {
                            if (boardDict.ContainsKey(to.ToArrayCoord()))
                            {
                                break;
                            }
                        }
                    }

                    to += possibleMoves[j].move;
                    k++;
                }
            }
        }

        return(ret.ToArray());
    }
Esempio n. 9
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. 10
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);
    }