示例#1
0
    public static Side GetWinningSide(PieceRank rankA, PieceRank rankB)
    {
        if (rankA == PieceRank.Flag && rankB == PieceRank.Flag) // Flag to Flag
        {
            return(Side.A);
        }
        if (rankA == PieceRank.Spy && rankB == PieceRank.Private)
        {
            return(Side.B);
        }
        if (rankA == PieceRank.Private && rankB == PieceRank.Spy)
        {
            return(Side.A);
        }
        if (rankA == rankB) // Same ranks
        {
            return(Side.None);
        }
        if (rankA < rankB)
        {
            return(Side.A);
        }

        return(Side.B);
    }
        public void ChangePromotion(PieceRank promotionRank)
        {
            if (promotionRank == PieceRank.King || promotionRank == PieceRank.None || promotionRank == PieceRank.Pawn)
            {
                // Not valid promotion.
                return;
            }

            if (_moves.Count > 0)
            {
                List <ChessMove> lastMoves = _moves.Peek();
                for (int i = 0; i < lastMoves.Count; i++)
                {
                    ChessMove promotionMove = lastMoves[i];
                    if (promotionMove.SpecialMove == ChessSpecialMove.PromotionIn)
                    {
                        lastMoves[i] = new ChessMove(promotionRank, promotionMove.Player,
                                                     promotionMove.From.HorizontalLocation, promotionMove.From.VerticalLocation,
                                                     promotionMove.To.HorizontalLocation, promotionMove.To.VerticalLocation,
                                                     promotionMove.SpecialMove);

                        _pieces[promotionMove.To.HorizontalLocation, promotionMove.To.VerticalLocation] =
                            new ChessBoardPiece(promotionMove.Player, promotionRank);
                        return;
                    }
                }
            }
        }
示例#3
0
 public GamePiece(PieceColour pieceColour, PieceRank pieceRank, int xCoord, int yCoord)
 {
     PieceColour = pieceColour;
     PieceRank   = pieceRank;
     Xcoord      = xCoord;
     Ycoord      = yCoord;
 }
示例#4
0
 public void Awake()
 {
     for (PieceRank i = PieceRank.Spy; i <= PieceRank.Flag; i++)
     {
         texts.Add(Instantiate(textPrefab, transform));
     }
 }
 private void DiscoverRank()
 {
     if (PossibleRanks.Count == 1)
     {
         GuaranteedRank = PossibleRanks[0];
     }
 }
示例#6
0
        private PieceRank CalculatePieceRank(int yPosition, PieceColour pieceColour, PieceRank pieceRank)
        {
            PieceRank resultPieceRank = PieceRank.Minion;

            if (pieceRank == PieceRank.King)
            {
                resultPieceRank = PieceRank.King;
            }
            else
            {
                switch (pieceColour)
                {
                case PieceColour.White:
                    if (yPosition == YLength - 1)
                    {
                        resultPieceRank = PieceRank.King;
                    }
                    break;

                case PieceColour.Black:
                    if (yPosition == 0)
                    {
                        resultPieceRank = PieceRank.King;
                    }
                    break;
                }
            }
            return(resultPieceRank);
        }
 public ChessMove(PieceRank rank, PiecePlayer player, int horizontalLocationFrom, int verticalLocationFrom, int horizontalLocationTo, int verticalLocationTo, ChessSpecialMove specialMove)
 {
     Rank        = rank;
     Player      = player;
     From        = new ChessBoardLocation(horizontalLocationFrom, verticalLocationFrom);
     To          = new ChessBoardLocation(horizontalLocationTo, verticalLocationTo);
     SpecialMove = specialMove;
 }
示例#8
0
 public void UpdateText(List <int> piecePool)
 {
     for (PieceRank i = PieceRank.Spy; i <= PieceRank.Flag; i++)
     {
         TextMeshProUGUI text = texts[(int)i];
         text.text = i.ToString() + ' ' + piecePool[(int)i];
     }
 }
示例#9
0
    private static PieceInfo ExtractPieceFromList(
        List <PieceInfo> toSpawn,
        PieceRank rank)
    {
        PieceInfo flag = toSpawn.Find(info => info.Rank == rank);

        toSpawn.Remove(flag);
        return(flag);
    }
    public void RemovePiecePossibility(PieceRank rank)
    {
        if (!possibilities[(int)rank])
        {
            return;
        }

        possibilities[(int)rank] = false;
        PossibleRanks.Remove(rank);
    }
示例#11
0
    private void UpdateEnemyInfo(BoardChange boardChange)
    {
        if (!boardChange.WasThereAnAttack())
        {
            return;
        }

        PieceInfo         thisPiece      = boardChange.GetPieceFromAction(side);
        PieceInfo         otherPiece     = boardChange.GetPieceFromAction(side.Flip());
        RankPossibilities otherPieceRank = enemyPieces[otherPiece.ID];

        if (boardChange.GetWinningPiece() == null)
        {
            otherPieceRank.TiedBattle(thisPiece.Rank);
        }
        else if (otherPiece == boardChange.GetWinningPiece())
        {
            otherPieceRank.WonBattle(thisPiece.Rank);
        }
        else // This piece is the winner
        {
            otherPieceRank.LostBattle(thisPiece.Rank);
        }

        // Remove from piece pool once piece has been discovered
        PieceRank guaranteedRank = otherPieceRank.GuaranteedRank;

        if (guaranteedRank == PieceRank.Invalid)
        {
            return;
        }

        // DEBUG
        piecePool[(int)guaranteedRank]--;
        pieceCounterPanel.UpdateText(piecePool);

        // If piece pool reaches 0, all other pieces can't be this piece
        if (piecePool[(int)guaranteedRank] > 0)
        {
            return;
        }

        foreach (RankPossibilities rankPossibilities in enemyPieces.Values)
        {
            if (rankPossibilities.GuaranteedRank == guaranteedRank)
            {
                continue;
            }

            rankPossibilities.RemovePiecePossibility(guaranteedRank);
        }
    }
    public void TiedBattle(PieceRank otherRank)
    {
        foreach (PieceRank thisRank in PieceRanks.AllRanks)
        {
            if (thisRank == otherRank)
            {
                continue;
            }

            RemovePiecePossibility(thisRank);
        }

        DiscoverRank();
    }
    public void LostBattle(PieceRank otherRank)
    {
        if (otherRank == PieceRank.Spy)
        {
            RemovePiecePossibility(PieceRank.Spy);
            RemovePiecePossibility(PieceRank.Private);
        }
        else if (otherRank == PieceRank.Private)
        {
            RemovePiecePossibility(PieceRanks.AllRanksWithoutSpy);
        }
        else
        {
            for (PieceRank thisRank = otherRank; thisRank >= 0; thisRank--)
            {
                RemovePiecePossibility(thisRank);
            }
        }

        DiscoverRank();
    }
    public void WonBattle(PieceRank otherRank)
    {
        if (otherRank == PieceRank.Spy)
        {
            RemovePiecePossibility(PieceRanks.AllRanksWithoutPrivate);
        }
        else if (otherRank == PieceRank.Private)
        {
            RemovePiecePossibility(PieceRank.Spy);
            RemovePiecePossibility(PieceRank.Private);
            RemovePiecePossibility(PieceRank.Flag);
        }
        else
        {
            for (PieceRank thisRank = otherRank; thisRank <= PieceRank.Flag; thisRank++)
            {
                RemovePiecePossibility(thisRank);
            }
        }

        DiscoverRank();
    }
 public bool IsPiecePossible(PieceRank rank)
 {
     return(possibilities[(int)rank]);
 }
示例#16
0
    private float EvaluateMove(Board boardCopy, MoveInfo move, int depth)
    {
        float resultSum = 0f;

        if (side == Side.A)
        {
            if (move.GetDifference().y > 0)
            {
                resultSum += forwardBonus;
            }
        }
        else
        {
            if (move.GetDifference().y < 0)
            {
                resultSum += forwardBonus;
            }
        }

        // If piece exists in next position, this is an attacking move
        if (boardCopy.DoesPieceExistInPosition(move.NewPosition))
        {
            // Get needed vars
            PieceInfo         oldPosPiece            = boardCopy.GetPieceFromPosition(move.OldPosition);
            PieceInfo         newPosPiece            = boardCopy.GetPieceFromPosition(move.NewPosition);
            PieceInfo         myPiece                = boardCopy.CurrentSide == side ? oldPosPiece : newPosPiece;
            PieceInfo         otherPiece             = boardCopy.CurrentSide == side ? newPosPiece : oldPosPiece;
            PieceRank         myRank                 = myPiece.Rank;
            RankPossibilities otherRankPossibilities = enemyPieces[otherPiece.ID];

            // Get win chance
            float winChance = CalculateWinChance(otherRankPossibilities, myRank);
            if (boardCopy.CurrentSide != side)
            {
                winChance = 1f - winChance;
            }

            if (winChance >= 0.99f) // Guaranteed to win!
            {
                resultSum += SimulateWin(boardCopy, move, depth);
            }
            else if (winChance <= 0.01f) // Guaranteed to lose!
            {
                // Optimization: don't explore moves where guaranteed to lose!
                return(-losingBattlePenalty * 10f);
            }
            else // Simulate both outcomes and multiply each with it's chance
            {
                // Simulated win
                resultSum += SimulateWin(boardCopy, move, depth) * winChance;

                // Simulated loss
                float lossChance = 1f - winChance;
                resultSum += SimulateLoss(boardCopy, move, depth) * lossChance;
            }
        }
        else
        {
            float myResult = SimulateNormal(boardCopy, move, depth);
            resultSum += myResult;
        }

        return(resultSum);
    }
        private void GetHorizontalAndVerticalMoves(PieceRank rank, PiecePlayer player, List <ChessMove> moves, int column, int row)
        {
            // To left
            for (int i = column - 1; i >= 0; i--)
            {
                if (IsOccupiedByOpponent(player, i, row) == true)
                {
                    moves.Add(new ChessMove(rank, player, column, row, i, row));
                }
                else if (IsEmpty(i, row) == true)
                {
                    moves.Add(new ChessMove(rank, player, column, row, i, row));
                    continue;
                }

                break;
            }

            // To right
            for (int i = column + 1; i < BOARD_SIZE; i++)
            {
                if (IsOccupiedByOpponent(player, i, row) == true)
                {
                    moves.Add(new ChessMove(rank, player, column, row, i, row));
                }
                else if (IsEmpty(i, row) == true)
                {
                    moves.Add(new ChessMove(rank, player, column, row, i, row));
                    continue;
                }

                break;
            }

            // To up
            for (int i = row - 1; i >= 0; i--)
            {
                if (IsOccupiedByOpponent(player, column, i) == true)
                {
                    moves.Add(new ChessMove(rank, player, column, row, column, i));
                }
                else if (IsEmpty(column, i) == true)
                {
                    moves.Add(new ChessMove(rank, player, column, row, column, i));
                    continue;
                }

                break;
            }

            // To down
            for (int i = row + 1; i < BOARD_SIZE; i++)
            {
                if (IsOccupiedByOpponent(player, column, i) == true)
                {
                    moves.Add(new ChessMove(rank, player, column, row, column, i));
                }
                else if (IsEmpty(column, i) == true)
                {
                    moves.Add(new ChessMove(rank, player, column, row, column, i));
                    continue;
                }

                break;
            }
        }
        private void GetDiagonalMoves(PieceRank rank, PiecePlayer player, List <ChessMove> moves, int column, int row)
        {
            // To north-east
            for (int i = 1; i <= BOARD_SIZE; i++)
            {
                if (IsOccupiedByOpponent(player, column + i, row - i) == true)
                {
                    moves.Add(new ChessMove(rank, player, column, row, column + i, row - i));
                }
                else if (IsEmpty(column + i, row - i) == true)
                {
                    moves.Add(new ChessMove(rank, player, column, row, column + i, row - i));
                    continue;
                }

                break;
            }

            // To south-east
            for (int i = 1; i <= BOARD_SIZE; i++)
            {
                if (IsOccupiedByOpponent(player, column + i, row + i) == true)
                {
                    moves.Add(new ChessMove(rank, player, column, row, column + i, row + i));
                }
                else if (IsEmpty(column + i, row + i) == true)
                {
                    moves.Add(new ChessMove(rank, player, column, row, column + i, row + i));
                    continue;
                }

                break;
            }

            // To north-west
            for (int i = 1; i <= BOARD_SIZE; i++)
            {
                if (IsOccupiedByOpponent(player, column - i, row - i) == true)
                {
                    moves.Add(new ChessMove(rank, player, column, row, column - i, row - i));
                }
                else if (IsEmpty(column - i, row - i) == true)
                {
                    moves.Add(new ChessMove(rank, player, column, row, column - i, row - i));
                    continue;
                }

                break;
            }

            // To south-west
            for (int i = 1; i <= BOARD_SIZE; i++)
            {
                if (IsOccupiedByOpponent(player, column - i, row + i) == true)
                {
                    moves.Add(new ChessMove(rank, player, column, row, column - i, row + i));
                }
                else if (IsEmpty(column - i, row + i) == true)
                {
                    moves.Add(new ChessMove(rank, player, column, row, column - i, row + i));
                    continue;
                }

                break;
            }
        }
示例#19
0
 public ChessBoardPiece(PiecePlayer player, PieceRank rank)
 {
     Player = player;
     Rank   = rank;
 }
 public static float GetValue(this PieceRank rank)
 {
     return(RankValues[(int)rank]);
 }
示例#21
0
    public void GenerateSmartSpawns()
    {
        // Get all my pieces
        List <PieceInfo> piecesToSpawn = new List <PieceInfo>(myPieces.AllPieces.Count);

        foreach (PieceInfo piece in myPieces.AllPieces)
        {
            piecesToSpawn.Add(piece);
        }

        // Get rows
        int backRow = side == Side.A ? 0 : 7;
        int midRow  = side == Side.A ? 1 : 6;

        // 75% to spawn flag on back row
        // 25% to spawn flag on mid row
        PieceInfo     flag    = ExtractPieceFromList(piecesToSpawn, PieceRank.Flag);
        BoardPosition flagPos = new BoardPosition(
            Random.Range(0, Board.WIDTH),
            Random.value > 0.25f ? backRow : midRow);

        gameManager.SpawnPiece(new SpawnInfo(flag, flagPos));

        // Get guard pieces for the flag
        PieceInfo guard1 = ExtractPieceFromList(piecesToSpawn, PieceRank.Spy);
        PieceInfo guard2 = ExtractPieceFromList(piecesToSpawn, PieceRank.Private);

        // 3rd guard can be 3, 4, or 5 star general, equally likely
        PieceRank guard3Rank   = PieceRank.General5;
        float     guard3Chance = Random.value;

        if (guard3Chance > 0.3333f)
        {
            guard3Rank = PieceRank.General3;
        }
        else if (guard3Chance > 0.6666f)
        {
            guard3Rank = PieceRank.General4;
        }
        PieceInfo guard3 = ExtractPieceFromList(piecesToSpawn, guard3Rank);

        // Get guard spawns
        List <BoardPosition> guardSpawns = new List <BoardPosition>();

        // Add sides
        AddBoardPositionIfValid(guardSpawns, flagPos.Left);
        AddBoardPositionIfValid(guardSpawns, flagPos.Right);

        // Add next row
        if (side == Side.A)
        {
            AddBoardPositionIfValid(guardSpawns, flagPos.UpperLeft);
            AddBoardPositionIfValid(guardSpawns, flagPos.Up);
            AddBoardPositionIfValid(guardSpawns, flagPos.UpperRight);
        }
        else
        {
            AddBoardPositionIfValid(guardSpawns, flagPos.DownLeft);
            AddBoardPositionIfValid(guardSpawns, flagPos.Down);
            AddBoardPositionIfValid(guardSpawns, flagPos.DownRight);
        }

        // Randomize spawns
        guardSpawns.Shuffle();

        // Spawn guard pieces
        gameManager.SpawnPiece(new SpawnInfo(guard1, guardSpawns[0]));
        gameManager.SpawnPiece(new SpawnInfo(guard2, guardSpawns[1]));
        gameManager.SpawnPiece(new SpawnInfo(guard3, guardSpawns[2]));

        // List all possible spawns
        float leftValue  = 0f;
        float midValue   = 0f;
        float rightValue = 0f;
        List <BoardPosition> leftFlank  = new List <BoardPosition>();
        List <BoardPosition> midFlank   = new List <BoardPosition>();
        List <BoardPosition> rightFlank = new List <BoardPosition>();

        // Left flank
        for (int i = 0; i < Board.WIDTH / 3; i++)
        {
            for (int j = minSpawnHeight; j <= maxSpawnHeight; j++)
            {
                PieceInfo pieceInfo = board.GetPieceFromPosition(i, j);
                if (pieceInfo != null)
                {
                    leftValue += pieceInfo.Rank.GetValue();
                }
                else
                {
                    leftFlank.Add(new BoardPosition(i, j));
                }
            }
        }

        // Middle flank
        for (int i = Board.WIDTH / 3; i < Board.WIDTH / 3 * 2; i++)
        {
            for (int j = minSpawnHeight; j <= maxSpawnHeight; j++)
            {
                PieceInfo pieceInfo = board.GetPieceFromPosition(i, j);
                if (pieceInfo != null)
                {
                    midValue += pieceInfo.Rank.GetValue();
                }
                else
                {
                    midFlank.Add(new BoardPosition(i, j));
                }
            }
        }

        // Right flank
        for (int i = Board.WIDTH / 3 * 2; i < Board.WIDTH; i++)
        {
            for (int j = minSpawnHeight; j <= maxSpawnHeight; j++)
            {
                PieceInfo pieceInfo = board.GetPieceFromPosition(i, j);
                if (pieceInfo != null)
                {
                    rightValue += pieceInfo.Rank.GetValue();
                }
                else
                {
                    rightFlank.Add(new BoardPosition(i, j));
                }
            }
        }

        // Types of spawns. Both equally likely
        // 1. Conservative - Equally distribute to all 3 flanks
        // 2. Blitz - Concentrate power in 1 flank
        if (Random.value > 0.5f)
        {
            // Conservative - Equally distribute
            Debug.Log("Conservative spawning");

            // Shuffle first
            piecesToSpawn.Sort((pieceInfo1, pieceInfo2) => pieceInfo2.Rank.GetValue().CompareTo(pieceInfo1.Rank.GetValue()));
            leftFlank.Shuffle();
            midFlank.Shuffle();
            rightFlank.Shuffle();

            while (piecesToSpawn.Count > 0)
            {
                PieceInfo pieceToSpawn = ExtractPieceFromList(piecesToSpawn, piecesToSpawn[0].Rank);

                // Find smallest flank in terms of value
                if (leftValue <= midValue && leftValue <= rightValue && leftFlank.Count > 0)
                {
                    SpawnPieceFromPositionList(leftFlank, pieceToSpawn);
                    leftValue += pieceToSpawn.Rank.GetValue();
                }
                else if (midValue <= leftValue && midValue <= rightValue && midFlank.Count > 0)
                {
                    SpawnPieceFromPositionList(midFlank, pieceToSpawn);
                    midValue += pieceToSpawn.Rank.GetValue();
                }
                else
                {
                    SpawnPieceFromPositionList(rightFlank, pieceToSpawn);
                    rightValue += pieceToSpawn.Rank.GetValue();
                }
            }
        }
        else
        {
            // Blitz
            Debug.Log("Blitz spawning");

            piecesToSpawn.Sort((pieceInfo1, pieceInfo2) => pieceInfo2.Rank.GetValue().CompareTo(pieceInfo1.Rank.GetValue()));

            // Choose 1 flank
            List <BoardPosition> chosenFlank;
            List <BoardPosition> otherFlanks;

            float flankChance = Random.value;
            if (flankChance < 0.3333f)
            {
                chosenFlank = leftFlank;
                otherFlanks = midFlank;
                otherFlanks.AddRange(rightFlank);
            }
            else if (flankChance < 0.6666f)
            {
                chosenFlank = midFlank;
                otherFlanks = leftFlank;
                otherFlanks.AddRange(rightFlank);
            }
            else
            {
                chosenFlank = rightFlank;
                otherFlanks = leftFlank;
                otherFlanks.AddRange(midFlank);
            }

            chosenFlank.Shuffle();
            otherFlanks.Shuffle();

            foreach (PieceInfo piece in piecesToSpawn)
            {
                // If chosen flank is not empty,
                if (chosenFlank.Count > 0)
                {
                    // 80% chosen blitz flank
                    // 20% for other flanks
                    flankChance = Random.value;
                    if (flankChance < 0.8f)
                    {
                        SpawnPieceFromPositionList(chosenFlank, piece);
                    }
                    else
                    {
                        SpawnPieceFromPositionList(otherFlanks, piece);
                    }
                }
                else
                {
                    SpawnPieceFromPositionList(otherFlanks, piece);
                }
            }
        }
    }