// simulates each card in _hand in a wide variety of tricks and returns a win count for each card private Dictionary <Card, int> SimulateRound(Card trumpCard, int playerCount, int simCount) { Dictionary <Card, int> winsByCard = _hand.Aggregate(new Dictionary <Card, int>(), (acc, card) => { acc[card] = 0; return(acc); }); int simsPerTrick = 1; int simsPerPlayPos = simCount / (simsPerTrick * playerCount); var allKnownCards = new List <Card>(_hand); allKnownCards.Add(trumpCard); var remainingCards = Deck.GetDeckComplement(allKnownCards); // iterate through each possible play position and simulate each card in _hand being played for (int playPos = 0; playPos < playerCount; playPos++) { // simulate simPerPlayPos number of tricks for each play position for (int simNumber = 0; simNumber < simsPerPlayPos; simNumber++) { // single trick simulation: // because SimulateTrick simulates an in-progress trick to completion, // a random trick with cards played must be built out before simulateTrick can be called var curSimTrick = new TrickContext(1 /*trick context*/); var curSimRemainingCards = new List <Card>(remainingCards); // for each sim, generate a random set of cardsPlayed by other players up to simPlayPos // this means that if the current playPosition is 2, cards played for positions 0 and 1 need to be generated before the trick is simulated for (int curSimPlayPos = 0; curSimPlayPos < playPos; curSimPlayPos++) { var randHand = takeRandomCardsFromList(curSimRemainingCards, _hand.Count); var playableCards = CardUtils.GetPlayableCards(randHand, curSimTrick.LeadingSuite); curSimTrick.CardsPlayed.Add(playableCards[_rand.Next() % playableCards.Count()]); } var curSimWinsByCard = SimulateTrick(curSimTrick, curSimRemainingCards, trumpCard.Suite, playerCount, simsPerTrick); // using the results from the current trick simulation, update the overall winsByCard foreach (var cardWinPair in curSimWinsByCard) { winsByCard[cardWinPair.Key] += cardWinPair.Value; } } } return(winsByCard); }
// simulates playing each card in _hand against an in-progress trick, plays random cards to finish and score the trick // returns a dictionary of cards in _hand to number of wins // @param hiddenCards refers to the cards in the deck that could potentialy be played by other players private Dictionary <Card, int> SimulateTrick(TrickContext trick, List <Card> hiddenCards, CardSuite trumpSuite, int playerCount, int simCount) { var playableCards = CardUtils.GetPlayableCards(_hand, trick.LeadingSuite); Dictionary <Card, int> winsByCard = playableCards.Aggregate(new Dictionary <Card, int>(), (acc, card) => { acc[card] = 0; return(acc); }); for (int i = 0; i < simCount; i++) { foreach (var card in playableCards) { var curSimRemainingCards = new List <Card>(hiddenCards); var simPlayedCards = new List <Card>(trick.CardsPlayed); simPlayedCards.Add(card); // each remaining player plays a random card from a randomly generated hand for (int j = simPlayedCards.Count(); j < playerCount; j++) { // rand hand selected from the remaining cards specific to this simulation var randHand = takeRandomCardsFromList(curSimRemainingCards, _hand.Count()); var playableCardsFromRandHand = CardUtils.GetPlayableCards(randHand, trick.LeadingSuite); simPlayedCards.Add(playableCardsFromRandHand[_rand.Next() % playableCardsFromRandHand.Count()]); } var winningCard = CardUtils.CalcWinningCard(simPlayedCards, trumpSuite, trick.LeadingSuite); if (card.Equals(winningCard)) { winsByCard[card]++; } } } return(winsByCard); //Dictionary<Card, double> winPercentagesByCard = new Dictionary<Card, double>(); //foreach(var winCardPair in winsByCard) //{ // double winPctg = winCardPair.Value * 1.0 / SIMULATION_COUNT; // winPercentagesByCard[winCardPair.Key] = winPctg; //} //return winPercentagesByCard; }