Пример #1
0
        // executes a single trick and stores state in a new TrickContext instance, as well
        private void PlaySingleTrick(int trickNum)
        {
            _frontend.DisplayStartTrick(trickNum);
            _gameContext.CurRound.Tricks.Add(new TrickContext(trickNum));

            var curRound = _gameContext.CurRound;
            var curTrick = curRound.CurTrick;

            Player leader = trickNum == 1
                ? leader = _players[(_players.IndexOf(curRound.Dealer) + 1) % _players.Count]
                : leader = curRound.PrevTrick.Winner;
            int leaderIndex = _players.IndexOf(leader);

            // create a player list that starts at the trick leader and wraps around
            List <Player> trickPlayerOrder = _players
                                             .GetRange(leaderIndex, _players.Count - leaderIndex)
                                             .Concat(_players.GetRange(0, leaderIndex)).ToList();

            trickPlayerOrder.ForEach(player =>
            {
                var cardPlayed = player.MakeTurn(_gameContext);
                curTrick.CardsPlayed.Add(cardPlayed);
                _frontend.DisplayTurnTaken(cardPlayed, player);
            });

            // find winner and save it to trick context
            var winningCard   = CardUtils.CalcWinningCard(curTrick.CardsPlayed, curRound.TrumpSuite, curTrick.LeadingSuite);
            var winningPlayer = trickPlayerOrder[curTrick.CardsPlayed.IndexOf(winningCard)];

            curTrick.Winner = winningPlayer;
            _frontend.DisplayTrickWinner(winningPlayer, winningCard);
        }
Пример #2
0
        public override Card MakeTurn(GameContext gameContext)
        {
            var curRound       = gameContext.CurRound;
            var curTrick       = curRound.CurTrick;
            var curRoundTricks = curRound.Tricks;

            var playableCards = CardUtils.GetPlayableCards(_hand, curTrick.LeadingSuite);

            List <Card> allKnownCards = _hand.Concat(curRoundTricks.Aggregate(new List <Card>(), (acc, trick) =>
            {
                acc.AddRange(trick.CardsPlayed);
                return(acc);
            })).ToList();

            List <Card> remainingCards = new List <Card>(new Deck().Cards);

            foreach (var card in allKnownCards)
            {
                remainingCards.Remove(card);
            }

            Dictionary <Card, int> winsByCard = playableCards.Aggregate(new Dictionary <Card, int>(), (acc, next) => { acc[next] = 0; return(acc); });

            for (int i = 0; i < SIMULATION_COUNT; i++)
            {
                foreach (var card in playableCards)
                {
                    var curSimRemainingCards = new List <Card>(remainingCards);
                    var cardsPlayed          = new List <Card>(curTrick.CardsPlayed);
                    cardsPlayed.Add(card);

                    // each remaining player plays a random card from a randomly generated hand
                    for (int j = cardsPlayed.Count(); j < gameContext.PlayerCount; j++)
                    {
                        // rand hand selected from the remaining cards specific to this simulation
                        var randHand = takeRandomCardsFromList(curSimRemainingCards, _hand.Count());
                        var playableCardsFromRandHand = CardUtils.GetPlayableCards(randHand, curTrick.LeadingSuite);
                        cardsPlayed.Add(playableCardsFromRandHand[_rand.Next() % playableCardsFromRandHand.Count()]);
                    }
                    var winningCard = CardUtils.CalcWinningCard(cardsPlayed, curRound.TrumpSuite, curTrick.LeadingSuite);

                    if (card.Equals(winningCard))
                    {
                        winsByCard[card]++;
                    }
                }
            }

            List <KeyValuePair <Card, double> > cardsSortedByWinPctg = winsByCard.Aggregate(new List <KeyValuePair <Card, double> >(), (acc, nextPair) =>
            {
                double winPercentage = nextPair.Value * 1.0 / SIMULATION_COUNT;
                acc.Add(new KeyValuePair <Card, double>(nextPair.Key, winPercentage));
                return(acc);
            });

            // sort it so that weakest cards are at lower indices and stronger card at higher indices
            cardsSortedByWinPctg.Sort((a, b) => a.Value < b.Value ? -1 : 1);

            var curBid     = curRound.Bids[this];
            var curWins    = curRound.Results[this];
            var roundsLeft = curRound.RoundNum - curRound.Tricks.Count + 1;

            /*
             *  requieredStrengthOfPlay is a value determining strength of card to play based on game context
             *  given that requiredStrengthOfPlay = k:
             *
             *  k>1  => impossible to win, play strongest card
             *  k=1 => play strongest cards from here on out to win
             *  0<k<1 => sort cards by strength and select closest index to k val
             *          i.e. k = .6 and 5 cards => choose card 3 /5 ranked by strength
             *  k=0 => play weakest cards from here on out to win
             *  k<0 => won too many, impossible to win, play weakest card
             *
             */
            double requiredStrengthOfPlay = (curBid - curWins) * 1.0 / roundsLeft;

            Card cardToPlay = null;

            if (requiredStrengthOfPlay >= 1)
            {
                cardToPlay = cardsSortedByWinPctg.Last().Key;
            }
            else if (requiredStrengthOfPlay <= 0)
            {
                cardToPlay = cardsSortedByWinPctg.First().Key;
            }
            else
            {
                // requiredStrengthOfPlay between 0 and 1
                int indexToPlay = (int)(requiredStrengthOfPlay * cardsSortedByWinPctg.Count());
                cardToPlay = cardsSortedByWinPctg[indexToPlay].Key;
            }

            _frontend.DisplayTurnInProgress(this);
            _hand.Remove(cardToPlay);
            return(cardToPlay);
        }