views:

55

answers:

1

Hi

I have the following code which obviously has some duplication. I'm sure this could be removed using a delegate or Action but can't quite grasp it.

anyone got any ideas?

public void DealStartingCards()
        {
            for (int i = 0; i < 3; i++)
            {
                foreach (var player in Players)
                {
                    if (player.Hand.FaceDownCards.Count < 3)
                    {
                        if (Deck.Count > 0) 
                        player.Hand.FaceDownCards.Add(Deck.TakeTopCard());
                    }
                }
            }

            for (int i = 0; i < 3; i++)
            {
                foreach (var player in Players)
                {
                    if (player.Hand.FaceUpCards.Count < 3)
                    {
                        if (Deck.Count > 0) 
                        player.Hand.FaceUpCards.Add(Deck.TakeTopCard());
                    }
                }
            }

            for (int i = 0; i < 3; i++)
            {
                foreach (var player in Players)
                {
                    if (player.Hand.InHandCards.Count < 3)
                    {
                        if (Deck.Count > 0) 
                        player.Hand.InHandCards.Add(Deck.TakeTopCard());
                    }
                }
            }
        }

InHandCards, FaceUpCards and FaceDownCards are all of type List<Card>

+5  A: 

Taking Oskar's solution and changing it slightly:

private void DealCards(Func<Hand, List<Card>> handProjection)
{
    for (int i = 0; i < 3; i++)
    {
        foreach (var player in Players)
        {
            List<Card> cards = handProjection(player.Hand);
            if (cards.Count < 3)
            {
                if (Deck.Count > 0) 
                {
                    cards.Add(Deck.TakeTopCard());
                }
            }
        }
    }
}

public void DealStartingCards()
{
    DealCards(hand => hand.FaceDownCards);
    DealCards(hand => hand.FaceUpCards);
    DealCards(hand => hand.InHandCards);
}

(That's assuming the type of player.Hand is Hand - adjust accordingly otherwise, of course.)

Jon Skeet
I like this one. Did not know you could use that kind of methods :)
Oskar Kjellin
this is what I was after. Just need to get my head round understanding it now. I was convinced an Action was what was required coz there wouldn't be a return value. Just performing some action on each of the parts of the Hand
Christo Fur
@Christo: Well, for each of the parts of the hand you need to check the count *and* add to it. It's simpler to just return that part of the hand as a list. You *could* do it in other ways, but I think this is the simplest.
Jon Skeet
OK - so what does the handProjection parameter represent? I'm struggling to understand how this works
Christo Fur
I can see handProjection is a delegate that takes a hand and returns a list<Card>. Just struggling to see how the code flows. this is my limited grasp of delegates I guess.
Christo Fur
the lamda is instructing which List<Card> to return? is that correct? i.e saying which part of the hand we do the subsequent action on
Christo Fur
@Christo: Sorry for the delay - yes, the delegate says which cards to fetch from a given hand. Using different lambda expressions means you can add cards to different bits of the hand.
Jon Skeet