public void IsValid_ShouldReturnFalse_IfPassedANullValue() { var playerActionValidator = new PlayerActionValidator(); var deck = new Deck(); var stateManager = new StateManager(); var context = new PlayerTurnContext( new StartRoundState(stateManager), deck.TrumpCard, deck.CardsLeft, 30, 30); var testPlayerHand = new List <Card>() { new Card(CardSuit.Club, CardType.Jack), new Card(CardSuit.Diamond, CardType.Nine) }; var playerActionCard = new Card(CardSuit.Diamond, CardType.Jack); var actualOutcome = playerActionValidator.IsValid( null, context, testPlayerHand); Assert.IsFalse(actualOutcome); }
public void IsValid_ShouldReturnTrue_IfPlayerActionIsChangeTrumpAndArgumentsAreCorrect() { var playerActionValidator = new PlayerActionValidator(); var deck = new Deck(); var stateManager = new StateManager(); var context = new PlayerTurnContext( new MoreThanTwoCardsLeftRoundState(stateManager), deck.TrumpCard, deck.CardsLeft, 30, 30); var testPlayerHand = new List <Card>() { new Card(CardSuit.Club, CardType.Queen), new Card(CardSuit.Diamond, CardType.King), new Card(CardSuit.Club, CardType.King), new Card(deck.TrumpCard.Suit, CardType.Nine) }; var playerActionCard = new Card(CardSuit.Club, CardType.King); var actualOutcome = playerActionValidator.IsValid( PlayerAction.ChangeTrump(), context, testPlayerHand); Assert.IsTrue(actualOutcome); }
public void TrickResolution(PlayerTurnContext context) { if (this.LastTrump == null) { this.LastTrump = context.TrumpCard; } else if (context.TrumpCard != this.LastTrump) { if (context.IsFirstPlayerTurn) { this.AllCards[this.LastTrump.Suit][this.LastTrump.GetValue()] = CardTracerState.InHand; } else { this.AllCards[this.LastTrump.Suit][this.LastTrump.GetValue()] = CardTracerState.InOpponentHand; } } if (!context.IsFirstPlayerTurn && context.FirstPlayerAnnounce != Announce.None) { var playedCard = context.FirstPlayedCard.GetValue() == 3 ? 4 : 3; this.AllCards[context.FirstPlayedCard.Suit][playedCard] = CardTracerState.InOpponentHand; } }
private PlayerAction TryToAnnounce20Or40(PlayerTurnContext context, ICollection <Card> possibleCardsToPlay) { // Choose card with announce 40 if possible foreach (var card in possibleCardsToPlay) { if (card.Type == CardType.Queen && this.AnnounceValidator.GetPossibleAnnounce(this.Cards, card, context.TrumpCard) == Announce.Forty) { return(this.PlayCard(card)); } } // Choose card with announce 20 if possible foreach (var card in possibleCardsToPlay) { if (card.Type == CardType.Queen && this.AnnounceValidator.GetPossibleAnnounce(this.Cards, card, context.TrumpCard) == Announce.Twenty) { return(this.PlayCard(card)); } } return(null); }
public override PlayerAction GetTurn(PlayerTurnContext context) { //if (this.PlayerActionValidator.IsValid(PlayerAction.ChangeTrump(), context, this.Cards)) //{ // this.CardsNotInDeck.Add(context.TrumpCard); // this.CardsNotInDeck.RemoveWhere(c => c.Suit == context.TrumpCard.Suit && c.Type == CardType.Nine); // return this.ChangeTrump(context.TrumpCard); //} //foreach (var card in this.Cards) //{ // if (card.Type == CardType.King && // (this.AnnounceValidator.GetPossibleAnnounce(this.Cards, card, context.TrumpCard) == Announce.Forty || // this.AnnounceValidator.GetPossibleAnnounce(this.Cards, card, context.TrumpCard) == Announce.Twenty)) // { // this.Cards.Remove(card); // return this.PlayCard(card); // } //} var bestCard = this.GetCardToPlay(context); return(this.PlayCard(bestCard)); }
public virtual PlayerAction GetTurn(PlayerTurnContext context) { this.IsFirstPlayer = context.IsFirstPlayerTurn; if (context.CardsLeftInDeck == 0) { this.CardMemorizer.LogTrumpCardDrawn(); } this.SetCorrectState(context); var myHand = this.CardMemorizer.GetMyHand(); if (this.PlayerActionValidator.IsValid(PlayerAction.ChangeTrump(), context, myHand)) { return(this.ChangeTrump()); } if (this.ShouldCloseGame(context)) { return(this.CloseGame()); } return(this.ChooseCard(context)); }
public virtual void EndTurn(PlayerTurnContext context) { if (!this.CardMemorizer.TrumpCardDrawn && !this.CardMemorizer.TrumpCard.Equals(context.TrumpCard)) { this.CardMemorizer.LogTrumpChange(); } if (this.IsFirstPlayer) { this.MyPoints = context.FirstPlayerRoundPoints; this.OpponentPoints = context.SecondPlayerRoundPoints; } else { this.MyPoints = context.SecondPlayerRoundPoints; this.OpponentPoints = context.FirstPlayerRoundPoints; } Card opponentCard = this.GetOpponentCard(context); if (opponentCard != null) { this.CardMemorizer.LogOpponentPlayedCard(opponentCard); } }
protected override PlayerAction ChooseCard(PlayerTurnContext context, ICollection <Card> possibleCardsToPlay) { var myCards = this.Bot.CardMemorizer.MyHand.OrderBy(c => c.GetValue()); //var possibleWins = new System.Collections.Generic.Dictionary<Card, int>(); //foreach (var myCard in myCards) //{ // possibleWins[myCard] = this.Bot.CountPotentialWins(myCard); //} var winningCards = this.Bot.GetWinningCardsWhenFirst(possibleCardsToPlay); var anounce = this.Bot.GetPossibleBestAnounce(possibleCardsToPlay); if (winningCards.Any()) { if (anounce != null && winningCards.Contains(anounce)) { return(this.Bot.PlayCard(anounce)); } Card card = winningCards.FirstOrDefault(this.Bot.IsTrumpCard) ?? winningCards.First(); return(this.Bot.PlayCard(card)); } if (anounce != null) { return(this.Bot.PlayCard(anounce)); } // Likely we will lose the hand so just give the lowest card Card result = myCards.FirstOrDefault(c => !this.Bot.IsTrumpCard(c)) ?? myCards.First(); return(this.Bot.PlayCard(result)); }
protected override PlayerAction ChooseCard(PlayerTurnContext context, ICollection <Card> possibleCardsToPlay) { var myCards = this.Bot.CardMemorizer.MyHand.OrderBy(c => c.GetValue());; var winningCards = this.Bot.GetWinningCardsWhenFirst(possibleCardsToPlay); // Announce 40 or 20 if possible var anounce = this.Bot.GetPossibleBestAnounce(possibleCardsToPlay); if (anounce != null) { return(this.Bot.PlayCard(anounce)); } // Playing the cards that will win the hand if (winningCards.Any()) { return(this.Bot.PlayCard(winningCards.FirstOrDefault(this.Bot.IsTrumpCard) ?? winningCards.Reverse <Card>().First())); } // Likely we will lose the hand so just give the lowest card Card result = myCards.FirstOrDefault(c => !this.Bot.IsTrumpCard(c)) ?? myCards.First(); return(this.Bot.PlayCard(result)); }
public override void EndTurn(PlayerTurnContext context) { this.EndTurnCalledCount++; this.EndTurnContextObject = context.DeepClone(); base.EndTurn(context); }
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); }
private PlayerAction ChooseCard(PlayerTurnContext context) { var orderedCardsByPower = this.PlayerActionValidator.GetPossibleCardsToPlay(context, this.Cards) .OrderByDescending(x => x.GetValue()) .ToArray(); if (context.State.ShouldObserveRules) { if (context.IsFirstPlayerTurn) { return this.ChooseCardWhenPlayingFirst(context, orderedCardsByPower); } else { return this.ChooseCardWhenPlayingSecond(context, orderedCardsByPower); } } else { if (context.IsFirstPlayerTurn) { return this.ChooseCardWhenPlayingFirst(context, orderedCardsByPower); } else { return this.ChooseCardWhenPlayingSecond(context, orderedCardsByPower); } } }
private bool PlayerWins(PlayerTurnContext context, ICollection <Card> hand) { var playerWinsWithHand = false; var playerPoints = context.SecondPlayerRoundPoints; var playedCard = context.FirstPlayedCard; var playedCardIsTrump = playedCard.Suit == context.TrumpCard.Suit; var canTake = hand.Where(x => (x.Suit == playedCard.Suit || (playedCard.Suit != context.TrumpCard.Suit && x.Suit == context.TrumpCard.Suit)) && x.GetValue() > playedCard.GetValue()) .OrderByDescending(x => x.GetValue()) .FirstOrDefault(); if (canTake == null) { return(playerWinsWithHand); } if (playerPoints + playedCard.GetValue() + canTake.GetValue() >= WinPoints) { playerWinsWithHand = true; } return(playerWinsWithHand); }
private PlayerAction ChooseCard(PlayerTurnContext context) { var orderedCardsByPower = this.PlayerActionValidator.GetPossibleCardsToPlay(context, this.Cards) .OrderByDescending(x => x.GetValue()) .ToArray(); if (context.State.ShouldObserveRules) { if (context.IsFirstPlayerTurn) { return(this.ChooseCardWhenPlayingFirst(context, orderedCardsByPower)); } else { return(this.ChooseCardWhenPlayingSecond(context, orderedCardsByPower)); } } else { if (context.IsFirstPlayerTurn) { return(this.ChooseCardWhenPlayingFirst(context, orderedCardsByPower)); } else { return(this.ChooseCardWhenPlayingSecond(context, orderedCardsByPower)); } } }
private bool CloseGame(PlayerTurnContext context) { // If we have 61 points in the hand, it is possible to win the game with it; int currentAllPoints = 0; foreach (var card in this.Cards) { currentAllPoints += card.GetValue(); if (card.Type == CardType.Queen && this.AnnounceValidator.GetPossibleAnnounce(this.Cards, card, context.TrumpCard) == Announce.Forty) { currentAllPoints += 40; } } var shouldCloseGame = this.PlayerActionValidator.IsValid(PlayerAction.CloseGame(), context, this.Cards) && (this.Cards.Count(x => x.Suit == context.TrumpCard.Suit) == WebPlayerConstants.HasEnoughTrumpCards || currentAllPoints >= WebPlayerConstants.MinimumPointsForClosingGame); if (shouldCloseGame) { GlobalStats.GamesClosedByPlayer++; } return(shouldCloseGame); }
private PlayerAction EndGameTurn(PlayerTurnContext context, ICardTracker tracker, ICollection <Card> myHand) { this.root = new Node(null, null, context.IsFirstPlayerTurn); if (context.IsFirstPlayerTurn && this.root.Children.Count == 0) { tracker.SetFinalRoundHands(myHand); var myCards = myHand.ToList(); EndgameAnalyzer.Compute(this.root, null, myCards, tracker.OpponentTookWith, context.SecondPlayerRoundPoints, context.FirstPlayerRoundPoints); } else if (this.root.Children.Count == 0) { tracker.SetFinalRoundHands(myHand); var myCards = myHand.ToList(); while (tracker.OpponentTookWith.Count < 6) { tracker.OpponentTookWith.Add(null); } EndgameAnalyzer.Compute(this.root, context.FirstPlayedCard, myCards, tracker.OpponentTookWith, context.FirstPlayerRoundPoints, context.SecondPlayerRoundPoints); } if (!context.IsFirstPlayerTurn) { this.root = this.root.Children.First(x => x.Card == context.FirstPlayedCard); } var card = this.root.Children.OrderByDescending(x => x.Wins / (decimal)x.Total).First().Card; return(PlayerAction.PlayCard(card)); }
private PlayerAction GetTurnChain(PlayerTurnContext context) { var decisionContext = new DecisionMakingContext() { ActionChoser = ActionChoser, CardChoser = CardChoser, MyCards = this.Cards, Tracker = Tracker, TurnContext = context, Validator = this.PlayerActionValidator }; // TODO: this of something more elegant var action = decisionMaker.Handle(decisionContext); switch (action.Type) { case PlayerActionType.PlayCard: return(this.PlayCard(action.Card)); case PlayerActionType.ChangeTrump: return(this.ChangeTrump(context.TrumpCard)); case PlayerActionType.CloseGame: return(this.CloseGame()); default: throw new InvalidOperationException("Invalid type of player action"); } }
public override void EndTurn(PlayerTurnContext context) { Tracker.TrickResolution(context); Report.Add(context.Stringify(this.myTurn) + " --- current hand: " + string.Join(", ", this.Cards.Select(x => x.ToString()))); base.EndTurn(context); }
protected Card TryToAnnounce20Or40(PlayerTurnContext context, ICollection <Card> possibleCardsToPlay) { if (!context.State.CanAnnounce20Or40) { return(null); } // Choose card with announce 40 if possible foreach (var card in possibleCardsToPlay) { if (card.Type == CardType.Queen && this.Validator.GetPossibleAnnounce(this.Cards, card, context.TrumpCard) == Announce.Forty) { return(card); } } // Choose card with announce 20 if possible foreach (var card in possibleCardsToPlay) { if (card.Type == CardType.Queen && this.Validator.GetPossibleAnnounce(this.Cards, card, context.TrumpCard) == Announce.Twenty) { return(card); } } return(null); }
private PlayerAction ChooseCardWhenPlayingSecond(PlayerTurnContext context, ICollection <Card> orderedCardsByPower) { ICollection <Card> trumpCards = orderedCardsByPower .Where(x => x.Suit == context.TrumpCard.Suit) .ToArray(); // If we have a bigger card of the same suit, we play it. var biggerCardOfSameSuit = orderedCardsByPower .Where(x => x.Suit == context.FirstPlayedCard.Suit && x.GetValue() > context.FirstPlayedCard.GetValue()) .FirstOrDefault(); // If we have a card of the same suit, we play it. if (biggerCardOfSameSuit != null) { return(this.PlayCard(biggerCardOfSameSuit)); } // If we don't have a card of the same suit, we play the smallest trump card else { // We will use trump cards only on strong opponent cards if (context.FirstPlayedCard.Type == CardType.Ten || context.FirstPlayedCard.Type == CardType.Ace) { if (trumpCards.Count > 0) { return(this.PlayCard(trumpCards.LastOrDefault())); } else { return(this.PlayCard(orderedCardsByPower.LastOrDefault())); } } return(this.PlayCard(orderedCardsByPower.LastOrDefault())); } }
private PlayerAction ChooseCardWhenPlayingSecondAndRulesApply( PlayerTurnContext context, ICollection <Card> possibleCardsToPlay) { // If bigger card is available => play it var biggerCard = possibleCardsToPlay.Where( x => x.Suit == context.FirstPlayedCard.Suit && x.GetValue() > context.FirstPlayedCard.GetValue()) .OrderByDescending(x => x.GetValue()) .FirstOrDefault(); if (biggerCard != null) { return(this.PlayCard(biggerCard)); } // Play smallest trump card? var smallestTrumpCard = possibleCardsToPlay.Where(x => x.Suit == context.TrumpCard.Suit) .OrderBy(x => x.GetValue()) .FirstOrDefault(); if (smallestTrumpCard != null) { return(this.PlayCard(smallestTrumpCard)); } // Smallest card var cardToPlay = possibleCardsToPlay.OrderBy(x => x.GetValue()).FirstOrDefault(); return(this.PlayCard(cardToPlay)); }
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())); }
public override PlayerAction ChooseCard(PlayerTurnContext context, ICollection <Card> possibleCardsToPlay) { // Announce 40 or 20 if possible var cardFor20Or40 = this.TryToAnnounce20Or40(context, possibleCardsToPlay); if (cardFor20Or40 != null) { // When playing a trump card and then announcing 40 or 20 will win the round then do it. var opponentHasTrump = this.Tracker.UnknownCards.Any(x => x.Suit == context.TrumpCard.Suit); var cardWhichWillSurelyWinTheTrick = this.GetCardWhichWillSurelyWinTheTrick(context.TrumpCard.Suit, opponentHasTrump); if (cardWhichWillSurelyWinTheTrick != null) { var points = context.FirstPlayerRoundPoints; points += cardWhichWillSurelyWinTheTrick.GetValue(); if (cardFor20Or40.Suit == context.TrumpCard.Suit) { points += 40; } else { points += 20; } if (points >= 66) { return(PlayerAction.PlayCard(cardWhichWillSurelyWinTheTrick)); } } return(PlayerAction.PlayCard(cardFor20Or40)); } // If the player is close to the win => play trump card which will surely win the trick var cardToWinTheGame = this.GetCardWhichWillSurelyWinTheGame( context.TrumpCard.Suit, context.FirstPlayerRoundPoints, possibleCardsToPlay); if (cardToWinTheGame != null) { return(PlayerAction.PlayCard(cardToWinTheGame)); } // Smallest non-trump card from the shortest opponent suit var cardToPlay = possibleCardsToPlay.Where(x => x.Suit != context.TrumpCard.Suit) .OrderBy(x => this.Tracker.UnknownCards.Count(y => y.Suit == x.Suit)) .ThenBy(x => x.GetValue()) .FirstOrDefault(); if (cardToPlay != null) { return(PlayerAction.PlayCard(cardToPlay)); } // Should never happen cardToPlay = possibleCardsToPlay.OrderBy(x => x.GetValue()).FirstOrDefault(); return(PlayerAction.PlayCard(cardToPlay)); }
/// <summary> /// Gets the player action by given player turn context /// </summary> /// <param name="context">The player turn context information</param> /// <returns>The player action</returns> public override PlayerAction GetTurn(PlayerTurnContext context) { var possibleCardsToPlay = this.PlayerActionValidator.GetPossibleCardsToPlay(context, this.Cards); var shuffledCards = possibleCardsToPlay.Shuffle(); var cardToPlay = shuffledCards.First(); return(this.PlayCard(cardToPlay)); }
public virtual Card Execute(PlayerTurnContext context, BasePlayer basePlayer, Card playerAnnounce) { var possibleCardsToPlay = this.playerActionValidator.GetPossibleCardsToPlay(context, this.cards); var shuffledCards = possibleCardsToPlay.Shuffle(); var cardToPlay = shuffledCards.First(); return cardToPlay; }
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); }
private Card GetCardToPlay(PlayerTurnContext context) { foreach (var card in this.Cards) { if (!this.CardsNotInDeck.Contains(card)) { this.CardsNotInDeck.Add(card); } } if (context.FirstPlayedCard != null) { this.CardsNotInDeck.Add(context.FirstPlayedCard); } if (context.SecondPlayedCard != null) { this.CardsNotInDeck.Add(context.SecondPlayedCard); } var validCards = this.GetValidCards(context); var hashedHand = this.GetHash(this.Cards, this.CardsNotInDeck); if (this.MonteCarlo.ContainsKey(hashedHand)) { for (int i = 0; i < validCards.Count; i++) { var cardHash = this.GetTwoNumberHash((uint)validCards[i].Type, (uint)validCards[i].Suit); if (validCards[i] == this.MonteCarlo[hashedHand]) { return(validCards[i]); } } } float bestActionProbability = float.MinValue; int bestActionIndex = 0; var currentContext = GetCurrentContext(context); var helper = new SantiagoHelper(this.Cards); for (int i = 0; i < validCards.Count; i++) { var probability = helper.GetProbability(currentContext, validCards[i], this.CardsNotInDeck, this.Cards); if (probability >= bestActionProbability) { bestActionProbability = probability; bestActionIndex = i; } } this.MonteCarlo[hashedHand] = validCards[bestActionIndex]; return(validCards[bestActionIndex]); }
public void CloneShouldReturnObjectOfTypePlayerTurnContext() { var haveStateMock = new Mock <IStateManager>(); var state = new TwoCardsLeftRoundState(haveStateMock.Object); var playerTurnContext = new PlayerTurnContext(state, new Card(CardSuit.Diamond, CardType.Ace), 2, 0, 0); var clonedPlayerTurnContext = playerTurnContext.DeepClone(); Assert.IsInstanceOf <PlayerTurnContext>(clonedPlayerTurnContext); }
// TODO: Improve close game decision private bool CloseGame(PlayerTurnContext context) { if (!this.PlayerActionValidator.IsValid(PlayerAction.CloseGame(), context, this.Cards)) { return(false); } return(this.Cards.Count(x => x.Suit == context.TrumpCard.Suit) == 5); }
public void CloneShouldReturnDifferentReference() { var haveStateMock = new Mock <IStateManager>(); var state = new StartRoundState(haveStateMock.Object); var playerTurnContext = new PlayerTurnContext(state, new Card(CardSuit.Heart, CardType.Queen), 12, 0, 0); var clonedPlayerTurnContext = playerTurnContext.DeepClone(); Assert.AreNotSame(playerTurnContext, clonedPlayerTurnContext); }
public override void EndTurn(PlayerTurnContext context) { Console.SetCursorPosition(20, 9); Console.WriteLine($"{context.FirstPlayedCard} - {context.SecondPlayedCard} "); Thread.Sleep(3000); Console.SetCursorPosition(20, 9); Console.WriteLine($" "); }
private PlayerAction ChooseCardWhenPlayingFirstAndRulesApply( PlayerTurnContext context, ICollection <Card> possibleCardsToPlay) { // Find card that will surely win the trick var opponentHasTrump = this.opponentSuitCardsProvider.GetOpponentCards( this.Cards, this.playedCards, context.CardsLeftInDeck == 0 ? null : context.TrumpCard, context.TrumpCard.Suit).Any(); var trumpCard = this.GetCardWhichWillSurelyWinTheTrick( context.TrumpCard.Suit, context.CardsLeftInDeck == 0 ? null : context.TrumpCard, opponentHasTrump); if (trumpCard != null) { return(this.PlayCard(trumpCard)); } foreach (CardSuit suit in Enum.GetValues(typeof(CardSuit))) { var possibleCard = this.GetCardWhichWillSurelyWinTheTrick( suit, context.CardsLeftInDeck == 0 ? null : context.TrumpCard, opponentHasTrump); if (possibleCard != null) { return(this.PlayCard(possibleCard)); } } // Announce 40 or 20 if possible var action = this.TryToAnnounce20Or40(context, possibleCardsToPlay); if (action != null) { return(action); } // Smallest non-trump card var cardToPlay = possibleCardsToPlay.Where(x => x.Suit != context.TrumpCard.Suit) .OrderBy(x => x.GetValue()) .FirstOrDefault(); if (cardToPlay != null) { return(this.PlayCard(cardToPlay)); } // Smallest card cardToPlay = possibleCardsToPlay.OrderBy(x => x.GetValue()).FirstOrDefault(); return(this.PlayCard(cardToPlay)); }
private PlayerAction ChooseCard(PlayerTurnContext context) { var possibleCardsToPlay = this.PlayerActionValidator.GetPossibleCardsToPlay(context, this.Cards); return context.State.ShouldObserveRules ? (context.IsFirstPlayerTurn ? this.ChooseCardWhenPlayingFirstAndRulesApply(context, possibleCardsToPlay) : this.ChooseCardWhenPlayingSecondAndRulesApply(context, possibleCardsToPlay)) : (context.IsFirstPlayerTurn ? this.ChooseCardWhenPlayingFirstAndRulesDoNotApply(context, possibleCardsToPlay) : this.ChooseCardWhenPlayingSecondAndRulesDoNotApply(context, possibleCardsToPlay)); }
public override PlayerAction GetTurn(PlayerTurnContext context) { if (this.PlayerActionValidator.IsValid(PlayerAction.ChangeTrump(), context, this.Cards)) { return this.ChangeTrump(context.TrumpCard); } if (this.CloseGame(context)) { return this.CloseGame(); } return this.ChooseCard(context); }
protected override PlayerAction ChooseCard(PlayerTurnContext context, ICollection<Card> possibleCardsToPlay) { Card opponentCard = this.Bot.GetOpponentCard(context); var winningCards = this.Bot.GetWinningCardsWhenSecond(possibleCardsToPlay, opponentCard); if (!winningCards.Any()) { return this.Bot.PlayCard(this.Bot.GetWeakestCard(possibleCardsToPlay)); } winningCards = winningCards.Reverse(); Card card = winningCards.FirstOrDefault(c => !this.Bot.IsTrumpCard(c)) ?? winningCards.First(); return this.Bot.PlayCard(card); }
public override void EndTurn(PlayerTurnContext context) { if (this.BotskoFirstPlayed == context.FirstPlayedCard) { BotskoIsFirstPlayer = true; } if (this.BotskoFirstPlayed == context.SecondPlayedCard) { BotskoIsFirstPlayer = false; } this.FirstTurnLogic.RegisterUsedCard(context.FirstPlayedCard); this.FirstTurnLogic.RegisterUsedCard(context.SecondPlayedCard); base.EndTurn(context); }
public override PlayerAction GetTurn(PlayerTurnContext context) { // When possible change the trump card as this is almost always a good move // Changing trump can be non-optimal when: // 1. Current player is planning to close the game and don't want to give additional points to his opponent // 2. The player will close the game and you will give him additional points by giving him bigger trump card instead of 9 // 3. Want to confuse the opponent if (this.PlayerActionValidator.IsValid(PlayerAction.ChangeTrump(), context, this.Cards)) { return this.ChangeTrump(context.TrumpCard); } if (this.CloseGame(context)) { return this.CloseGame(); } return this.ChooseCard(context); }
public override PlayerAction GetTurn(PlayerTurnContext context) { var currentGameState = context.State.GetType().Name; // If enemy has announce, add other card from announce to enemy card collection. if (context.FirstPlayerAnnounce != Announce.None) { var otherTypeFromAnnounce = context.FirstPlayedCard.Type == CardType.King ? CardType.Queen : CardType.King; var otherCardFromAnnounce = new Card(context.FirstPlayedCard.Suit, otherTypeFromAnnounce); this.cardHolder.EnemyCards.Add(otherCardFromAnnounce); this.cardHolder.AllCards[otherCardFromAnnounce.Suit][otherCardFromAnnounce.Type] = CardStatus.InEnemy; } // If in final state refresh enemy cards if (currentGameState == GameStates.FinalRoundState && context.CardsLeftInDeck == 0 && this.Cards.Count == 6) { this.cardHolder.RefreshEnemyCards(); if (context.FirstPlayedCard != null) { this.cardHolder.EnemyCards.Remove(context.FirstPlayedCard); } } // Try to change to exchange the bottom trump card from the deck. if (this.PlayerActionValidator.IsValid(PlayerAction.ChangeTrump(), context, this.Cards)) { return this.ChangeTrump(context.TrumpCard); } // In case all requirements are met: close the game. if (context.FirstPlayedCard == null && currentGameState == GameStates.MoreThanTwoCardsLeftRoundState && context.State.CanClose && this.stalkerHelper.CanCloseTheGame(context, this.Cards)) { return this.CloseGame(); } var cardToPlay = context.FirstPlayedCard != null ? this.GetBestCardToRespond(context) : this.GetBestCardToPlayFirst(context); return this.PlayCard(cardToPlay); }
public override void EndTurn(PlayerTurnContext context) { if (this.Cards.Count <= 6) { this.cardHolder.EnemyCards.Remove(context.FirstPlayedCard); this.cardHolder.EnemyCards.Remove(context.SecondPlayedCard); } // If round ends with 20 or 40 announce one of the players could have not played a card. if (context.FirstPlayedCard != null) { this.cardHolder.AllCards[context.FirstPlayedCard.Suit][context.FirstPlayedCard.Type] = CardStatus.Passed; } if (context.SecondPlayedCard != null) { this.cardHolder.AllCards[context.SecondPlayedCard.Suit][context.SecondPlayedCard.Type] = CardStatus.Passed; } base.EndTurn(context); }
public bool IsGoodToClose(PlayerTurnContext context) { if (!context.State.CanClose) { return false; } var handSummary = this.GetTrumpsInHand(this.cards, context.TrumpCard.Suit); if (handSummary.CountOfTrumps > 4) { return true; //// With more than 4 trumps in hand => go get the win } if (handSummary.CountOfTrumps == 4 && handSummary.CountOfAcesNoTrumps > 1) { var condition = this.cards .Where(c => c.Suit == context.TrumpCard.Suit && (c.Type == CardType.Queen || c.Type == CardType.King)) .Count(); if (condition == 2) { return true; ////4 trumps, maybe 40 as announce and at least one ace has good chance to win the game } } if (handSummary.CountOfTrumps >= 3 && handSummary.CountOfAcesNoTrumps > 0 && (66 - (handSummary.PointsOfAll + handSummary.PointsOfTrumps + context.FirstPlayerRoundPoints)) <= 15) { if (this.IsThereBigCardsInPlay(context.TrumpCard.Suit, 3)) //// Secure the choice even more if big values are gone, it is risky { return true; //// At least 3 trumps, 1 ace and points close to win } } return false; }
public bool CanCloseTheGame(PlayerTurnContext context, ICollection<Card> playerCards) { // Stalker has A and 10 from trumps, certain ammount of points and some other winning cards. var hasHighTrumps = this.cardHolder.AllCards[context.TrumpCard.Suit][CardType.Ace] == CardStatus.InStalker && this.cardHolder.AllCards[context.TrumpCard.Suit][CardType.Ten] == CardStatus.InStalker; // Stalker has 40 and is already above certain points. var has40 = this.cardHolder.AllCards[context.TrumpCard.Suit][CardType.King] == CardStatus.InStalker && this.cardHolder.AllCards[context.TrumpCard.Suit][CardType.Queen] == CardStatus.InStalker; var hasEnoughAfterAnounce = context.FirstPlayerRoundPoints > StalkerHelperConstants.CloseGamePointsBeforeAnnounce; var hasNecessaryPoints = playerCards.Sum(c => c.GetValue()) + context.FirstPlayerRoundPoints > StalkerHelperConstants.CloseGameMinimumPoints; var sureWiningCards = playerCards.Count(card => !this.ContainsGreaterCardThan(card, CardStatus.InDeckOrEnemy)); if (has40 && hasEnoughAfterAnounce) { return true; } return hasHighTrumps && hasNecessaryPoints && sureWiningCards > 0; }
private bool CloseGame(PlayerTurnContext context) { // If we have 61 points in the hand, it is possible to win the game with it; int currentAllPoints = 0; foreach (var card in this.Cards) { currentAllPoints += card.GetValue(); if (card.Type == CardType.Queen && this.AnnounceValidator.GetPossibleAnnounce(this.Cards, card, context.TrumpCard) == Announce.Forty) { currentAllPoints += 40; } } var shouldCloseGame = this.PlayerActionValidator.IsValid(PlayerAction.CloseGame(), context, this.Cards) && (this.Cards.Count(x => x.Suit == context.TrumpCard.Suit) == WebPlayerConstants.HasEnoughTrumpCards || currentAllPoints >= WebPlayerConstants.MinimumPointsForClosingGame); if (shouldCloseGame) { GlobalStats.GamesClosedByPlayer++; } return shouldCloseGame; }
/// <summary> /// Check for 100% winning card in the hand /// </summary> /// <param name="context">The information about current turn.</param> /// <param name="possibleCardsToPlay">Cards that player can play.</param> /// <returns>If the player have winning card return true, /// if not return false.</returns> public bool CanWinWithTrumpCard(PlayerTurnContext context, ICollection<Card> possibleCardsToPlay) { var biggestTrumpCardInHand = this.FindTrumpCardsInHand(possibleCardsToPlay, context.TrumpCard.Suit) .FirstOrDefault(); if (biggestTrumpCardInHand == null) { return false; } int botskoPoints = BotskoPlayer.BotskoIsFirstPlayer ? context.FirstPlayerRoundPoints : context.SecondPlayerRoundPoints; var pointsWithBiggestTrumpCard = biggestTrumpCardInHand.GetValue() + botskoPoints; if (this.IsBiggestCardInMyHand(biggestTrumpCardInHand) && pointsWithBiggestTrumpCard >= 66) { this.currentWinningCard = biggestTrumpCardInHand; return true; } return false; }
protected PlayerAction AnnounceMarriage(PlayerTurnContext context, ICollection<Card> cards) { if (context.State.CanAnnounce20Or40) { // get 40 var card = this.GetAnnounce(context, Announce.Forty, cards); if (card != null) { return this.PlayCard(cards, card); } // get 20 card = this.GetAnnounce(context, Announce.Twenty, cards); if (card != null) { return this.PlayCard(cards, card); } } return null; }
protected override PlayerAction ChooseCard(PlayerTurnContext context, ICollection<Card> possibleCardsToPlay) { var myCards = this.Bot.CardMemorizer.MyHand.OrderBy(c => c.GetValue()); ; var winningCards = this.Bot.GetWinningCardsWhenFirst(possibleCardsToPlay); // Announce 40 or 20 if possible var anounce = this.Bot.GetPossibleBestAnounce(possibleCardsToPlay); if (anounce != null) { return this.Bot.PlayCard(anounce); } // Playing the cards that will win the hand if (winningCards.Any()) { return this.Bot.PlayCard(winningCards.FirstOrDefault(this.Bot.IsTrumpCard) ?? winningCards.Reverse<Card>().First()); } // Likely we will lose the hand so just give the lowest card Card result = myCards.FirstOrDefault(c => !this.Bot.IsTrumpCard(c)) ?? myCards.First(); return this.Bot.PlayCard(result); }
private PlayerAction ChooseCardWhenPlayingFirstAndRulesApply(PlayerTurnContext context, ICollection<Card> possibleCardsToPlay) { var action = this.TryToAnnounce20Or40(context, possibleCardsToPlay); if (action != null) { return action; } // TODO: The logic below should be extracted somewhere var cardToPlay = possibleCardsToPlay .Where(c => (c.Suit == context.TrumpCard.Suit)) .OrderByDescending(c => c.GetValue()) .FirstOrDefault(); if (cardToPlay != null) { if (cardToPlay.Type == CardType.Ace) { return this.PlayCard(cardToPlay); } if (cardToPlay.Type == CardType.Ten && this.playedCards.Contains(new Card(context.TrumpCard.Suit, CardType.Ace))) { return this.PlayCard(cardToPlay); } if (cardToPlay.Type == CardType.King && this.playedCards.Contains(new Card(context.TrumpCard.Suit, CardType.Ace)) && this.playedCards.Contains(new Card(context.TrumpCard.Suit, CardType.Ten))) { return this.PlayCard(cardToPlay); } if (cardToPlay.Type == CardType.Queen && this.playedCards.Contains(new Card(context.TrumpCard.Suit, CardType.Ace)) && this.playedCards.Contains(new Card(context.TrumpCard.Suit, CardType.Ten)) && this.playedCards.Contains(new Card(context.TrumpCard.Suit, CardType.King))) { return this.PlayCard(cardToPlay); } if (cardToPlay.Type == CardType.Jack && this.playedCards.Contains(new Card(context.TrumpCard.Suit, CardType.Ace)) && this.playedCards.Contains(new Card(context.TrumpCard.Suit, CardType.Ten)) && this.playedCards.Contains(new Card(context.TrumpCard.Suit, CardType.King)) && this.playedCards.Contains(new Card(context.TrumpCard.Suit, CardType.Queen))) { return this.PlayCard(cardToPlay); } if (cardToPlay.Type == CardType.Nine && this.playedCards.Contains(new Card(context.TrumpCard.Suit, CardType.Ace)) && this.playedCards.Contains(new Card(context.TrumpCard.Suit, CardType.Ten)) && this.playedCards.Contains(new Card(context.TrumpCard.Suit, CardType.King)) && this.playedCards.Contains(new Card(context.TrumpCard.Suit, CardType.Queen)) && this.playedCards.Contains(new Card(context.TrumpCard.Suit, CardType.Jack))) { return this.PlayCard(cardToPlay); } } cardToPlay = this.HighCardThatWontBeTaken(context, possibleCardsToPlay); if (cardToPlay != null) { return this.PlayCard(cardToPlay); } return this.PlayCard(possibleCardsToPlay.OrderBy(c => c.GetValue()).FirstOrDefault()); }
private PlayerAction ChooseCardWhenPlayingSecondAndRulesDoNotApply(PlayerTurnContext context, ICollection<Card> possibleCardsToPlay) { var opponentCard = context.FirstPlayedCard; var trumpCards = possibleCardsToPlay .Where(c => c.Suit == context.TrumpCard.Suit) .OrderByDescending(c => c.GetValue()) .ToList(); if (trumpCards.Count != 0 && trumpCards[0].GetValue() + opponentCard.GetValue() + context.SecondPlayerRoundPoints >= 66) { return this.PlayCard(trumpCards[0]); } if (trumpCards.Count != 0 && (opponentCard.Type == CardType.Ace || opponentCard.Type == CardType.Ten)) { return this.PlayCard(trumpCards[trumpCards.Count - 1]); } if (context.CardsLeftInDeck == 2) { if (context.TrumpCard.Type != CardType.Jack && context.TrumpCard.Type != CardType.Nine) { var card = this.FindSmallestValueCard(context, opponentCard, possibleCardsToPlay); if (card != null) { return this.PlayCard(card); } return this.PlayCard(possibleCardsToPlay .OrderBy(c => c.GetValue()) .FirstOrDefault(c => c.Suit != context.TrumpCard.Suit)); } } var cardToPlay = this.FindHighestValueCardFromSuit(opponentCard, possibleCardsToPlay); if (cardToPlay != null) { return this.PlayCard(cardToPlay); } cardToPlay = this.FindSmallestValueCard(context, opponentCard, possibleCardsToPlay); if (cardToPlay != null) { return this.PlayCard(cardToPlay); } return this.PlayCard(possibleCardsToPlay.OrderBy(c => c.GetValue()).FirstOrDefault()); }
public override void EndTurn(PlayerTurnContext context) { this.playedCards.Add(context.FirstPlayedCard); this.playedCards.Add(context.SecondPlayedCard); }
private bool CloseGame(PlayerTurnContext context) { var possibleCardsToPlay = this.PlayerActionValidator.GetPossibleCardsToPlay(context, this.Cards); var cardsSum = possibleCardsToPlay.Sum(c => c.GetValue()); var trumpsCount = possibleCardsToPlay.Count(c => c.Suit == context.TrumpCard.Suit); if (this.PlayerActionValidator.IsValid(PlayerAction.CloseGame(), context, this.Cards)) { if (trumpsCount >= 5) { return true; } else if (possibleCardsToPlay.Count(c => c.Type == CardType.Ace) >= 3 && possibleCardsToPlay.Count(c => c.Type == CardType.Ten) >= 2) { return true; } else if (cardsSum >= 50) { return true; } } return false; }
private bool CloseGame(PlayerTurnContext context) { throw new NotImplementedException(); }
private PlayerAction ChooseCard(PlayerTurnContext context) { throw new NotImplementedException(); }
private Card FindSmallestValueCard(PlayerTurnContext context, Card opponentCard, ICollection<Card> possibleCardsToPlay) { var smallestCard = possibleCardsToPlay .Where(c => (c.Suit != context.TrumpCard.Suit) && (c.Type == CardType.Jack || c.Type == CardType.Nine)) .FirstOrDefault(); return smallestCard; }
public override PlayerAction GetTurn(PlayerTurnContext context, IPlayerActionValidater actionValidater) { // TODO: implement method return null; }
public override PlayerAction ChooseCard(PlayerTurnContext context, ICollection<Card> cards) { Card card; if (!this.cardValidator.IsTrump(context.FirstPlayedCard, this.cardTracker.TrumpSuit)) { // play higher card not part of announce card = this.GetHigherCard(context.FirstPlayedCard); if (card != null && !this.cardValidator.IsCardInAnnounce(context, card, this.possibleCardsToPlay, Announce.Twenty)) { return this.PlayCard(cards, card); } // play high trump to win the round card = this.GetHighestCardInSuit(this.possibleCardsToPlay, this.cardTracker.TrumpSuit); if (card != null && this.cardTracker.MyTrickPoints >= GlobalConstants.EnoughPointsToWinGame - (context.FirstPlayedCard.GetValue() + card.GetValue())) { return this.PlayCard(cards, card); } } else { // opponent has Ace and plays small trump => play trump 10 if (context.FirstPlayedCard.Type != CardType.Ace && this.cardTracker.FindRemainingCard(CardType.Ace, this.cardTracker.TrumpSuit) != null) { card = this.possibleCardsToPlay.FirstOrDefault(c => c.Type == CardType.Ten && c.Suit == this.cardTracker.TrumpSuit); if (card != null) { return this.PlayCard(cards, card); } } // opponent plays forty => play card to win if (context.FirstPlayerAnnounce == Announce.Forty) { card = this.GetHigherCard(context.FirstPlayedCard); if (card != null) { return this.PlayCard(cards, card); } } //} // player has Ace and first played card is not Ten => play smallest trump to win if (this.cardTracker.FindMyRemainingTrumpCard(CardType.Ace) != null && context.FirstPlayedCard.Type != CardType.Ten) { // if it will win the round or opponent has announced forty => play Ace if (this.cardTracker.MyTrickPoints + context.FirstPlayedCard.GetValue() >= 55 || context.FirstPlayerAnnounce == Announce.Forty) { card = this.possibleCardsToPlay.FirstOrDefault(c => c.Type == CardType.Ace); return this.PlayCard(cards, card); } // play smallest trump that will win and is not in forty card = this.possibleCardsToPlay.OrderBy(c => c.GetValue()) .FirstOrDefault(c => c.GetValue() > context.FirstPlayedCard.GetValue() && !this.cardValidator.IsCardInAnnounce(context, c, this.possibleCardsToPlay, Announce.Forty)); if (card != null) { return this.PlayCard(cards, card); } // if opponent is not close to the win play smallest trump that will not win card = this.possibleCardsToPlay.OrderBy(c => c.GetValue()) .FirstOrDefault(); if (this.cardTracker.OpponentsTrickPoints + context.FirstPlayedCard.GetValue() + card.GetValue() < 55) { return this.PlayCard(cards, card); } // play trump Ace card = this.possibleCardsToPlay.FirstOrDefault(c => c.Type == CardType.Ace); return this.PlayCard(cards, card); } card = this.GetHigherCard(context.FirstPlayedCard); if (card != null && !this.cardValidator.IsCardInAnnounce(context, card, this.possibleCardsToPlay, Announce.Forty)) { return this.PlayCard(cards, card); } } // play smallest non-announce non-trump card card = this.GetSmallestNonAnnounceNonTrumpCard(context); if (card != null) { return this.PlayCard(cards, card); } // play smallest non-trump card card = this.GetSmallestNonTrumpCard(); if (card != null) { return this.PlayCard(cards, card); } card = GetSmallestNonAnnounceTrumpCard(context); if (card != null) { return this.PlayCard(cards, card); } return this.PlayCard(cards, this.GetSmallestCard()); }
private Card HighCardThatWontBeTaken(PlayerTurnContext context, ICollection<Card> possibleCardsToPlay) { var aces = possibleCardsToPlay.Where(c => c.Type == CardType.Ace); foreach (var ace in aces) { if (this.playedCards.Where(c => c != null).Count(c => c.Suit == ace.Suit) <= 4) { return ace; } } var tens = possibleCardsToPlay.Where(c => c.Type == CardType.Ten); foreach (var ten in tens) { if (this.playedCards.Where(c => c != null).Count(c => c.Suit == ten.Suit) <= 4 && this.playedCards.Contains(new Card(ten.Suit, CardType.Ace))) { return ten; } } foreach (var card in possibleCardsToPlay) { if (this.playedCards.Where(c => c != null).Any(c => c.Suit == card.Suit && c.GetValue() > card.GetValue())) { return card; } } return null; }
private PlayerAction TryToAnnounce20Or40(PlayerTurnContext context, ICollection<Card> possibleCardsToPlay) { foreach (var card in possibleCardsToPlay) { if (card.Type == CardType.Queen && (this.AnnounceValidator.GetPossibleAnnounce(this.Cards, card, context.TrumpCard) == Announce.Forty || this.AnnounceValidator.GetPossibleAnnounce(this.Cards, card, context.TrumpCard) == Announce.Twenty)) { return this.PlayCard(card); } } return null; }
public void GetTrickPoints(PlayerTurnContext context) { this.MyTrickPoints = context.IsFirstPlayerTurn ? context.FirstPlayerRoundPoints : context.SecondPlayerRoundPoints; this.OpponentsTrickPoints = context.IsFirstPlayerTurn ? context.SecondPlayerRoundPoints : context.FirstPlayerRoundPoints; }
public ICollection<Card> GetSureCardsWhenGameClosed(PlayerTurnContext context, ICollection<Card> cards, bool deckHasCards = true) { var sureCards = new List<Card>(); cards = cards.OrderByDescending(c => c.GetValue()).ToList(); var opponentsCards = this.RemainingCards.OrderByDescending(c => c.GetValue()).ToList(); foreach (var myCard in cards) { // if card is part of an announce => skip it if (this.cardValidator.IsCardInAnnounce(context, myCard, cards, Announce.Forty) || this.cardValidator.IsCardInAnnounce(context, myCard, cards, Announce.Twenty)) { continue; } // if opponent has no trump cards & no cards of myCard's suit & myCard is not trump => sure card var opponentsCardsInSuit = opponentsCards.Where(c => c.Suit == myCard.Suit) .OrderByDescending(c => c.GetValue()).ToList(); if (!this.cardValidator.HasTrumpCard(context, this.RemainingCards) && opponentsCardsInSuit.Count == 0) //&& myCard.Suit != this.TrumpSuit - TODO: check { sureCards.Add(myCard); } // add trump ace if (deckHasCards && myCard.Type == CardType.Ace && myCard.Suit == this.TrumpSuit) { sureCards.Add(myCard); } // add trump ten if ace is played or in player if (deckHasCards && myCard.Type == CardType.Ten && myCard.Suit == this.TrumpSuit && (this.FindPlayedCard(CardType.Ace, this.TrumpSuit) != null || this.FindMyRemainingTrumpCard(CardType.Ace) != null)) { sureCards.Add(myCard); } foreach (var opponetCard in opponentsCardsInSuit) { // if opponent has any higher card in that suit if (opponentsCardsInSuit.Any(c => c.GetValue() > myCard.GetValue())) { break; } if (myCard.GetValue() > opponetCard.GetValue()) { if (deckHasCards) { // if game is closed but deck is not empty => add card if opponent has no trump cards || if it's top trumps if (!this.cardValidator.HasTrumpCard(context, this.RemainingCards)) { this.MySureTrickPoints += (myCard.GetValue() + opponetCard.GetValue()); sureCards.Add(myCard); } } else { // if deck is empty => sure card this.MySureTrickPoints += (myCard.GetValue() + opponetCard.GetValue()); sureCards.Add(myCard); opponentsCards.Remove(opponetCard); } break; } } } return sureCards; }
private Card GetBestCardToPlayFirst(PlayerTurnContext context) { var currentGameState = context.State.GetType().Name; var possibleCards = this.PlayerActionValidator.GetPossibleCardsToPlay(context, this.Cards); var cardToPlay = this.stalkerHelper.CheckForAnounce(context.TrumpCard.Suit, context.CardsLeftInDeck, currentGameState, this.Cards); var cardsByPower = this.Cards.OrderByDescending(c => c.GetValue()); if (cardToPlay != null) { return cardToPlay; } if (currentGameState == GameStates.StartRoundState) { cardToPlay = this.cardChooser.ChooseCardToPlay(context, possibleCards); return cardToPlay; } if (currentGameState == GameStates.FinalRoundState && context.CardsLeftInDeck == 0) { foreach (var card in cardsByPower) { if (this.stalkerHelper.ContainsLowerCardThan(card, CardStatus.InEnemy) && !this.stalkerHelper.ContainsGreaterCardThan(card, CardStatus.InEnemy)) { return card; } } var enemyHasTrump = this.cardHolder.EnemyCards.Any(c => c.Suit == context.TrumpCard.Suit); var cardThatEnemyHasNotAsSuit = this.stalkerHelper.GetCardWithSuitThatEnemyDoesNotHave(enemyHasTrump, context.TrumpCard.Suit, this.Cards); if (cardThatEnemyHasNotAsSuit == null) { cardThatEnemyHasNotAsSuit = cardsByPower.LastOrDefault(); } return cardThatEnemyHasNotAsSuit; } if (currentGameState == GameStates.FinalRoundState) { var trump = cardsByPower.FirstOrDefault(c => c.Suit == context.TrumpCard.Suit); if (trump != null && !this.stalkerHelper.ContainsGreaterCardThan(trump, CardStatus.InDeckOrEnemy)) { return trump; } foreach (var card in cardsByPower) { if (this.stalkerHelper.ContainsLowerCardThan(card, CardStatus.InDeckOrEnemy)) { return card; } } cardToPlay = cardsByPower.Last(); } else if (currentGameState == GameStates.TwoCardsLeftRoundState) { cardToPlay = this.Cards.Where(c => c.Suit != context.TrumpCard.Suit).OrderBy(c => c.GetValue()).FirstOrDefault(); } else if (currentGameState == GameStates.MoreThanTwoCardsLeftRoundState) { cardToPlay = this.cardChooser.ChooseCardToPlay(context, possibleCards); } return cardToPlay; }
private Card GetBestCardToRespond(PlayerTurnContext context) { var enemyCard = context.FirstPlayedCard; var enemyCardPriority = this.stalkerHelper.GetCardPriority(enemyCard); var possibleCards = this.PlayerActionValidator.GetPossibleCardsToPlay(context, this.Cards); var trumpSuit = context.TrumpCard.Suit; // Use trump to take the enemy card in case it is with higher value if ((enemyCardPriority == 2) && enemyCard.Suit != trumpSuit && possibleCards.Any(c => c.Suit == trumpSuit)) { var trump = possibleCards.Where(c => c.Suit == context.TrumpCard.Suit) .OrderBy(this.stalkerHelper.GetCardPriority) .LastOrDefault(); return trump; } // Try to take the played enemy card. if (possibleCards.Any(c => c.Suit == enemyCard.Suit && c.GetValue() > enemyCard.GetValue())) { var higherCard = possibleCards.Where(c => c.Suit == enemyCard.Suit).OrderBy(c => c.GetValue()).LastOrDefault(); return higherCard; } // Else play the weakest card which is not trump. var card = possibleCards.Where(c => c.Suit != trumpSuit).OrderBy(c => c.GetValue()).FirstOrDefault() ?? possibleCards.OrderBy(c => c.GetValue()).FirstOrDefault(); return card; }