Beispiel #1
0
 public void ExecuteTurn(shootout.TurnResult turn)
 {
     if (turn.chosenCard != null)
     {
         hand.PlayCard(turn.chosenCard);
         if (turn.fourthCard != null)
         {
             hand.PlayCard(turn.fourthCard);
         }
     }
 }
Beispiel #2
0
        private float FinishAITurn(int bid, int bidScalar, CardGameAI ai)
        {
            currentBid       = bid;
            currentBidScalar = bidScalar;
            amountInPot     += currentBid;
            AdvanceTurn();

            TurnResult subResult = CaclulateOptimalTurn(ai);

            return(subResult.value - bid);
        }
Beispiel #3
0
    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);
    }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
    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);
    }
Beispiel #7
0
    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;
                }
            }
        });
    }
Beispiel #8
0
    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;
    }
Beispiel #9
0
        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);
        }
Beispiel #10
0
    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();
    }