public void OnWriteLog(TextWriter writer) { writer.WriteLine(NumPossibleDecks + " possible decks"); writer.WriteLine(NumPossibleCards + " possible cards"); writer.WriteLine(""); writer.WriteLine(NumPredictedCards + " predicted cards:"); PredictedCards.ForEach(cardInfo => writer.WriteLine(cardInfo.ToString())); writer.WriteLine(""); writer.WriteLine("Next " + RunnerUpCards.Count + " most likely cards:"); RunnerUpCards.ForEach(cardInfo => writer.WriteLine(cardInfo.ToString())); }
/// <summary> /// Creates a prediction using the specified parameters and adds these to the prediction map. /// </summary> /// <param name="handZoneCount">the number of the opponent's hand cards</param> /// <param name="predictedCards">the predicted hand cards of the opponent</param> /// <param name="predictedDecks">the predicted decks of the opponent</param> /// <param name="predictionMap">the map the prediction is added to</param> private void createPrediction(int handZoneCount, PredictedCards predictedCards, List <Deck> predictedDecks, ref List <Prediction> predictionMap) { int deckCount = 0; for (int d = 0; d < predictedDecks.Count && deckCount < _predictionParameters.DeckCount; d++) { Deck predictedDeck = predictedDecks[d]; List <KeyValuePair <Card, double> > cardPool = predictedDeck.CardEntries; int predictionsCount = 0; //for (int i = 0; i < (cardPool.Count - handZoneCount) // && predictionMap.Count() < _predictionParameters.SetCount; // i += _predictionParameters.StepWidth) for (int i = 0; i < (cardPool.Count - handZoneCount) && predictionsCount < _predictionParameters.SetCount; i += _predictionParameters.StepWidth) { // create hand var hand = new Hand(); int j = 0; while (j < handZoneCount && j < cardPool.Count) { KeyValuePair <Card, double> card = cardPool[i + j]; hand.Add(card); j++; } double sum = hand.Sum; // create deck Deck deck = copyDeck(predictedDeck); hand.Cards.ForEach(h => { if (deck.Cards.Contains(h)) { deck.Remove(h); } }); predictionMap.Add(new Prediction(sum, hand, deck)); predictionsCount++; } deckCount++; } }
/// <summary> /// TODO: API /// </summary> /// <param name="simulationGame">the game the prediction is performed on</param> /// <param name="opponent">the controller of the opponent</param> /// <returns></returns> private List <Prediction> GetPredictionMap(POGame simulationGame, Controller opponent) { PlayedCards playedCards = UpdateTasks(opponent); var predictionMap = new List <Prediction>(); if (!(playedCards.CardEntries?.Any() ?? false)) { return(predictionMap); } Dictionary <CardClass, double> predictedDeckClasses = predictDeckClasses(opponent, _oppBoardCards); if (_lastPredictionCards == null) { _lastPredictionCards = PredictCards(_predictionParameters.CardCount, playedCards, _oppBoardCards, predictedDeckClasses); } var combinedPredictedCards = new PredictedCards(_lastPredictionCards .SelectMany(p => p.CardEntries) .ToList()); List <Deck> predictedDecks = predictDecks(combinedPredictedCards, _oppBoardCards); var predictedDecksCopy = new List <Deck>(); foreach (Deck deck in predictedDecks) { Deck predictedDeckCopy = CopyDeck(deck); // remove already drawn cards from deck _oppBoardCards.Cards.ForEach(c => { if (predictedDeckCopy.Cards.Contains(c)) { predictedDeckCopy.Remove(c); } }); predictedDecksCopy.Add(predictedDeckCopy); } int handZoneCount = opponent.HandZone.Count; CreatePrediction(handZoneCount, combinedPredictedCards, predictedDecksCopy, ref predictionMap); return(predictionMap); }
/// <summary> /// Returns a prediction of the opponent's strategy and deck, i.e. a scoring function and a set of cards, based on /// the predicted cards of the opponent. /// </summary> /// <param name="predictedCards">the cards the strategy and the deck is predicted with</param> /// <param name="boardCards">the board cards of the opponent</param> /// <returns>the scoring function and a set of cards</returns> private List <Deck> predictDecks(PredictedCards predictedCards, BoardCards boardCards) { var allCards = predictedCards.Cards .Union(boardCards.Cards) .ToList(); return(getDecks().Values.OrderByDescending(d => { int hit = 0; foreach (Card card in d.Cards) { if (allCards.Contains(card)) { hit++; } } double value = ((double)(hit) / allCards.Count); return value; }).ToList()); }
/// <summary> /// Returns a prediction of the opponent's hand cards, i.e. set of cards and there probability, /// based on the bi-gram map and cards which haven been played the opponent. /// </summary> /// <param name="cardCount">the number of sets which will by predicted</param> /// <param name="simulationGame">the game the prediction is performed on</param> /// <param name="playedCards">the cards which have been played by the opponent</param> /// <param name="boardCards">the board cards of the opponent</param> /// <param name="classPrediction">the prediction of the deck classes of the opponent</param> /// <returns>the set of cards and there probability</returns> private List <PredictedCards> predictCards(int cardCount, POGame.POGame simulationGame, PlayedCards playedCards, BoardCards boardCards, Dictionary <CardClass, double> classPrediction) { List <Dictionary <string, double> > occMaps = getOccurenceMaps(playedCards); var combinedOccMap = new Dictionary <string, double>(); foreach (Dictionary <string, double> occMap in occMaps) { occMap.ToList().ForEach(o => { string cardId = o.Key; double cardValue = o.Value; if (combinedOccMap.ContainsKey(cardId)) { // greedy approach if (combinedOccMap[cardId] < cardValue) { combinedOccMap[cardId] = cardValue; } } else { combinedOccMap.Add(cardId, cardValue); } }); } Dictionary <Card, double> playableCards = convertToCardMap(combinedOccMap, classPrediction); // get number of cards in relation to the class distribution of already drawn cards var tempPredictedCardGroups = new List <PredictedCards>(); classPrediction.ToList().ForEach(c => { // filter cards if they have already been exhausted or not var filterdPlayableCards = new PredictedCards( playableCards.Where(p => p.Key.Class == c.Key) .Where(p => { if (p.Key.Rarity == Rarity.LEGENDARY) { return(boardCards.Cards .Count(b => b == p.Key) < 1); } else { return(boardCards.Cards .Count(b => b == p.Key) < 2); } }).ToList()); int share = (int)(c.Value * cardCount); var predictedCards = new PredictedCards(filterdPlayableCards .CardEntries.Take(share) .ToList()); tempPredictedCardGroups.Add(predictedCards); }); var combinedPredictedCards = new PredictedCards( tempPredictedCardGroups.SelectMany(g => g.CardEntries) .ToList()); double sum = combinedPredictedCards.Sum; var predictedCardGroups = new List <PredictedCards>(); foreach (PredictedCards group in tempPredictedCardGroups) { var newGroup = new PredictedCards(); group.CardEntries // sort list .OrderByDescending(c => c.Value) .ToList().ForEach(c => newGroup.Add(c.Key, (c.Value / sum))); predictedCardGroups.Add(newGroup); } return(predictedCardGroups); }
public void AddPredictedCard(string cardId) => PredictedCards.Add(cardId);