Zach Reese
Zach Reese

Reputation: 5

Returning a random value via char array

I'm trying to create an a blackjack game for my C# class and I've been trying to figure out how to obtain a random suit/card value from reciprocating char arrays. The goal is to return these values to a console application to "test" the return values and see if they're correct/adequate.

I have already declared the fields, properties, and set up a constructor. I just can't figure out how to get the values to return them so that they can be tested. We've just started using these things in my class as well.

[Additional Information added from O.P.'s "answer" below]

Right now, we're just trying to obtain a single card that is translated into a console application and the setup of the arrays is what the teacher told us to use.

public class Card
{
  //Declaration of fields
  char[] suit = new char[] { 'D', 'H', 'S', 'C' };    //Backing Variables
  char[] value = new char[]{'A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K'};
  static Random random = new Random();

  public Card(char s, char v) //Constructor
  {
    suit = s;
    value = v;
  }

  public char Suit //Properties
  {
    int suitType = random.Next(0, suit.Length);
    char s = suit[suitType];

    get { return value; }
  }

  public char Value
  {
    get { return value; }
  }

}

Upvotes: 0

Views: 153

Answers (2)

mikemchugh
mikemchugh

Reputation: 26

As we cannot change the structure of the program, I would do this:

public class Card
{
    //Declaration of fields
    private static char[] suits = new char[] { 'D', 'H', 'S', 'C' };    //Backing Variables
    private static char[] values = new char[]{'A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K'};
    private readonly char suit;
    private readonly char value;
    static Random random = new Random();

    public Card() //Constructor
    {
        int suitIndex = random.Next(0, suits.Length);
        suit = suits[suitIndex];

        int valueIndex = random.Next(0, values.Length);
        value = values[valueIndex];
    }

    public char Suit //Properties
    {
        get { return suit; }
    }

    public char Value
    {
        get { return value; }
    }
}

The set up of the fields is done in the constructor, without having to pass in any parameters. The properties can then be used in your console app like so:

class Program
{
    static void Main(string[] args)
    {
        Card aCard = new Card();
        Console.WriteLine("Suit: {0}", aCard.Suit);
        Console.WriteLine("Value: {0}", aCard.Value);

        Console.Read();
    }
}

A card will be created with a random suit and value. As others have stated the random class could not be used to reliably used to build a deck of cards.

To build a deck you could add another constructor to the Card class like:

public Card(char suit, char value)
{
    this.suit = suit;
    this.value = value;
}

Then add a simple Deck class like so (after this you could remove the constructor with no paramaeters and the suit and value arrays from the Card class) :

public class Deck
{
    private static char[] suits = new char[] { 'D', 'H', 'S', 'C' };   
    private static char[] values = new char[] { 'A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K' };
    private readonly List<Card> cards;

    public Deck()
    {
        cards = new List<Card>();
        foreach (char suit in suits)
        {
            foreach (char value in values)
            {
                Card card = new Card(suit, value);
                cards.Add(card);
            }
        }
    }

    public List<Card> Cards { get { return cards; } }
}

Then to view in the console app:

Deck deck = new Deck();

foreach (Card card in deck.Cards)
{
    Console.WriteLine("Suit: {0}", card.Suit);
    Console.WriteLine("Value: {0}", card.Value);
}

Upvotes: 1

Nicholas Carey
Nicholas Carey

Reputation: 74257

Myself, I'd do something like this:

public enum CardSuit
{
  Hearts   = 1 ,
  Spades   = 2 ,
  Diamonds = 3 ,
  Clubs    = 4 ,
}
public enum CardValue {
  Ace    =  1 ,
  Two    =  2 ,
  Three  =  3 ,
  Four   =  4 ,
  Five   =  5 ,
  Six    =  6 ,
  Seven  =  7 ,
  Eight  =  8 ,
  Nine   =  9 ,
  Ten    = 10 ,
  Jack   = 11 ,
  Queen  = 12 ,
  King   = 13 ,
}

public class Card : IEquatable<Card> , IComparable<Card>
{
  public readonly CardSuit  Suit  ;
  public readonly CardValue Value ;
  public Card( CardSuit suit , CardValue value )
  {
    if ( ! Enum.IsDefined(typeof(CardSuit),suit)   ) throw new ArgumentOutOfRangeException("suit") ;
    if ( ! Enum.IsDefined(typeof(CardValue),value) ) throw new ArgumentOutOfRangeException("value") ;

    this.Suit  = suit ;
    this.Value = value ;

    return;
  }

  public override int GetHashCode()
  {
    int value = ((int)this.Suit  << 16         )
              | ((int)this.Value &  0x0000FFFF )
              ;
    return value.GetHashCode() ;
  }

  public bool Equals( Card other )
  {
    return this.Suit == other.Suit && 0 == CompareTo(other) ;
  }

  public int CompareTo( Card other )
  {
    int cc = Math.Sign( (int)this.Value - (int) other.Value ) ;
    return cc;
  }
}

public class DeckOfCards
{
  private static Random rng = new Random() ;
  private readonly IList<Card> cards ;

  public DeckOfCards()
  {
    this.cards = new List<Card>(52) ;
    foreach( CardSuit suit in Enum.GetValues(typeof(CardSuit)) )
    {
      foreach( CardValue value in Enum.GetValues(typeof(CardValue)) )
      {
        cards.Add(new Card(suit,value));
      }
    }

  }

  public void Shuffle()
  {
    // Fisher-Yates (Durtensfeld) shuffle algorithm: http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
    for ( int i = 0 ; i < cards.Count ; ++i )
    {
       int  j   = rng.Next(i,cards.Count) ;
       Card t   = cards[j] ;
       cards[j] = cards[i] ;
       cards[i] = t        ;
    }
    return;
  }

}

Proper implementation of operators comparison operators (==, !=, <, <=, >, >=) is left up to you.

Upvotes: 0

Related Questions