HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpModerate

Playing card game method

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
playinggamecardmethod

Problem

Is there a better, more elegant solution to the following method?

Boolean[] spades = new Boolean[10]; // 40 cards deck

foreach (Card card in m_Cards.Where(card => (card.Suit == Suit.Spades)))
    spades[(Int32)card.Rank] = true; // Rank goes from Ace (0) to King (10)

if (spades[0] && spades[1] && spades[2])
{
    points += 3;

    for (Int32 i = 3; i < spades.Length; ++i)
    {
        if (spades[i])
            ++points;
        else
            break;
    }
}


In fact, the function awards 3 points to the player only if he owns Ace, Two and Three... and, always if this condition is satisfied, it awards him a point for every card that extends the sequence. Examples:

Ace + Three + Five = 0 Points
Ace + Two + Three = 3 Points
Ace + Two + Three + Five = 3 Points
Ace + Two + Three + Four + Five + Six = 6 Points


Every kind of better solution is accepted, such as Linq and enumerable extensions.

Solution

We can use the fact that in the ordered sequence of cards the cards that match your requirement will be located at the beginning of sequence, and their rank will match their position:

var count = _cards.Where(card => card.Suit == Suit.Spades)
    .Select(card => (int)card.Rank) //we only need the rank
    .Distinct() //ignoring multiple cards with the same rank
    .OrderBy(rank => rank) //sorting by rank
    .TakeWhile((rank, index) => rank == index) //taking all initial cards with index matching their rank
    .Count();

return count < 3 ? 0 : count;


Note that your code will perform better than this one (you'll notice that only if you run it thousands times a second) since you're using the fact that there are only 10 sequential values present in Rank.

Code Snippets

var count = _cards.Where(card => card.Suit == Suit.Spades)
    .Select(card => (int)card.Rank) //we only need the rank
    .Distinct() //ignoring multiple cards with the same rank
    .OrderBy(rank => rank) //sorting by rank
    .TakeWhile((rank, index) => rank == index) //taking all initial cards with index matching their rank
    .Count();

return count < 3 ? 0 : count;

Context

StackExchange Code Review Q#23940, answer score: 10

Revisions (0)

No revisions yet.