-1

Apologies I haven't done very well with the title of the question, hopefully it will be apparenent with some code

I've created a class that stores poker hand information as follows

public class BestHandSummary<T>
{
    public Func<T, bool> Test { get; set; }
    public Ranking Rank { get; set; } //Enum: Nothing, TwoPair, Straight, Flush, Poker :in ascending order
    public int BestCard { get; set; }
    public BestHand(Ranking r)
    {
        Rank = r;
    }
    ..//default ctor
}

I initialised the rules collection in order of most valuable hand so that when I take the First() of the matched rules the most powerful hand will be chosen as best hand.

rules = new List<BestHandSummary<PokerHand>>()
{
    new BestHandSummary<PokerHand> { Test = h => h.HandContainsFourOfAKind(out bestCard), 
                              Rank = Ranking.FourOfAKind,
                              BestCard = bestCard },
    new BestHandSummary<PokerHand> { Test = h => h.HandContainsFlush(), 
                              Rank = Ranking.Flush },
    new BestHandSummary<PokerHand> { Test = h => h.HandContainsStraight(out bestCard), 
                              Rank = Ranking.Straight,
                              BestCard = bestCard },
    new BestHandSummary<PokerHand> { Test = h => h.HandContainsTwoPair(out bestCard), 
                                      Rank = Ranking.Straight,
                                      BestCard = bestCard },

};
private BestHandSummary<PokerHand> GetAPlayersBestHand(PokerHand hand)
{
   bool hasAny = rules.Any(r => r.Test(hand));
   if (hasAny)
   {
       return rules.Where(r => r.Test(hand) == true).First();
   }
   return new BestHandSummary<PokerHand>(Ranking.Nothing);
}

What I can't seem to figure out is how can I tunnel the out param bestCard into the BestCard property of the BestHandSummary class? The code above doesn't work, BestCard = bestCard doestn't get assigned, which I can understand why, but I'm wondering if there is any small change I can make to fix it..

user48408
  • 3,234
  • 11
  • 39
  • 59

2 Answers2

1
int bestCard;

new BestHand<PokerHand> { Test = h => h.HandContainsFourOfAKind(out bestCard), 
                              Rank = Ranking.FourOfAKind,
                              BestCard = bestCard },

This code won't work, because HandContainsFourOfAKind was never called, and so nothing was assigned to bestCard.

I'm only interested in bestCard when the rule matched. It is used for when there is a draw between two players. E.G. H= 22KJJ -> best card is Jack, not king

So, you want BestCard to be assigned only when Test is invoked? This will do.

var hand = new BestHand<PokerHand> {Rank = Ranking.FourOfAKind};
hand.Test = h => 
     {
        int bestCard; //var local to the lambda's scope
        bool contains = h.HandContainsFourOfAKind(out bestCard);
        hand.BestCard = bestCard;
        return contains;
     };
dcastro
  • 66,540
  • 21
  • 145
  • 155
  • I'm only interested in bestCard when the rule matched. It is used for when there is a draw between two players. E.G. Player 1= 22KJJ -> best card is Jack, not king , Player 2 = 33AQQ -> bestCard Q. Since both have 2 pair I can use p2 bestcard of Q to determine winner – user48408 Feb 17 '14 at 10:52
0

I've written an equalizer myself a few years ago. I don't have a direct answer to your question, but one thing comes to my mind:

In your example, if you just look at the best card involved building the rank like the Jack in the two-pair hand, you won't figure out the best hand, if both have the same two-pair with different kicker. You might have to use a third method on that. Maybe you are better of to do this in one piece. I solved this with an if-monster, which returned an exact long-value, indicating every card in it's value for that hand.

Martin Tausch
  • 714
  • 5
  • 20
  • Valid point but I'm actually sticking to a brief, its a simple simulator which doesn't implement all the rules correctly. For instance i.e p1:44778 p2: 4477Q is a draw but p1:44778 p2:44QQ2 P2 Wins – user48408 Feb 17 '14 at 12:49