public void ExecuteTurn(shootout.TurnResult turn) { if (turn.chosenCard != null) { hand.PlayCard(turn.chosenCard); if (turn.fourthCard != null) { hand.PlayCard(turn.fourthCard); } } }
private float FinishAITurn(int bid, int bidScalar, CardGameAI ai) { currentBid = bid; currentBidScalar = bidScalar; amountInPot += currentBid; AdvanceTurn(); TurnResult subResult = CaclulateOptimalTurn(ai); return(subResult.value - bid); }
public override IEnumerator StartTurn(List <List <Card> > onBoard, int currentBid, int currentBidScalar, int inPot, int currentTurn) { choice = ChooseCard(onBoard[index], onBoard[1 - index], inPot, currentBid, currentBidScalar, currentTurn); yield return(hand.PutCardOnTable(choice.chosenCard)); if (CanPlayExtraCard(choice.chosenCard) && choice.fourthCard == null) { choice.fourthCard = PickCard(); } yield return(null); }
private float TakeOtherPlayerTurn(float foldProb, int bid, int bidScalar, CardGameAI ai) { // other player responds CardGameState nextState = Clone(); nextState.currentBid = bid; nextState.currentBidScalar = bidScalar; nextState.amountInPot += bid; nextState.AdvanceTurn(); TurnResult subResult = nextState.CaclulateOptimalTurn(ai); return(subResult.value * (1 - foldProb) + amountInPot * foldProb); }
private TurnResult TakeAITurn(int bid, int bidScalar, CardGameAI ai) { TurnResult result = shootout.TurnResult.Fold(); aiPlayer.ForEachInHand((index) => { CardGameState nextState = Clone(); Card cardPlayed = nextState.aiPlayer.PlayCard(index); if (round == 2 && nextState.aiPlayer.CanPlayTriple()) { nextState.aiPlayer.ForEachInHand((fourthIndex) => { CardGameState fourthPlayState = nextState.Clone(); Card fourthCard = fourthPlayState.aiPlayer.PlayFourthCard(fourthIndex); float score = fourthPlayState.FinishAITurn(bid, bidScalar, ai); if (score > result.value) { result.value = score; result.chosenCard = cardPlayed; result.bid = nextState.currentBid; result.fourthCard = fourthCard; } }); } else { float score = nextState.FinishAITurn(bid, bidScalar, ai); if (score > result.value) { result.value = score; result.chosenCard = cardPlayed; result.bid = nextState.currentBid; } } }); return(result); }
public HumanPlayerLogic( int index, PlayerHand hand, Button foldButton, Transform guiTransform, Text bidPreview, RadioButtons multiplier, Image multiplierShow, Sprite[] multiplierSymbols, List <Button> cardSelection, Text moneyLabel ) : base(index, hand, moneyLabel) { this.foldButton = foldButton; this.guiTransform = guiTransform; this.bidPreview = bidPreview; this.multiplier = multiplier; this.multiplierShow = multiplierShow; this.multiplierSymbols = multiplierSymbols; this.cardSelection = cardSelection; this.multiplier.Change((multiplierIndex) => { UpdateBid(); }); foldButton.onClick.AddListener(() => { if (takingTurn) { choice = shootout.TurnResult.Fold(); } }); for (int i = 0; i < cardSelection.Count; ++i) { BindCardClick(cardSelection[i], i); } SetGUIVisible(false, -1, 1); }
private void BindCardClick(Button button, int index) { button.onClick.AddListener(() => { Card pickedCard = index < hand.GetHand().Count ? hand.GetHand()[index] : null; if (takingTurn && pickedCard != null) { if (choice == null) { choice = new shootout.TurnResult(GetBid(), multiplier.Selected + 1, pickedCard); chosenCard = pickedCard; } else if (choice.chosenCard != pickedCard) { choice.bid = GetBid(); choice.fourthCard = pickedCard; chosenCard = pickedCard; } } }); }
public override IEnumerator StartTurn(List <List <Card> > onBoard, int currentBid, int currentBidScalar, int inPot, int currentTurn) { takingTurn = true; choice = null; cardChoice = -1; multiplier.SetSelected(0); UpdateBid(); minBid = Math.Max(Math.Min((currentBid == -1) ? inPot / 2 : currentBid, money), 1); SetGUIVisible(true, currentBid, 1); while (choice == null || (CanPlayExtraCard(choice.chosenCard) && choice.fourthCard == null)) { if (chosenCard != null) { PositionGUI(1); yield return(hand.PutCardOnTable(chosenCard)); chosenCard = null; } yield return(null); } SetGUIVisible(false, -1, 1); if (chosenCard != null) { if (chosenCard != choice.fourthCard) { yield return(hand.PutCardOnTable(chosenCard)); } chosenCard = null; } takingTurn = false; }
public TurnResult CaclulateOptimalTurn(CardGameAI ai) { TurnResult result = TurnResult.Fold(); if (round == 3) { ++checkCount; result.value = ai.winProbability(aiPlayer, otherPlayer, isAIFirst, currentBidScalar) * amountInPot; } else { int minBid = (amountInPot - currentBid) / 2; int cardSlot = aiPlayer.cardsPlayed; if (isFirstTurn && isAIFirst) { // this player goes first for (int bidScalar = 1; bidScalar <= 3; ++bidScalar) { TurnResult subResult = TakeAITurn(bidScalar * minBid, bidScalar, ai); if (subResult.value > result.value) { result = subResult; } } } else if (!isFirstTurn && isAIFirst) { // other player responds float foldProb = ai.foldProbaility(aiPlayer, otherPlayer, isAIFirst, currentBidScalar); result.value = TakeOtherPlayerTurn(foldProb, currentBid, currentBidScalar, ai); } else if (!isFirstTurn && !isAIFirst) { // this player responds result = TakeAITurn(currentBid, currentBidScalar, ai); } else { // other player goes first float foldProb = ai.foldProbaility(aiPlayer, otherPlayer, isAIFirst, currentBidScalar); float scoreResult = float.PositiveInfinity; for (int bidScalar = 1; bidScalar <= 3; ++bidScalar) { float singleResult = TakeOtherPlayerTurn(foldProb, bidScalar * minBid, bidScalar, ai); if (singleResult < scoreResult) { scoreResult = singleResult; } } result.value = scoreResult; } } return(result); }
public IEnumerator PlayHand() { playAgain.gameObject.SetActive(false); stopPlaying.gameObject.SetActive(false); for (int i = 0; i < players.Length; ++i) { var player = players[i]; deck.Discard(player.hand.TakeCards()); player.AdjustMoney(-buyInPrice); yield return(AnimateMoney(-buyInPrice, player.moneyLabel.transform.position, potLabel.transform.position)); moneyInPot += buyInPrice; potLabel.text = moneyInPot.ToString(); } deck.Shuffle(); stillIn = new bool[players.Length]; int stillInCount = players.Length; int startingTurn = currentTurn; for (int i = 0; i < players.Length; ++i) { stillIn[i] = true; players[i].hand.GiveHand(deck.Deal(5)); } List <shootout.TurnResult> allRoundChoices = new List <shootout.TurnResult>(); for (int round = 0; stillInCount > 1 && round < 3; ++round) { var playerHands = players.Select(player => player.hand.GetPlayedCards()).ToList(); int currentBid = -1; int currentBidScalar = 0; List <shootout.TurnResult> choices = new List <shootout.TurnResult>(); List <float> choiceInSeconds = new List <float>(); int minBid = moneyInPot / 2; for (int i = 0; i < players.Length; ++i) { int playerIndex = (currentTurn + i) % players.Length; if (stillIn[playerIndex]) { PlayerLogic player = players[playerIndex]; if (stillInCount == 1) { choices.Add(new shootout.TurnResult(moneyInPot / 2, 1, player.hand.GetHand().Where(card => card != null).Take(1).ToArray()[0])); choiceInSeconds.Add(0.0f); } else { float startTime = Time.time; yield return(player.StartTurn(playerHands, currentBid, currentBidScalar, moneyInPot, round)); choiceInSeconds.Add(Time.time - startTime); shootout.TurnResult choice = player.TurnResult(); Debug.Log("Turn " + playerIndex + " " + Card.ToString(choice.chosenCard) + " extra " + Card.ToString(choice.fourthCard)); currentBid = System.Math.Max(choice.bid, currentBid); currentBidScalar = Mathf.Max(1, currentBid / minBid); multiplierShow.sprite = multiplierImages[currentBidScalar - 1]; if (choice.IsFold()) { stillIn[playerIndex] = false; } else { player.AdjustMoney(-choice.bid); yield return(AnimateMoney(-choice.bid, player.moneyLabel.transform.position, potLabel.transform.position)); moneyInPot += choice.bid; potLabel.text = moneyInPot.ToString(); } if (choice.IsFold()) { --stillInCount; } choices.Add(choice); } } else { choices.Add(shootout.TurnResult.Fold()); --stillInCount; choiceInSeconds.Add(0.0f); } } allRoundChoices.AddRange(choices); for (int i = 0; i < players.Length; ++i) { int playerIndex = (currentTurn + i) % players.Length; PlayerLogic player = players[playerIndex]; shootout.TurnResult choice = choices[i]; /*RoundLogger.LogRound( * round, * playerIndex, * choice.PlayedCards(), * choice.bid, * player.hand.UnplayedCards(), * choiceInSeconds[i], * player.money + choice.bid * );*/ if (!stillIn[playerIndex] && stillInCount == 1) { break; } if (choices[i].chosenCard != null) { if (choices[i].fourthCard != null) { yield return(player.hand.PutCardOnTable(choice.fourthCard)); } players[playerIndex].ExecuteTurn(choice); } } currentTurn = (currentTurn + 1) % players.Length; } currentTurn = (startingTurn + 1) % players.Length; var playersStillIn = players.Where(player => stillIn[player.Index]); foreach (PlayerLogic player in players) { PlayerHand thisHand = player.hand; PlayerHand theirHand = players[1 - player.Index].hand; player.Learn(allRoundChoices, startingTurn == player.Index, thisHand.GetMaxScore(), theirHand.GetMaxScore(), thisHand.ShowedDouble(), theirHand.ShowedDouble()); player.hand.RevealHand(); } int maxScore = playersStillIn.Aggregate(0, (sum, player) => System.Math.Max(sum, player.hand.GetScore())); var winningPlayers = playersStillIn.Where(player => maxScore == player.hand.GetScore()); int winningCount = winningPlayers.Count(); foreach (PlayerLogic player in winningPlayers) { int moneyEarned = moneyInPot / winningCount + (player == players[currentTurn] ? (moneyInPot % winningCount) : 0); moneyInPot -= moneyEarned; potLabel.text = moneyInPot.ToString(); yield return(AnimateMoney(moneyEarned, potLabel.transform.position, player.moneyLabel.transform.position)); player.AdjustMoney(moneyEarned); } playAgain.gameObject.SetActive(true); stopPlaying.gameObject.SetActive(true); StartHand(); }