Вопрос

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..

Это было полезно?

Решение

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;
     };

Другие советы

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top