CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 17
  1. #1
    Join Date
    Mar 2007
    Posts
    109

    Random() - Shuffling

    I am making a card game. I need to shuffle the cards. I made a shuffler but it looks like its not always random. It seems like 0 is always close to the bottom. I remember in VB you had to call Randomize() before it was true random. I can't find that function anymore.

    Code:
    	public class CardShuffler
    	{
    		private const int CARDS_IN_DECK = 52;
    
    		public List<int> Shuffle()
    		{
    			List<int> totalCards = new List<int>();
    			List<int> shuffledCards = new List<int>();
    
    			// Populate totalCards with numbers 0-51 (total of 52 numbers)
    			for (int i = 0; i != CARDS_IN_DECK; i++)
    			{
    				totalCards.Add(i);
    			}
    
    			Random rnd = new Random();
    			while (totalCards.Count != 0)
    			{
    				// Get a random number, <= the number of items left in totalCards.
    				int currentCard = rnd.Next(totalCards.Count);
    				
    				// Use the random number to pull the item (card) from totalCards,
    				// and insert it into shuffledCards at the next index.
    				shuffledCards.Add(totalCards[currentCard]);
    
    				// Remove the item (card) from totalCards, so it is not used again.
    				totalCards.RemoveAt(currentCard);
    			}
    
    			return shuffledCards;
    		}
    	}
    Code:
    CardShuffler cs = new CardShuffler();
    List<int> ar = cs.Shuffle();
    for (int i = 0; i < ar.Count; i++)
    {
    	listBox1.Items.Add(ar[i]);
    }
    Thanks.

  2. #2
    Join Date
    Sep 2006
    Location
    Eastern, NC, USA
    Posts
    907

    Re: Random() - Shuffling

    One of two ways that I know of here. First you can put in your own seed using a constructor overload "new Random(seed)" where seed is an int32. If you search this forum on randomize and seed, you'll find useful techniques for generating this seed. The other way is to allow your random object to "autoseed". You will need to allow the timer to advance by calling Thread.Sleep(1) before your Random object is constructed. For further info on this, check out the MSDN info "Random Class, about Random Class".
    Code:
        {
            // Wait to allow the timer to advance.
            Thread.Sleep( 1 );
    
            Random rnd  = new Random( );
    
            While (totalCards.Count != 0)
            .....
    Last edited by petes1234; March 18th, 2007 at 05:48 PM.

  3. #3
    Join Date
    Mar 2004
    Location
    Ukraine
    Posts
    170

    Re: Random() - Shuffling

    try this
    Code:
    DateTime dt=DateTime.Now;
    Random r1=new Random(dt.Ticks);
    it will randomize using current ticks from time;
    God could improve essentially a
    human nature, but he
    was too anxious with compatibility
    with the monkey.
    (Eugeny Goldberg)

  4. #4
    Join Date
    Mar 2006
    Location
    Craiova, Romania
    Posts
    439

    Re: Random() - Shuffling

    Quote Originally Posted by Skoons
    try this
    Code:
    DateTime dt=DateTime.Now;
    Random r1=new Random(dt.Ticks);
    it will randomize using current ticks from time;
    Random will automatically seed based on time so there is no need to specify that.
    Bogdan

    If someone helped you then please Rate his post and mark the thread as Resolved
    Please improve your messages appearance by using tags [ code] Place your code here [ /code]

  5. #5
    Join Date
    Mar 2004
    Location
    Ukraine
    Posts
    170

    Re: Random() - Shuffling

    Quote Originally Posted by creatorul
    Random will automatically seed based on time so there is no need to specify that.
    yes it is but i have negin mypost before yourse and so I have not thing about such nice move like thread.Sleep(); So this is one of the variants, but user may use here not only ticks but seconds and other digit options
    God could improve essentially a
    human nature, but he
    was too anxious with compatibility
    with the monkey.
    (Eugeny Goldberg)

  6. #6
    Join Date
    Mar 2007
    Posts
    109

    Re: Random() - Shuffling

    What??

  7. #7
    Join Date
    Jan 2003
    Location
    Sweden
    Posts
    115

    Re: Random() - Shuffling

    Quote Originally Posted by WesTurrant
    I am making a card game. I need to shuffle the cards. I made a shuffler but it looks like its not always random. It seems like 0 is always close to the bottom. I remember in VB you had to call Randomize() before it was true random. I can't find that function anymore.
    I have been looking at your code and I think that it looks fine. I think that random was only playing you a joke, when I was running your code I found that 0 was equally often in top, middle or bottom
    In C# there is no need for calling something like "Randomize timer", since when you initialize a 'random' object without seed, it takes the seed from time just as creatorul pointed out.
    Quote Originally Posted by creatorul
    Random will automatically seed based on time so there is no need to specify that.
    The only problem one could have with random is if one creates many sessions of random within a short time interval, they will then all be initialized using the same tick count, and thus yield the same random number:
    Code:
    for (int i = 0; i < 5; i++)
    {
    //Does not work, every myrand object will use the same random seed.
    //myrand should preferrably be created outside of loop
       Random myrand = new Random();
       int number = myrand.Next();
       textBox1.Text += number.ToString() + "\r\n";
    }
    Quote Originally Posted by petes1234
    Code:
    // Wait to allow the timer to advance.
    Thread.Sleep( 1 );
    Random rnd  = new Random( );
    Petes1234 has a workaround for this specific situation, calling a thread.sleep before initializing the random object. I have done some testing on this and it seems like the method of Petes1234 does not work since 1 is too short time interval for the timer to advance (at least on my machine). I found out that one has to use at least Thread.Sleep( 10 ); in order for the timer to update properly:
    Code:
    for (int i = 0; i < 5; i++)
    {
       //Waiting solves the problem of identical seeds being used.
       Thread.Sleep(10);
       Random myrand = new Random();
       int number = myrand.Next();
       textBox1.Text += number.ToString() + "\r\n";
    }

  8. #8
    Join Date
    Jan 2003
    Location
    Sweden
    Posts
    115

    DateTime.Now update rate???

    Quote Originally Posted by Cyanide
    I found out that one has to use at least Thread.Sleep(10); in order for the timer to update properly
    All gurus out there, do you have an explanation for the above? I have been tracking the DateTime.Now function and found out that it updates only every 10 msec. Is this normal???
    Code:
    for (int i = 0; i < 20; i++)
    {
       // Wait to allow the timer to advance.
       System.Threading.Thread.Sleep(2);
       textBox1.Text += DateTime.Now.Millisecond + "\r\n";
    }
    gives the following output
    Code:
    879
    889
    889
    889
    889
    889
    899
    899
    899
    899
    899
    909
    909
    909
    909
    919
    919
    919
    929
    929

  9. #9
    Join Date
    Sep 2006
    Location
    Eastern, NC, USA
    Posts
    907

    Re: Random() - Shuffling

    Quote Originally Posted by Cyanide
    Petes1234 has a workaround for this specific situation, calling a thread.sleep before initializing the random object. I have done some testing on this and it seems like the method of Petes1234 does not work since 1 is too short time interval for the timer to advance (at least on my machine). [/CODE]
    I wish I could claim this workaround as my own, but it's not. It is from the MSDN.

  10. #10
    Join Date
    Jan 2005
    Posts
    56

    Simple Soluition to me

    I wonder why you don't just create a simple Static Class, setting the seed the first time you invoke the utility, and as they say "Set it and Forget it".

    If any of you Guru see a problem with that idea, I'd love to know what I'm missing.


    Code:
    public class Utility 
    {
    	static Random rand;
    	public static Random Rand 
    	{
    		get 
    		{
    			if(rand == null) 
    				rand = new Random();
    			return rand;
    		}
    	}
    }
    Am I missing something?

  11. #11
    Join Date
    May 2006
    Location
    Norway
    Posts
    1,709

    Re: DateTime.Now update rate???

    Hi Cyanide!

    If it is normal depends on your operating system.

    Have a look at the documentation of the DateTime.Now property; DateTime.Now Property

    This states that the resolution is 10ms on Windows NT 3.5 and later, and 55 ms on Win98.

    However the DateTime.Ticks property has an accuracy of 100 nano seconds; DateTime.Ticks Property

    Hope this helps!

    Regards,

    Laitinen

  12. #12
    Join Date
    Mar 2004
    Location
    33°11'18.10"N 96°45'20.28"W
    Posts
    1,808

    Re: DateTime.Now update rate???

    here's what you need to do.

    I wrote a card game a while ago, and the best way I found to get a random shuffle, was to give each card object a GUID, and sort the deck on that guid. each time you shuffled the deck, you re-assign each card w/ a new guid before calling sort.

    It had way better results than using random.

    here's a sample of what I used (just a quick and dirty sample):

    Code:
    class Program {
        [STAThread]
        static void Main(string[] args) {
            Deck deck = new Deck();
            deck.Shuffle();
            deck.Shuffle();
        }
    }
    
    public enum Suit { None, Club, Spade, Heart, Diamond }
    
    public enum FaceValue { None, Ace, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Eleven, Jack, Queen, King }
    
    public class Card : IComparable<Card> {
        Guid cardId = Guid.Empty;
        Suit suit = Suit.None;
        FaceValue value = FaceValue.None;
    
        public Guid CardId {
            get { return cardId; }
        }
    
        public Suit Suit {
            get { return suit; }
        }
    
        public FaceValue Value {
            get { return this.value; }
        }
    
        public void NewId() { cardId = Guid.NewGuid(); }
    
        public int CompareTo(Card other) {
            return cardId.CompareTo(other.cardId);
        }
    
        public override string ToString() {
            return string.Format("{0} of {1}", value, suit);
        }
    
        public Card(Suit suit, FaceValue value) {
            this.suit = suit;
            this.value = value;
            NewId();
        }
    }
    
    public class Deck {
        List<Card> cards = new List<Card>();
    
        public List<Card> Cards {
            get { return cards; }
        }
    
        public void Shuffle() {
            foreach(Card card in cards) { card.NewId(); }
            cards.Sort();
        }
    
        public Deck() {
            for(int suit = 1; suit <= 4; suit++) {
                for(int value = 1; value <= 14; value++) {
                    cards.Add(new Card((Suit)suit, (FaceValue)value));
                }
            }
            Shuffle();
        }
    }
    Last edited by MadHatter; March 20th, 2007 at 12:49 PM.

  13. #13
    Join Date
    Mar 2007
    Posts
    109

    Re: DateTime.Now update rate???

    Thanks MadHatter. That really helps me think I'm on the right track I thought I was doing it wrong. But my program looks exactally like yours' In fact I had to scroll up to make sure I didn't post my actual code. I made a special card class to represent each card, and enums for suit and face value. Almost all of your code looks exactally like mine.

    Now I know I've been on the right track, and I can modify my shuffler.

    What game did you make? Did you have any tricks to validating the players hand? That's one part I'm still working on. There are so many possible combinations that could be correct for them to win, its hard for me to figure out the best way to do it.

  14. #14
    Join Date
    Mar 2004
    Location
    33°11'18.10"N 96°45'20.28"W
    Posts
    1,808

    Re: DateTime.Now update rate???

    I built some foundation classes that were basically the card / deck domain, and then had a rules framework that governed the rules of the specific game implementation. and another that did the rendering (it was just a windows forms app). I'm not much of a card player. I had black jack, and was working on a vanilla version of hearts when my hdd's crashed and I lost it all.

    the main thing that gave me a fit (that I remember) was the shuffling of the deck and went the same route you did for a while before thinking of the GUID solution. I forget exactly how I had designed the rules part of the framework (I may think of it later) but it was fairly easy to specify game logic. If I remember it I'll let you know. It was one of those things I came up with one bored night that I never really touched again, then lost.

    I think my rules framework basically revolved around game setup, game play, and who wins. the game setup dealt with number of players, which affected the number of decks used (and some other things), the game play dealt with whether a particular card could be dealt to or combined to a specific hand or given to a particular player, whether sets of cards were at all permissible for play, and the winning rules took a list of hands (I had another object that was Hand that was a wrapper around a list of cards) and returned those hands in winning order. each rule set was actually a list of a particular interface (ISetupRule, IGamePlayRule, IWinSorter or something like that) and you could create hierarchies of rules so you could theoretically share common rules amongst various games.
    Last edited by MadHatter; March 20th, 2007 at 03:30 PM.

  15. #15
    Join Date
    Mar 2007
    Posts
    109

    Re: DateTime.Now update rate???

    I really have no idea what all you are talking about. I'm still learning programming, and this is my first program I've ever built. I hope you can find an example for me to use so I can understand better what you are trying to do.

    I can no longer post my code because the program is starting to become somewhat large, and the files are also too large to attach to the thread. I think its going to be very fast and concise.

    Everything is using complete OOP, and Enums.

    There is a lack of comments because I'm still working out the kinks, before I go and write all the comments.

    Maybe I can ask one favor. Since this is my first solution. I want to make sure I'm on the right track before I completely screw up. I will post the solution files on my website, and maybe you can look at them quick, and see if I'm on the right track. If you have time.

    My main concerns are how the dealer is chosen, I'm not sure if its a reasonable solution. Most of the code was in place before, but some I modified because I liked your solution a little better. It made more since.

    I intend to create card engine, and then another project with the rules for Gin/Oklahoma Gin, and Wild Gin.

    Then a third project for the UI. This way if I make more card games in the figure I can reuse the card engine, and only have to replace Gin Engine which has the rules for Gin with another engine that has the rules for another card game, and recompile. It should be extremely simple to create additional games.

    Download (the additional exe file is just me playing around with the animation)

    Thanks. Please let me know what you think.

Page 1 of 2 12 LastLast

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