# C# question (java related)



## spy2520 (Feb 26, 2010)

I'm totally green on C#. Just got bored and decided to port one of my java apps to C# to see how it would go. Turns out its 90% cut and paste lol. Anyway...

In java i have a for loop that basically reads "for each suit in cards.suits, <execute code>".

This is written in java as "for (Card.suits S: Card.suits.values()){execute code}".

How would i go about doing this in C#?


----------



## spy2520 (Feb 26, 2010)

It something like this i think: "foreach (suits S in Card.suits)"

but not quite that. Cards.suits is an enumerated type also.


----------



## FordGT90Concept (Feb 26, 2010)

I tend to avoid foreach statements in C# because I end up having to go back and change it to a for loop anyway (collection was altered error).  Basically...

```
IF AN ARRAY (fixed length):
for (int i = 0; i < Card.suits.Length; i++)
{
  Card.suits[i];
}

IF A LIST (variable length):
for (int i = 0; i < Card.suits.Count; i++)
{
  Card.suits[i];
}

FOREACH STATEMENT:
foreach (Suit suit in Card.suits)
{
  suit
}
```

What is Card.suits declared as?  Also, what does Card.suits.values() return?


----------



## spy2520 (Feb 26, 2010)

Card.suits is an enumerated type, it looks like "protected enum suits {Hearts, Diamonds, Clubs, Spades}" in java, and similar in c# except 'protected' didnt work how i expected it to.

And it appears in C# that Card.suits.values() doesnt exist.


----------



## Kreij (Feb 26, 2010)

What methods does your card class expose?


----------



## FordGT90Concept (Feb 26, 2010)

An enum is just a constant number (with names attached).  The closest I think you can get to .values() would be Card.suits.GetNames() (returns strings) or Card.suits.GetValues() (returns numerical type).

I think this should work for you:

```
foreach (Card.suits S in Card.suits.GetValues())
{
}
```


Enumerator types should be declared either public or internal (only this assembly can access it).  I perfer public and I always place them in "Enumerators.cs" without an encompassing class.  For example:

```
namespace MyAppNamespace
{
  public enum Suits : byte { Hearts, Diamonds, Clubs, Spakes };
}
```

Just type "Suits" and you got it.


----------



## spy2520 (Feb 26, 2010)

Kreij said:


> What methods does your card class expose?



The Card class literally just has getFace(), printFace(), and ToString(). All 3 are public currently. This for loop is actually in CardDeck which will contain 52 instances of the Card class in an array.


----------



## spy2520 (Feb 26, 2010)

FordGT90Concept said:


> For example:
> 
> ```
> namespace MyAppNamespace
> ...



Why is "byte" there? Is this necessary or is Suits{ Hearts, Diamonds, Clubs, Spakes } all that is needed?


----------



## FordGT90Concept (Feb 26, 2010)

By the way, a great thing about C# is it has properties:

```
private Suits _Face;
public Suits Face
{
  get { return _Face; }
}
```
Because it only has a "get" member, Card.Face would be read-only.  "get" in the name is therefore redundant. 

Just for reference, here is an example with get and set:

```
private Suits _Face;
public Suits Face
{
  get { return _Face; }
  set { _Face = value; }
}
```


----------



## spy2520 (Feb 26, 2010)

i see.


----------



## FordGT90Concept (Feb 26, 2010)

spy2520 said:


> Why is "byte" there? Is this necessary or is Suits{ Hearts, Diamonds, Clubs, Spakes } all that is needed?


I think the default for enumerators is int (32-bit signed integer).  By explicitly declaring it byte (8-bit unsigned integer), it takes up 1/4th the memory.  It isn't necessary but good practice.

Put verbally in that context, "Suits inherits byte" just as System.Byte inherits System.Object (everything in C# ultimately comes back to Object).


----------



## spy2520 (Feb 26, 2010)

FordGT90Concept said:


> I think the default for enumerators is int (32-bit signed integer).  By explicitly declaring it byte (8-bit unsigned integer), it takes up 1/4th the memory.  It isn't necessary but good practice.
> 
> Put verbally in that context, "Suits inherits byte" just as System.Byte inherits System.Object (everything in C# ultimately comes back to Object).



oh that makes alot of sense. Thanks


----------



## spy2520 (Feb 26, 2010)

i'm still having an issue with the for loop. I have attached an image. Even intellisense only wants to give me the elements in Suits. I cant get anything like getValues or anything. I must be missing something simple. I have Enumerators.cs and have two enumerated types (Suits and Faces), i wrote them how you did in your example.


----------



## FordGT90Concept (Feb 26, 2010)

Whoops, brain fart.  Enum.GetValues(Suits) should work.


----------



## spy2520 (Feb 26, 2010)

ok cool i'll try that.


----------



## spy2520 (Feb 26, 2010)

ok i got foreach (Suits S in Enum.GetValues(typeof(Suits))) with no squiggly lines. THANK YOU. On to the next roadblock...


----------



## FordGT90Concept (Feb 26, 2010)

Good thing I linked you.  I had another brain fart on typeof. XD

I need to get to bed. :shadedshu


----------



## spy2520 (Feb 26, 2010)

yup, thanks.


----------



## spy2520 (Feb 26, 2010)

alright i just gotta create a GUI now, should be fun since i never bothered in java, just printed to the console It seems C# needs just about everything public as opposed to java.


----------



## spy2520 (Feb 27, 2010)

*ok heres the long post*


```
using System;
using System.Collections;

namespace blackJackPort
{
    public class Game
    {

        public class Hand
        {
            public int handValue = 0;
            ArrayList handCards = new ArrayList();


           public void addCard(Card card)
            {
                if (card.getFace().Equals("Ace") && handValue > 10) card.value = 1;
                handCards.Add(card);
                handValue += card.value;
                Bust();
            }
            
            bool Bust()
            {
                if (handValue > 21) return true;
                else return false;
            }
            
           public string printCards()
            {
			string CardList = "";
			foreach (Card x in handCards)
                {
			    CardList += x.toString() + "\n";	
			    }return CardList;
		    }


        }
        
        public CardDeck Deck;
        public int card;
        public Random rand = new Random();
        public Hand DealerHand, PlayerHand;


       public void initialDeal(){
			initializeDeck();
			DealerHand = new Hand(); PlayerHand = new Hand();
			DealPlayer(); DealDealer();
			DealPlayer(); DealDealer();
			//System.out.println(printHand());
			}
       public void initializeDeck()
        {
            Deck.fillDeck();
           
        }

        public void DealPlayer()
        {
            card = rand.Next(52);
            Card newCard = new Card(Deck.cards[card].value, Deck.cards[card].suit, Deck.cards[card].face);
            if (newCard.value == 0) DealPlayer();
            else
            {
                PlayerHand.addCard(newCard);
                Deck.cards[card].value = 0;
            }

        }
        public void DealDealer()
        {
            card = rand.Next(52);
            Card newCard = new Card(Deck.cards[card].value, Deck.cards[card].suit, Deck.cards[card].face);
            if (newCard.value == 0) DealDealer();
            else
            {
                DealerHand.addCard(newCard);
                Deck.cards[card].value = 0;
            }

        }
        //void Bust(int Hand){
        //	if (Hand > 21) System.out.println("BUST");

        //}
       public String printHand()
        {
            return ("\nDealer: " + DealerHand.handValue + " " + "Player: " + PlayerHand.handValue + "\n");
        }
       public String printAllHands()
        {
            return ("Player Hand: \n" + PlayerHand.printCards() + "\nDealer Cards: \n" + DealerHand.printCards());
        }
       public Boolean playerWins()
        {
            if (DealerHand.handValue > 21 || (PlayerHand.handValue > DealerHand.handValue && PlayerHand.handValue <= 21)) return true;
            else return false;
        }
    }


}
```


```
using System;

namespace blackJackPort
{
   public class Card
    {
        //public enum suits { Hearts, Diamonds, Clubs, Spades }
        //public enum faces { Face2, Face3, Face4, Face5, Face6, Face7, Face8, Face9, Face10, King, Queen, Jack, Ace }
        public Faces face;
        public Suits suit;

        public int value
        {
            get { return value; }
            set { value = 0; }

        }
        public Card(int value, Suits suit, Faces face)
        {
            this.suit = suit; this.value = value;

            this.face = face;
            if (face == Faces.Ace)
            {
                this.value = 11;
            }
        }

        public string printFace()
        {
            return this.face.ToString();
        }
        public string toString()
        {
            string words;
            if (face.ToString().Length > 3 && face.ToString().Contains("Face"))
                words = face.ToString().Substring(4) + " of " + suit + ": " + value;
            else words = face + " of " + suit + ": " + value;
            return words;
        }
        public Faces getFace()
        {
            return face;
        }

    }
   public class CardDeck
    {
        public Card[] cards;
        int count = 0;
        int MaxCards = 52;

        CardDeck()
        {
            cards = new Card[MaxCards];
        }

        void addCard(int value, Suits suit, Faces face)
        {
            cards[count++] = new Card(value, suit, face);
        }


        public void fillDeck(){
		
	foreach (Suits S in Enum.GetValues(typeof(Suits))){
		int counter = 2;
		foreach (Faces F in Enum.GetValues(typeof(Suits))){
			if (counter < 10){
				addCard(counter,S,F);
				counter++;
			}else addCard(10, S,F);
		}	
		}			
							}
        public String toString()
        {
            String CardList = "";
            for (int x = 0; x < MaxCards; x++)
            {
                CardList += cards[x].toString() + "\n";
            } return CardList;
        }
        public void removeCard(int index)
        {
            cards[index].value = 0;
        }
    }
}
```


```
namespace blackJackPort
{
    public enum Suits : byte { Hearts, Diamonds, Clubs, Spades };
    public enum Faces : byte { Face2, Face3, Face4, Face5, Face6, Face7, Face8, Face9, Face10, King, Queen, Jack, Ace };
}
```


Theres all my code, now for the question...


----------



## spy2520 (Feb 27, 2010)

```
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace blackJackPort
{
    public partial class Form1 : Form
    {

        public Game game
        {
            get { return game; }
            set { game = new Game(); }
        }
        public Form1()
        {
            InitializeComponent();
            
        }

        private void Form1_Load(object sender, EventArgs e)
        {
           
        }

        private void ExitButton_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void newButton_Click(object sender, EventArgs e)
        {
            hitButton.Enabled = true;
            stayButton.Enabled = true;
            [B]game.initializeDeck();[/B]
            playerHandLabel.Text = "Player Hand";
            dealerHandLabel.Text = "Dealer Hand";
        }
    }
}
```

The bold part is where i am having problems. When its time to initialize the deck the program freezes and VS locks up, i dont get an error message so its kinda hard to diagnose. Does anything seem wrong? I know its alot to ask looking through all the code but i cannot see where i went wrong.

Even if i comment out all the code in CardDeck.InitializeDeck() it still locks up, so i'm not too sure its even the code causing the problem.


----------



## FordGT90Concept (Feb 27, 2010)

VS caught it for me (make sure it is in debug mode):
StackOverflowException @ line 17 in Form1.cs

```
public Game game
        {
            [b]get { return game; }[/b]
            set { game = new Game(); }
        }
```

That's a circular reference and the variable "game" does not exist although the member name "game" does; this should fix it:

```
private Game game = new Game();
        public Game Game
        {
            get { return game; }
        }
```

Next, fillDeck() throws a NullReferenceException because Deck is null.  I'm not sure how you want to fix that but it generally involves "new Deck()" before it reaches fillDeck().


----------



## spy2520 (Feb 27, 2010)

oh ok thanks, i'll get it straight.


----------



## spy2520 (Feb 27, 2010)

i think my problem is that VS is crashing before i can see whats going on in debug mode, it doesnt care about my breakpoints. Must be an issue with the beta. We'll see.


----------



## FordGT90Concept (Feb 27, 2010)

Oh, you are using Visual Studio 2010 beta?  That could be it.  I am running Visual Studio 2008 Team Suite.


----------



## spy2520 (Feb 27, 2010)

i'm installing the rc right now. Gotta be at work in 3 hours and can't go back to sleep.


----------



## spy2520 (Feb 27, 2010)

Guess what? I can now successfully debug my application without VS quitting. I guess the RC really was worth switching to.


----------



## FordGT90Concept (Feb 27, 2010)

Heh, post if you have more problems you can't sort.


----------



## spy2520 (Feb 27, 2010)

I sure will. Won't be til I get out of work. Once I get it working I may try doing a silverlight app. The best way to learn sometimes is just to face-plant right into it. Unfortunately the RC doesn't support silverlight 4 so my dreams may be shattered.


----------



## FordGT90Concept (Feb 27, 2010)

Silverlight, IMO, isn't ready for primetime.  Even simple tasks like finding resources on the server (like data from a database) take lots of work.  It has potential but it needs to be streamlined.


----------



## spy2520 (Feb 28, 2010)

i'm golden now. Everything is coming together nicely. Had one big error holding me up. For some reason i was building the deck of cards as "for each suit in Suits, *for each face in Suits*, add card(value, suit, face) which was causing some of the cards being dealt to have null values since there are only 4 suits. It pretty much gave me 4 cards for each suit, 16 cards in a 52 card array.


----------



## FordGT90Concept (Feb 28, 2010)

Suits only contains Spade, Heart, Diamond, and Club.  Face should have Ace, 1-10, Jack, Queen, King.  for each face in suits, therefore, would go through Spade, Heart, Diamond, and Club rather than the face values.  Get what I'm saying?

Change it to...

```
foreach (Face face in Enum.GetValues(typeof(Faces)))
{
}
```


You might want to consider changing Faces to:
public enum Faces : byte { Ace, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King };

When you have to display the type of card, do:
txtMyTextBox.Text = face.ToString() + " of " + suit.ToString();

That would return, for example, "Five of Clubs" or "Ace of Spades"


----------



## spy2520 (Feb 28, 2010)

that's pretty much what I have. I am going to change the enums. My Card.toString() method gets a substring of the face name currently. I guess I could make it less complicated, however.


----------



## FordGT90Concept (Feb 28, 2010)

Remember, you can get the numerical value of an enumerator by casting it.  For example:

byte value = (byte)Faces.Two; // Value would equal 2.

So if you could do:
public enum Faces : byte { Ace = 1, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King };

...and pull the values out using the code above.


----------

