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; } } } }
public GamePiece(PieceColour pieceColour, PieceRank pieceRank, int xCoord, int yCoord) { PieceColour = pieceColour; PieceRank = pieceRank; Xcoord = xCoord; Ycoord = yCoord; }
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]; } }
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; }
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]; } }
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); }
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]); }
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; } }
public ChessBoardPiece(PiecePlayer player, PieceRank rank) { Player = player; Rank = rank; }
public static float GetValue(this PieceRank rank) { return(RankValues[(int)rank]); }
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); } } } }