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