private int CardWorth(Card card, ICollection<Card> hand, PlayerTurnContext context) { var possibleTakes = this.cardTracker.AllCards[card.Suit] .Where(x => (x.Value == CardTracerState.InOpponentHand || x.Value == CardTracerState.Unknown) && x.Key < card.GetValue()) .ToList(); if (possibleTakes.Count == 0) { return card.GetValue(); } var value = card.GetValue() + possibleTakes.Max(x => x.Key); return value; }
private float PointAndSuitCountParameter(Card card, PlayerTurnContext context, ICollection<Card> allowedCards) { var cardSuit = card.Suit; float cardValue = card.GetValue(); float coutOfSuitInHand = allowedCards.Count(x => x.Suit == cardSuit); return (11f - cardValue) * coutOfSuitInHand; }
public double CalculateProbabilityCardToBeTaken(Card card, ICollection<Card> myCards, ICollection<Card> playedCards) { ICollection<Card> opponentCards = this.opponentsCardProvider.GetOpponentCards(myCards, playedCards, this.context.TrumpCard, card.Suit); ICollection<Card> trumpOpponentCard = this.opponentsCardProvider.GetOpponentCards(myCards, playedCards, this.context.TrumpCard, this.context.TrumpCard.Suit); int biggestThanCardCount = 0; foreach (var opponentCard in opponentCards) { if (opponentCard.Suit == this.context.TrumpCard.Suit && card.Suit != opponentCard.Suit) { biggestThanCardCount++; } else if (opponentCard.GetValue() > card.GetValue()) { biggestThanCardCount++; } } if (card.Suit != this.context.TrumpCard.Suit) { biggestThanCardCount += trumpOpponentCard.Count; } int lesserThanCardCount = 24 - playedCards.Count - biggestThanCardCount - 6; if (lesserThanCardCount < 6) { return 1; } double result = CalculateFactoriel(lesserThanCardCount) / SixFactoriel * CalculateFactoriel(lesserThanCardCount - 6); return 1 - result; }
private float MaxHandValue(Card card, PlayerTurnContext context) { var suit = card.Suit; var value = card.GetValue(); var isTrump = context.TrumpCard.Suit == suit; var result = 0f; var cardsToTake = this.cardtracker .AllCards[suit] .Where(x => x.Key < value && (x.Value == CardTracerState.InOpponentHand || x.Value == CardTracerState.Unknown)) .ToList(); if (isTrump) { cardsToTake .AddRange(this.cardtracker .AllCards .Where(s => s.Key != suit) .SelectMany(c => c.Value) .Where(x => x.Value == CardTracerState.InOpponentHand || x.Value == CardTracerState.Unknown)); } var high = cardsToTake.Count > 0 ? cardsToTake.Max(x => x.Key) : 0; result += high; if (isTrump) { result += 10; } return result / (this.MaxTakeCases(value, suit) - cardsToTake.Count()); }
private int NumberOfHandsCardCanTake(Card card, PlayerTurnContext context) { var count = this.cardTracker.AllCards[card.Suit] .Where(x => (x.Value == CardTracerState.InOpponentHand || x.Value == CardTracerState.Unknown) && x.Key < card.GetValue()) .Count(); return count; }
private int CardMaxWorthCalculator(Card player, ICardTracker cardTracker) { var worth = 0; worth += player.GetValue(); var maxCardCanTake = cardTracker.AllCards[player.Suit].Where(x => x.Key > player.GetValue() && (x.Value == CardTracerState.Unknown || x.Value == CardTracerState.InOpponentHand)).ToList(); if (maxCardCanTake.Count == 0) { return worth; } worth += maxCardCanTake.Max(x => x.Key); return worth; }
public GameAction(Card opponent, Card player, PlayerTurnContext context, ICardTracker cardTracker) { this.OpponetCard = opponent; this.PlayerCard = player; this.PlayerTakes = this.CheckIfPlayerTakes(opponent, player, context); this.HandValue = opponent.GetValue() + player.GetValue(); this.CardMaxWorth = this.CardMaxWorthCalculator(player, cardTracker); this.OpponentPoints = context.FirstPlayerRoundPoints; this.PlayerPoints = context.SecondPlayerRoundPoints; }
private float BiggestGainParameter(Card card, PlayerTurnContext context, ICollection<Card> allowedCards) { var suit = card.Suit; float value = card.GetValue(); var allOfSuit = this.cardtracker.AllCards[suit]; var maxAvailableForTaking = allOfSuit.Where(x => x.Value != CardTracerState.TakenByOpponent || x.Value != CardTracerState.TakenByPlayer).Max(x => x.Key); return (value + maxAvailableForTaking) / BiggestGainDivisor; }
public PlayerPosition Winner(Card firstPlayerCard, Card secondPlayerCard, CardSuit trumpSuit) { if (firstPlayerCard.Suit == secondPlayerCard.Suit) { // If both players play the same suit, the higher card wins. return firstPlayerCard.GetValue() > secondPlayerCard.GetValue() ? PlayerPosition.FirstPlayer : PlayerPosition.SecondPlayer; } // If just one player plays a trump, the trump wins. if (secondPlayerCard.Suit == trumpSuit) { return PlayerPosition.SecondPlayer; } // If the players play non-trumps of different suits the card played by the first player wins. return PlayerPosition.FirstPlayer; }
public PlayerPosition Winner(Card firstPlayerCard, Card secondPlayerCard, CardSuit trumpSuit) { if (firstPlayerCard.Suit == secondPlayerCard.Suit) { if (firstPlayerCard.GetValue() > secondPlayerCard.GetValue()) { return PlayerPosition.FirstPlayer; } else { return PlayerPosition.SecondPlayer; } } if (secondPlayerCard.Suit == trumpSuit) { return PlayerPosition.SecondPlayer; } return PlayerPosition.FirstPlayer; }
private float CurrentCardWorth(Card card, PlayerTurnContext context, ICollection<Card> allowedCards) { var result = 0f; var cardValue = card.GetValue(); if (cardValue == 0) { result = this.NineEvaluation(card, context); } else if (cardValue == QueenValue || cardValue == KingValue) { result = this.QueenKingEvaluation(card, context, allowedCards); } else { result = this.MaxHandValue(card, context); } return result; }
public Card PlaySecondOpen(IList<Card> firstPlayerHandThisTurn, IList<Card> secondPlayerHandThisTurn, int pointsFirstPlayer, int pointsSecondPlayer, PlayerTurnContext context, Card firstPlayerCard) { Card secondPlayerCard; ////play th second player choice var secondPlayerSameSuit = secondPlayerHandThisTurn.Where(x => x.Suit == firstPlayerCard.Suit).Where(x => x.GetValue() > firstPlayerCard.GetValue()); if (secondPlayerSameSuit.Count() > 0) { secondPlayerCard = secondPlayerSameSuit.FirstOrDefault(); } else if (firstPlayerCard.GetValue() > 4) { ////CHECK for trump to take the other card ////TODO secondPlayerCard = secondPlayerHandThisTurn.FirstOrDefault(); } else { secondPlayerCard = secondPlayerHandThisTurn.FirstOrDefault(); } return secondPlayerCard; }
public bool IfFirstPlayerIsWinner(Card first, Card second, PlayerTurnContext context) { if (first.Suit == second.Suit) { return first.GetValue() > second.GetValue(); } else { if (second.Suit == context.TrumpCard.Suit) { return false; } return true; } }
public Card PlaySecondClosed(IList<Card> firstPlayerHandThisTurn, IList<Card> secondPlayerHandThisTurn, int pointsFirstPlayer, int pointsSecondPlayer, PlayerTurnContext context, Card firstPlayerCard) { Card secondPlayerCard; ////play th second player choice IList<Card> secondPlayerSameSuit = secondPlayerHandThisTurn.Where(x => x.Suit == firstPlayerCard.Suit).ToList(); if (secondPlayerSameSuit.Count() > 0) { secondPlayerSameSuit.OrderByDescending(x => x.GetValue()); if (secondPlayerSameSuit.First().GetValue() > firstPlayerCard.GetValue()) { secondPlayerCard = secondPlayerSameSuit.First(); } else { secondPlayerCard = secondPlayerSameSuit.Last(); } } else { ////us trumps var trumps = secondPlayerHandThisTurn.Where(x => x.Suit == context.TrumpCard.Suit); if (trumps.Count() > 0) { secondPlayerCard = trumps.OrderBy(x => x.GetValue()).ElementAt(0); } else { secondPlayerCard = secondPlayerHandThisTurn.FirstOrDefault(); } } return secondPlayerCard; }
private PlayerAction ChooseCardWhenPlayingFirstAndRulesDoNotApply(PlayerTurnContext context, ICollection<Card> possibleCardsToPlay) { var action = this.TryToAnnounce20Or40(context, possibleCardsToPlay); if (action != null) { return action; } int points = 0; int secondPlayerPoints = 0; if (context.IsFirstPlayerTurn) { points = context.FirstPlayerRoundPoints; secondPlayerPoints = context.SecondPlayerRoundPoints; } else { points = context.SecondPlayerRoundPoints; secondPlayerPoints = context.FirstPlayerRoundPoints; } if (points < 33 && secondPlayerPoints >= 50) { List<Card> cardsBiggerThanTen = this.Cards.Where(c => c.Suit == context.TrumpCard.Suit && c.GetValue() >= 10).ToList(); if (cardsBiggerThanTen.Count() == 1 && cardsBiggerThanTen[0].GetValue() == 10) { this.calculator = new ProbabilityCalculator(context, this.opponentSuitCardsProvider); double probabilityTenToBeTaken = this.calculator.CalculateProbabilityCardToBeTaken(cardsBiggerThanTen[0], this.Cards, this.playedCards); if (probabilityTenToBeTaken <= 0.5) { if (cardsBiggerThanTen[0] == null || !this.Cards.Contains(cardsBiggerThanTen[0])) { cardsBiggerThanTen[0] = this.Cards.First(); } return this.PlayCard(cardsBiggerThanTen[0]); } } } Card cardToPlay = new Card(context.TrumpCard.Suit, CardType.Ace); foreach (var card in possibleCardsToPlay) { if (card.GetValue() < cardToPlay.GetValue() && card.Suit != context.TrumpCard.Suit) { if ((card.Type == CardType.King && !this.playedCards.Any(p => p.Type == CardType.Queen && p.Suit == card.Suit)) || (card.Type == CardType.Queen && !this.playedCards.Any(p => p.Type == CardType.King && p.Suit == card.Suit))) { continue; } cardToPlay = card; } } if (cardToPlay == null || !this.Cards.Contains(cardToPlay)) { cardToPlay = this.Cards.First(); } return this.PlayCard(cardToPlay); }
public static void Compute(Node root, Card oppCard, IList<Card> myCards, IList<Card> oppCards, int myPoints, int oppPoints) { if (myPoints >= 66) { root.Wins++; root.Total++; return; } if (oppPoints >= 66) { root.Total++; return; } if (oppCard == null) { for (int i = 0; i < 6; i++) { if (myCards[i] == null) { continue; } var myNextCard = myCards[i]; myCards[i] = null; var root1 = new Node(root, myNextCard, true); var myValue = myNextCard.GetValue(); for (int j = 0; j < 6; j++) { if (oppCards[j] == null) { continue; } var nextOppCard = oppCards[j]; oppCards[j] = null; var oppValue = nextOppCard.GetValue(); if ((nextOppCard.HasSameSuitAs(myNextCard) && oppValue > myValue) || (!oppCards.Any(x => x!= null && x.Suit == myNextCard.Suit) && nextOppCard.IsTrump())) { var root2 = new Node(root1, nextOppCard, false); for (int k = 0; k < 6; k++) { if (oppCards[k] == null) { continue; } var oppCard3 = oppCards[k]; oppCards[k] = null; var root3 = new Node(root2, oppCard3, false); Compute(root3, oppCard3, myCards, oppCards, myPoints, oppPoints + myValue + oppValue); root2.Children.Add(root3); root2.Wins += root3.Wins; root2.Total += root3.Total; oppCards[k] = oppCard3; } root1.Children.Add(root2); root1.Wins += root2.Wins; root1.Total += root2.Total; } else { var root2 = new Node(root1, nextOppCard, true); Compute(root2, null, myCards, oppCards, myPoints + myValue + oppValue, oppPoints); root1.Children.Add(root2); root1.Wins += root2.Wins; root1.Total += root2.Total; } oppCards[j] = nextOppCard; } root.Children.Add(root1); root.Wins += root1.Wins; root.Total += root1.Total; myCards[i] = myNextCard; } } else { for (int i = 0; i < 6; i++) { if (myCards[i] == null) { continue; } var myNextCard = myCards[i]; myCards[i] = null; var root1 = new Node(root, myNextCard, true); if (myNextCard.HasSameSuitAs(oppCard) && myNextCard.GetValue() > oppCard.GetValue() && !(!myNextCard.IsTrump() && oppCard.IsTrump())) { Compute(root1, null, myCards, oppCards, myPoints + myNextCard.GetValue() + oppCard.GetValue(), oppPoints); } else { for (int j = 0; j < 6; j++) { if (oppCards[j] == null) { continue; } var oppNextCard = oppCards[j]; oppCards[j] = null; var root2 = new Node(root1, oppNextCard, false); Compute(root2, oppNextCard, myCards, oppCards, myPoints, oppPoints + myNextCard.GetValue() + oppCard.GetValue()); root1.Children.Add(root2); root1.Wins += root2.Wins; root1.Total += root2.Total; oppCards[j] = oppNextCard; } } root.Children.Add(root1); root.Wins += root1.Wins; root.Total += root1.Total; myCards[i] = myNextCard; } } }
public static bool CanPlayCard( bool isThePlayerFirst, Card playedCard, Card otherPlayerCard, Card trumpCard, ICollection<Card> playerCards, bool shouldObserveRules) { if (!playerCards.Contains(playedCard)) { return false; } if (!shouldObserveRules) { // When rules does not apply every card is valid return true; } if (isThePlayerFirst) { // When the player is first he can play every card return true; } if (otherPlayerCard.Suit == playedCard.Suit) { // Played bigger card of the same suit - OK if (playedCard.GetValue() > otherPlayerCard.GetValue()) { return true; } // When a card is led, the opponent must play a higher card of the same suit if possible // ReSharper disable once LoopCanBeConvertedToQuery (performance critical) foreach (var card in playerCards) { if (card.Suit == otherPlayerCard.Suit && card.GetValue() > otherPlayerCard.GetValue()) { // Found bigger card which is not played => wrong action return false; } } } else { // Having no higher card, the second player MUST play a lower card of the suit that was led // ReSharper disable once LoopCanBeConvertedToQuery (performance critical) foreach (var card in playerCards) { if (card.Suit == otherPlayerCard.Suit) { // Found same suit card which is not played => wrong action return false; } } // Player has no card of the same suit and plays trump - OK if (playedCard.Suit == trumpCard.Suit) { return true; } // If the player has no card of the suit played by the first player he must play a trump if possible // ReSharper disable once LoopCanBeConvertedToQuery (performance critical) foreach (var card in playerCards) { // Found trump card which is not played => wrong action if (card.Suit == trumpCard.Suit) { return false; } } } // Having no cards of the suit led and no trumps, the second player may throw any card. return true; }
public void GetValueShouldThrowAnExceptionWhenGivenInvalidCardType() { var cardTypes = Enum.GetValues(typeof(CardType)); var cardTypeValue = cardTypes.OfType<CardType>().Max() + 1; var card = new Card(CardSuit.Club, cardTypeValue); card.GetValue(); }
private bool CheckIfPlayerTakes(Card opponent, Card player, PlayerTurnContext context) { var trumpSuit = context.TrumpCard.Suit; if (opponent.Suit == player.Suit) { return player.GetValue() > opponent.GetValue(); } if (player.Suit != trumpSuit) { return false; } return true; }
public void AddCard(Card card) { this.AllCards[card.Suit][card.GetValue()] = CardTracerState.InHand; }
public void RoundPointsShouldReturnCorrectValueOfCards() { var roundPlayerInfo = new RoundPlayerInfo(new Mock<BasePlayer>().Object); var card1 = new Card(CardSuit.Diamond, CardType.Jack); var card2 = new Card(CardSuit.Diamond, CardType.Ace); roundPlayerInfo.TrickCards.Add(card1); roundPlayerInfo.TrickCards.Add(card2); Assert.AreEqual(card1.GetValue() + card2.GetValue(), roundPlayerInfo.RoundPoints); }
private float QueenKingEvaluation(Card card, PlayerTurnContext context, ICollection<Card> hand) { var result = 0f; var value = card.GetValue(); var valueOfCounterPart = value == KingValue ? QueenValue : KingValue; var announceValue = card.Suit == context.TrumpCard.Suit ? FourtyAnnounceValue : TwentyAnnounceValue; var suit = card.Suit; var havePair = this.cardtracker.AllCards[suit][valueOfCounterPart] == CardTracerState.InHand; var counterPartCardTrackInfo = this.cardtracker.AllCards[suit][valueOfCounterPart]; var pairIsPossible = counterPartCardTrackInfo == CardTracerState.Unknown || counterPartCardTrackInfo == CardTracerState.TrumpIndicator; if (havePair) { result = announceValue + value; } else if (pairIsPossible) { result = (announceValue / 2f) + value; } else { result += this.MaxHandValue(card, context); } return result; }
public void GetValueShouldReturnPositiveValueForEveryCardType() { foreach (CardType cardTypeValue in Enum.GetValues(typeof(CardType))) { var card = new Card(CardSuit.Diamond, cardTypeValue); var value = card.GetValue(); // Not expecting exceptions here Assert.IsTrue(value >= 0); } }