CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Mar 2009
    Posts
    22

    Array Randomization Problem

    Hi all,

    I'm relatively new to these forums, as this is only my second thread. My first experience asking for help went very well and I'm hoping that this experience will prove no different.

    I'm writing a program to simulate video poker. My class to create card objects is a huge success and i have no problems with that. I'm having trouble creating the Deck class, which creates an object that represents a deck of cards using card objects.

    Here's the code for the working Card class:
    Code:
    /**
    * Create a simple playing card with a suit and a face value
    * Suit Key: 0 --> Heart
    *		  1 --> Spade
    *		  2 --> Club
    *		  3 --> Diamond
    * Value Key: 2-10 --> Face value
    *		    11 --> Jack
    *		    12 --> Queen
    *		    13 --> King
    *		    1 --> Ace
    */
    public class Card implements Comparable
    {
    	/*
    	* Declare private data members (attibutes)
    	*/
    	private int Suit;
    	private int Value;
    
    	
    	/**
    	* Default constructor which sets the suit and value variables to 0
    	*/
    	public Card()
    	{
    		this.Suit = 0;
    		this.Value = 0;
    	}
    	
    	/**
    	* Explicit constructor which sets the suit and value variables to those given by user
    	* @param s the Suit
    	* (Precondition: s >= 0 and s <= 4)
    	* @param v the Value
    	*(Precondition: v >= 0 and v <= 14)
    	*/
    	public Card(int s, int v)
    	{
    		this.Suit = s;
    		this.Value = v;
    	}
    	
    	/**
    	* Get the suit of the card
    	* @return the Suit
    	*/
    	public int getSuit(){return this.Suit;}
    	
    	/**
    	* Get the value of the card
    	* @return the Value
    	*/
    	public int getValue() {return this.Value;}
    
    	/**
    	* Set the suit of the card
    	* @param s the Suit
    	* (Precondition: s >= 0 and s <= 4)
    	*/	
    	public void setSuit(int s) {this.Suit = s;}
    
    	/**
    	* Set the value of the card
    	* @param v the Value
    	*(Precondition: v >= 0 and v <= 14)
    	*/	
    	public void setValue(int v) {this.Value = v;}
    	
    	/**
    	* Compares two cards to find if they are same
    	*@param c the card to compar with the card that activated the method
    	*@return true if the cards are the same, false if not the same
    	*/
    	public Boolean equals(Card c)
    	{
    		return this.Suit == c.Suit && this.Value == c.Value;
    	}
    	
    	/**
    	* Compare the face values of the cards to sort
    	* @param o the object to compare
    	* @return 0 if the equal
    	* @return 1 if Card 1 > Card 2
    	* @return -1 if Card 1 < Card 2
    	*/
    	public int compareTo(Object o) 
    	{
    		//Implement cast in order to assure the correct object is being compared
    		if (this.Value == ((Card) o).Value) 
    			return 0;
    		else if ((this.Value) > ((Card) o).Value)
    			return 1;
    		else
    			return -1;
    	}
    	
    	/**
    	* Create a string representation of the card
    	*@return the String representation of the card
    	*/
    	public String toString()
    	{
    		//Declare integer value to temporarily store the suit and create a String to store the name which will be created
    		int suit = this.getSuit();
    		String SuitName;
    		
    		//Declare integer value to temporarily store the value and create a String to store the name which will be created
    		int value = this.getValue();
    		String ValueName;
    		
    		//Use switch statement to properly assign a Suit
    		switch(suit)
    		{
    			case 0: SuitName = "Hearts"; break;
    			case 1: SuitName = "Spades"; break;
    			case 2: SuitName = "Clubs"; break;
    			case 3: SuitName = "Diamonds"; break;
    			default: SuitName = "Error";
    		}
    		
    		//Use switch statement to properly assign a Value
    		switch(value)
    		{
    			case 1: ValueName = "A"; break;
    			case 2: ValueName = "2"; break;
    			case 3: ValueName = "3"; break;
    			case 4: ValueName = "4"; break;
    			case 5: ValueName = "5"; break;
    			case 6: ValueName = "6"; break;
    			case 7: ValueName = "7"; break;
    			case 8: ValueName = "8"; break;
    			case 9: ValueName = "9"; break;
    			case 10: ValueName = "10"; break;
    			case 11: ValueName = "J"; break;
    			case 12: ValueName = "Q"; break;
    			case 13: ValueName = "K"; break;
    			default: ValueName = "Error"; break;
    		}
    		
    		return ValueName + " of " + SuitName;
    	}
    
    }
    Here is the non-working Deck Class:

    Code:
    /**
    * Creates a deck of cards, using the card class
    */
    
    import java.util.*;
    public class Deck
    {
    	private Card[] DeckOfCards = new Card[52];
    	private static Random Suit, Value;
    	private static int FaceValue, SuitValue;
    	
    	/**
    	* Creates a deck of cards with 13 of each suit
    	*/
    	public Deck()
    	{
    		//DeckOfCards = new Card[52];
    		
    		//Initiate for loop to fill the array with blank cards, avoiding null reference when searching for duplicates
    		for (int i = 0; i < 52; i++)
    		{
    			DeckOfCards[i] = new Card();
    		}
    			
    		Card tempCard = new Card();
    			//do while blanks exist			
    			do
    			{	
    				//for each index, create a random card to insert
    				for(int i = 0; i < 52; i++)
    				{
    					tempCard = generateRandomCard();
    					DeckOfCards[i] = tempCard;
    				}
    			}while(!findDuplicate(tempCard, DeckOfCards));	
    	}
    	
    	/**
    	* Creates a card with random face value and suit
    	* @return the randomly generated card
    	*/
    	private Card generateRandomCard()
    	{
    		//Initiate the random objects for the Suit and Value
    		Suit = new Random();
    		Value = new Random();
    		
    		//Initialize local variable to hold the random number for suit
    		 SuitValue = Suit.nextInt(4);
    		
    		//Initilize local variable to 0 to control while loop for FaceValue to not equal 0
    		FaceValue = 0;
    		
    		//Initiate while loop to generate a non-zero face value
    		while(FaceValue == 0)
    		{
    			FaceValue = Value.nextInt(14);
    		}
    		
    		Card tempCard = new Card(SuitValue, FaceValue);
    		
    		if(!findDuplicate(tempCard, DeckOfCards))
    			return tempCard;
    		else
    			return new Card();
    	}
    	
    	/**
    	* Searches the Deck which activates the method for a duplicate card
    	* @param c the card to compare to the deck
    	* @return true if a duplicate is found, false if not
    	*/
    	private Boolean findDuplicate(Card c, Card[] d)
    	{
    		boolean FoundDuplicate = false;
    		for(int i = 0; i < 52; i++)
    		{
    			if (d[i].equals(c))
    				FoundDuplicate = true;
    		}
    		return FoundDuplicate;
    	}
    	
    	/**
    	* Create a string representation of the deck
    	* @return a string representation of the deck, numbered 1 to 52 using the card class toString method to convert the cards to string
    	*/
    	public String toString()
    	{
    		int Counter = 1;
    		String DeckString = "";
    		
    		Arrays.sort(DeckOfCards);
    		for(int i = 0; i < DeckOfCards.length; i++)
    		{
    			 DeckString += Counter + ". " + DeckOfCards[i] + "\n";
    			Counter++;
    		}
    		return DeckString;
    	}
    }
    I hope my code is clear and easy to understand. I take a lot of time to document and indent properly so that it is easy to read

    My problem lies in the loop to fill the DeckOfCards array in the Deck() constructor, more specifically in the loop controlling the random AND unique creation of the cards. The problem I'm running into is not syntax, as it does compile and run. The problem is that the cards are not unique (i.e. some are doubles/triples and/or some don't even exist).

    I understand it would be legal java to simply fill the array by hand with the cards I need, but that would pose me two problems: 1. The array would not be truly random, which is necessary to represent a shuffled deck of cards 2. It certainly is not an efficient use of time and programming.

    So what I'm hoping is that someone can give me some direction on what I'm doing wrong to create a deck of 52 unique cards.

    Thanks in advance for any help and consideration.
    Last edited by platticus; September 11th, 2009 at 11:22 AM.

  2. #2
    Join Date
    May 2006
    Location
    UK
    Posts
    4,473

    Re: Array Randomization Problem

    I take a lot of time to document and indent properly so that it is easy to read
    Congratulations, I certainly wish more people posted questions and code like this.

    The easiest solution is to put one of each card into a List (eg ArrayList) and call the java.util.Collections class's shuffle method. There's even one version where you can supply your own Random object.

    If you are not allowed to use the Collection classes then a simple way is to fill the array with one of each card and then iterate over the array swopping the card at each array element with a card at a random element.

  3. #3
    Join Date
    May 2009
    Posts
    2,413

    Re: Array Randomization Problem

    Quote Originally Posted by platticus View Post
    Thanks in advance for any help and consideration.
    You should first generate a deck of unique cards and then shuffle it randomly.

    If you fill the deck with cards generated at random you're bound to get duplicates. That's in the nature of random.

  4. #4
    Join Date
    Mar 2009
    Posts
    22

    Re: Array Randomization Problem

    Keang, that is a fantastic suggestion and I thank you very much for your input.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured