示例#1
0
 public Hint(Player p, int? suit, int? num)
 {
     this.For = p;
     // Check hint content;
     if (suit.HasValue && num.HasValue) throw new ArgumentException("both dimensions");
     this.Suit = suit;
     this.Number = num;
     // Find matching card positions.
     this.Positions = new List<int>();
     var cards = p.Hand();
     for (int i = 0; i < cards.Count; i++)
     {
         bool match = num.HasValue ? num.Value == cards[i].Number : suit.Value == cards[i].Suit;
         if (match) this.Positions.Add(i);
     }
     if (Positions.Count <= 0) throw new ArgumentException("no matching cards");
 }
示例#2
0
 public void AddOtherPlayersHintsToActions(List<Move> actions, Player initialPlayer)
 {
     foreach (var player in game.Players.Where(player => player != this && player != initialPlayer && player.WillPlayAgain))
      {
     player.AddHintsToPossibleActions(actions);
      }
 }
示例#3
0
        public IEnumerable<Move> GetPossibleActions(Player initialPlayer)
        {
            var actions = new List<Move>();

             AddGainToPossibleActions(actions);

             if (game.CanBurn())
            AddBurnToPossibleActions(actions);

             if (game.CanHint())
            AddOtherPlayersHintsToActions(actions, initialPlayer);

             actions.Add(Yolo());

             return actions;
        }
示例#4
0
 public NumberHint(Player targetPlayer, int number)
 {
     TargetPlayer = targetPlayer;
      Number = number;
 }
示例#5
0
 public SuitHint(Player targetPlayer, Card.Suit suit)
 {
     TargetPlayer = targetPlayer;
      Suit = suit;
 }
示例#6
0
 public Simulation(Game game)
 {
     this.game = game;//.Copy();
     initialScore = game.GetScore();
     initialPlayer = game.GetCurrentPlayer();
 }
示例#7
0
 public Move Play(Player me)
 {
     return Move.DoPlay(me.Cards[0]);
 }
示例#8
0
        public Move Play(Player me)
        {
            // Narrow down card possibilities by process of elimination.
            me.RestrictCards();

            // Re-evaluate all cards based on new information in hand, board, and opponents' hands.
            foreach (HeldCard c in me.Cards)
            {
                c.Label = c.State(me);
            }

            // TODO: override states based on last hint (requires history)
            // TODO: immediately PLAY on recent hints according to position?
            // Keep any queued cards that have a known number or suit (likely received a hint).
            foreach (HeldCard c in me.Cards.Where(c =>
                c.Label == Intent.QUEUE && (c.Number().HasValue || c.Suit().HasValue)))
            {
                c.Label = Intent.KEEP;
            }

            Player next = me.Next();

            // Send critical hints, if possible.
            if (me.Game.Hints > 0)
            {
                // For playable cards, or cards wrongly marked playable, hint number, then suit (top of queue first).
                foreach (HeldCard c in next.Cards)
                {
                    bool canPlay = me.Game.Deck.AllowPlay(c.Actual);
                    if ((canPlay && c.Label != Intent.PLAY) ||
                        (!canPlay && c.Label == Intent.PLAY))
                    {
                        if (!c.Number().HasValue) return Move.DoHint(new Hint(next, null, c.Actual.Number));
                        if (!c.Suit().HasValue) return Move.DoHint(new Hint(next, c.Actual.Suit, null));
                    }
                }
                // For pole cards that shouldn't be discarded, hint suit. This should move them into state KEEP.
                // Only hint when there are no PLAY or DISCARD cards, since these are higher priority.
                // TODO: enable this once we have better hinting. At the moment it does not help.
                /*
                if (next.Cards.FirstOrDefault(c => c.Label == Intent.PLAY || c.Label == Intent.DISCARD) == null)
                {
                    var pole = next.Cards.FirstOrDefault(c => c.Label == Intent.QUEUE);
                    if (pole != null && pole.Actual.LastChance(next, me))
                    {
                        //if (!pole.Number().HasValue) return Move.DoHint(new Hint(next, null, pole.Actual.Number));
                        if (!pole.Suit().HasValue) return Move.DoHint(new Hint(next, pole.Actual.Suit, null));
                    }
                }
                */
            }

            // Play cards that are ready (lowest number first).
            HeldCard play = me.Cards.Where(c => c.Label == Intent.PLAY)
                .OrderBy(c => c.Number().GetValueOrDefault(int.MaxValue))
                .FirstOrDefault();
            if (play != null) return Move.DoPlay(play);

            // Discard when we have cards ready to go (any order).
            HeldCard disc = me.Cards.FirstOrDefault(c => c.Label == Intent.DISCARD);
            if (disc != null) return Move.DoDiscard(disc);

            // TODO: send non-critical hints, like suit, especially when many hints are available
            // TODO: special hints for 5s?

            // Otherwise discard the first card from queue.
            HeldCard discq = me.Cards.FirstOrDefault(c => c.Label == Intent.QUEUE);
            if (discq != null) return Move.DoDiscard(discq);

            // TODO: Non-critical hint?

            // If we really have to, discard any card from the keep stack.
            // TODO: discard the _safest_ card (highest, or least played).
            return Move.DoPlay(me.Cards[0]);
        }