Welcome to Dream.In.Code
Getting C# Help is Easy!

Join 135,951 C# Programmers for FREE! Get instant access to thousands of C# experts, tutorials, code snippets, and more! There are 2,666 people online right now. Registration is fast and FREE... Join Now!




Making a deck of cards

2 Pages V  1 2 >  
Reply to this topicStart new topic

Making a deck of cards, using random to shuffle the cards

OliveOyl3471
12 May, 2008 - 09:32 PM
Post #1

It's all about the code ♥
Group Icon

Joined: 11 Jul, 2007
Posts: 1,606



Thanked: 17 times
Dream Kudos: 150
My Contributions
This is not homework, but was an assignment that was optional. I am only doing it now to see if I can.

The easy part is done. The textboxes will contain a number or letter from a deck of cards, when the user clicks the button, and it will randomize them. I still have to add the characters for the heart, spade, diamond and club. And if possible, change everything to the appropriate colors.
Then I have to figure out how to keep from repeating the same card. Please don't tell me yet, if you know. I'd like to try it first.

My question is about the textboxes. Is there a way to NOT have to write out each textbox? Something like:
CODE

for (int i =1; i<=52; i++)
{
textbox[i].Text = GetValues();
}


...but not that because it didn't work when I tried it. (Should I use something other than a textbox for this?)

Here's what I mean....too many textboxes!

CODE

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

namespace DeckOfCards
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        Random RandomClass = new Random();
        //create method to assign values to textboxes
        public string GetValues()
    {
      
             //populate textboxes with random numbers from 1 to 13
            // use "A" for 1, "J" for 11, "Q" for 12, and "K" for 13

                string Num = Convert.ToString(RandomClass.Next(1,13));
                if (Num == "1")
                {
                    Num = "A";
                }
                else if (Num == "11")
                {
                    Num = "J";
                }

                else if (Num == "12")
                {
                    Num = "Q";
                }
                else if (Num == "13")
                {
                    Num = "K";
                }
            return Num;
      
    }

        private void button1_Click(object sender, EventArgs e)
        {
            //when the user clicks the button populate textboxes with
            //random values equal to a deck of cards
               textBox1.Text = GetValues();
               textBox2.Text = GetValues();
               textBox3.Text = GetValues();
               textBox4.Text = GetValues();
               textBox5.Text = GetValues();
               textBox6.Text = GetValues();
               textBox7.Text = GetValues();
               textBox8.Text = GetValues();
               textBox9.Text = GetValues();
               textBox10.Text = GetValues();
               textBox11.Text = GetValues();
               textBox12.Text = GetValues();
               textBox13.Text = GetValues();
               textBox14.Text = GetValues();
               textBox15.Text = GetValues();
               textBox16.Text = GetValues();
               textBox17.Text = GetValues();
               textBox18.Text = GetValues();
               textBox19.Text = GetValues();
               textBox20.Text = GetValues();
               textBox21.Text = GetValues();
               textBox22.Text = GetValues();
               textBox23.Text = GetValues();
               textBox24.Text = GetValues();
               textBox25.Text = GetValues();
               textBox26.Text = GetValues();
               textBox27.Text = GetValues();
               textBox28.Text = GetValues();
               textBox29.Text = GetValues();
               textBox30.Text = GetValues();
               textBox31.Text = GetValues();
               textBox32.Text = GetValues();
               textBox33.Text = GetValues();
               textBox34.Text = GetValues();
               textBox35.Text = GetValues();
               textBox36.Text = GetValues();
               textBox37.Text = GetValues();
               textBox38.Text = GetValues();
               textBox39.Text = GetValues();
               textBox40.Text = GetValues();
               textBox41.Text = GetValues();
               textBox42.Text = GetValues();
               textBox43.Text = GetValues();
               textBox44.Text = GetValues();
               textBox45.Text = GetValues();
               textBox46.Text = GetValues();
               textBox47.Text = GetValues();
               textBox48.Text = GetValues();
               textBox49.Text = GetValues();
               textBox50.Text = GetValues();
               textBox51.Text = GetValues();
               textBox52.Text = GetValues();
          
        }
    }
}



edit-Now I have it all done except the colors and how to keep the cards from repeating. I have a feeling that is going to be the most difficult part of this. smile.gif

CODE


        public string GetChars()
        {
        //return either a heart, spade, diamond or club
           string c = Convert.ToString(RandomClass.Next(1, 5));
            if (c == "1")
            {
                //make it a heart //use alt + 3
                c = "♥";
                //change font color to red?
            }
            else if (c == "2")
            {
            //make it a diamond //use alt + 4
                c = "♦";
                //change font color to red?
            }
            else if (c == "3")
            {
            //make it a spade //use alt + 6
                c = "♠";
            }
            else if (c == "4")
            {
            //make it a club //use alt + 5
                c = "♣";
            }
            return c;
        }

   //code here

        private void button1_Click(object sender, EventArgs e)
        {
            //when the user clicks the button populate textboxes with
            //random values equal to a deck of cards
               textBox1.Text = GetValues() + GetChars();



Thanks for the suggestion BeaverDono. Do you know how to do it?
smile.gif

This post has been edited by OliveOyl3471: 12 May, 2008 - 10:31 PM
User is offlineProfile CardPM
+Quote Post

BeaverDono
RE: Making A Deck Of Cards
12 May, 2008 - 09:53 PM
Post #2

New D.I.C Head
*

Joined: 17 Apr, 2007
Posts: 36


My Contributions
For Loop 52 text boxes.. save your fingers! XD

I know you can do it in a For Loop, I've seen my friend Josh do it before at least a couple of times...
User is offlineProfile CardPM
+Quote Post

baavgai
RE: Making A Deck Of Cards
13 May, 2008 - 03:51 AM
Post #3

Dreaming Coder
Group Icon

Joined: 16 Oct, 2007
Posts: 2,015



Thanked: 105 times
Dream Kudos: 475
Expert In: C, C++, Java, C#, ASP.NET, PHP, Perl, Python, Oracle, SQL Server, MySql, HTML, JavaScript, Lua

My Contributions
QUOTE(OliveOyl3471 @ 13 May, 2008 - 01:32 AM) *

My question is about the textboxes. Is there a way to NOT have to write out each textbox?


Good question. Since you've already created the things the easiest way would be to create an array that references all of them and use that.

csharp

// you can't initialize this here, the form needs to do it's thing
private TextBox[] boxes;

public Form1() {
InitializeComponent();
// now the form has all it's objects lined up, we gather them up into an array
this.boxes = new TextBox[] {
textBox1,textBox2,textBox3,textBox4,textBox5,textBox6,
textBox7,textBox8,textBox9,textBox10,textBox11,textBox12,
textBox13,textBox14,textBox15,textBox16,textBox17,textBox18,
textBox19,textBox20,textBox21,textBox22,textBox23,textBox24,
textBox25,textBox26,textBox27,textBox28,textBox29,textBox30,textBox31,textBox32,

textBox33,textBox34,textBox35,textBox36,textBox37,textBox38,textBox39,textBox40,

textBox41,textBox42,textBox43,textBox44,textBox45,textBox46,textBox47,textBox48,

textBox49,textBox50,textBox51,textBox52
};
}

private void Form1_Load(object sender, EventArgs e) {
// Just a little test, to make sure we got them all
int i = 1;
foreach (TextBox tb in boxes) {
tb.Text = (i++).ToString();
}
}


Hope this helps.

User is offlineProfile CardPM
+Quote Post

OliveOyl3471
RE: Making A Deck Of Cards
13 May, 2008 - 11:55 AM
Post #4

It's all about the code ♥
Group Icon

Joined: 11 Jul, 2007
Posts: 1,606



Thanked: 17 times
Dream Kudos: 150
My Contributions
Thanks, baavgai. biggrin.gif

I didn't do it exactly as you wrote it (using this.), because it caused errors. Here is what I have now, which will work. biggrin.gif

As it is now, the textboxes come out the proper color, but I haven't attempted to keep the cards from repeating, yet. That is all that is left to do. smile.gif

CODE

namespace DeckOfCards
{

    public partial class Form1 : Form
    {
        Random RandomClass = new Random();

        TextBox[] boxes = null; //had to add this to get access to 'boxes' in button click event

        public Form1()
        {

            InitializeComponent();
            // now the form has all it's objects lined up, we gather them up into an array  
            //it doesn't like 'this.boxes = ...'
            boxes = new TextBox[]{  
        textBox1,textBox2,textBox3,//and the rest

//code here

public string GetChars()
        {
            //return either a heart, spade, diamond or club
            string c = Convert.ToString(RandomClass.Next(1, 5));
            if (c == "1")
            {
                //make it a heart //use alt + 3
                c = "♥";
            }
            else if (c == "2")
            {
                //make it a diamond //use alt + 4
                c = "♦";
            }
            else if (c == "3")
            {
                //make it a spade //use alt + 6
                c = "♠";
            }
            else if (c == "4")
            {
                //make it a club //use alt + 5
                c = "♣";
            }

    
            return c;
        }
        
//code here

                private void button1_Click(object sender, EventArgs e)
        {
            //when the user clicks the button populate textboxes with
            //random values equal to a deck of cards
            //change font color for diamonds and hearts to red, leave spades and clubs black

            foreach (TextBox tb in boxes)
            { tb.ForeColor = Color.Black; }

            foreach (TextBox tb in boxes)
            {
                {
                    string c = GetChars();
                    tb.Text = GetValues() + c;
                    if (c == "♦" || c == "♥")
                      
                        { tb.ForeColor = Color.Red; }
            }
                }


I'll keep trying and come back and edit this with the correct code when/if I get it. smile.gif

I have to go make dinner now so I can't work on this again until tonight. sad.gif

edit--added this code at the bottom and now every card is the same when the user clicks the button. It is still randomized when the button is clicked again tho.

I must have something backwards.
CODE

            //compare the contents of each textbox and replace any duplicates
for(int i =0; i<=50; i++)
{
            while  (string.Compare(boxes[i].ToString(), boxes[i+1].ToString()) != 0)
            {
                //replace content in second textbox being compared, if a duplicate is found
                string c = GetChars();
                boxes[i + 1].Text = GetValues() + c;
                boxes[i + 1].ForeColor = Color.Black;
                if (c == "♦" || c == "♥")

                {boxes[i + 1].ForeColor = Color.Red; }
            }              
            }


If I make this ==0 instead of !=0, then the cards will still have duplicates. (maybe it needs another loop somewhere?)
while (string.Compare(boxes[i].ToString(), boxes[i+1].ToString()) != 0)


This post has been edited by OliveOyl3471: 13 May, 2008 - 08:06 PM
User is offlineProfile CardPM
+Quote Post

OliveOyl3471
RE: Making A Deck Of Cards
14 May, 2008 - 06:20 AM
Post #5

It's all about the code ♥
Group Icon

Joined: 11 Jul, 2007
Posts: 1,606



Thanked: 17 times
Dream Kudos: 150
My Contributions
Ok...I admit defeat. I am stumped. How do you prevent duplicates in the textboxes?

As is, the program runs, but I'm not yet playing with a full deck, since there are duplicates.

tongue.gif

The program does compare some of the textboxes and replace duplicate text, but it doesn't keep comparing each textbox to every other one and replace the text until there are no more duplicates.

Is there something like a 'do until' loop in C#?

Am I looking in the right place, or is there a logic error somewhere else? Should I do the random differently, so it doesn't create the duplicates in the first place?

This post has been edited by OliveOyl3471: 14 May, 2008 - 06:40 AM
User is offlineProfile CardPM
+Quote Post

baavgai
RE: Making A Deck Of Cards
14 May, 2008 - 07:23 AM
Post #6

Dreaming Coder
Group Icon

Joined: 16 Oct, 2007
Posts: 2,015



Thanked: 105 times
Dream Kudos: 475
Expert In: C, C++, Java, C#, ASP.NET, PHP, Perl, Python, Oracle, SQL Server, MySql, HTML, JavaScript, Lua

My Contributions
It's simple, though probably not so if you've never seen it. wink2.gif

You want to create something like a CardDeck class, with all possible cards, usually 52. You then randomly pick a card from that deck, returning the chosen card and removing it from the deck. Rinse and repeat.

Without giving you the guts of it, your code might look like this

csharp

CardDeck deck = new CardDeck();
deck.Fill(); // load up all possible

for(int i=0; i<52; i++) {
Card card = deck.Deal(); // this removes a card at random from the deck and returns that value
if (card==null) {
boxes[i].Text = "Out of Cards";
} else {
boxes[i].Text = card.ToString();
}
}


Now, for your code...

First, buy a method; they don't cost anything. Also, I think your loop is one shy.
csharp


private string GetNewCard() {
return GetValues() + GetChars();
}

private bool HasCard(string cardValue, int maxCards) {
for(int i=0; i<=maxCards; i++) {
if (boxes[i].Text==cardValue) { return true; }
}
return false;
}

// now do the loop
for(int i=0; i<52; i++) {
string cardValue = GetNewCard();
while(HasCard(cardValue, i - 1)) {
cardValue = GetNewCard();
}
boxes[i].Text = cardValue;
}


Note, the loop is not optimal. The former card deck method will be significantly faster.

Hope this helps.


User is offlineProfile CardPM
+Quote Post

OliveOyl3471
RE: Making A Deck Of Cards
14 May, 2008 - 08:09 AM
Post #7

It's all about the code ♥
Group Icon

Joined: 11 Jul, 2007
Posts: 1,606



Thanked: 17 times
Dream Kudos: 150
My Contributions
Thank you baavgai.
biggrin.gif

Even with your help I still can't get it to work.

lookaround.gif sad.gif

This post has been edited by OliveOyl3471: 14 May, 2008 - 06:54 PM
User is offlineProfile CardPM
+Quote Post

OliveOyl3471
RE: Making A Deck Of Cards
15 May, 2008 - 08:05 PM
Post #8

It's all about the code ♥
Group Icon

Joined: 11 Jul, 2007
Posts: 1,606



Thanked: 17 times
Dream Kudos: 150
My Contributions

edit--I'm going to try the card deck method as you suggested, since I think you are quite right. It is the best way to do it.

And, since it wasn't working my way, I think maybe it just can't be done the way I've been trying to do it.

See...you can teach an old dog new tricks. Sometimes it just takes us a little longer. lol.

This post has been edited by OliveOyl3471: 15 May, 2008 - 08:47 PM
User is offlineProfile CardPM
+Quote Post

OliveOyl3471
RE: Making A Deck Of Cards
15 May, 2008 - 11:35 PM
Post #9

It's all about the code ♥
Group Icon

Joined: 11 Jul, 2007
Posts: 1,606



Thanked: 17 times
Dream Kudos: 150
My Contributions
I tried to do as you said.

I had to comment some of it out to get it to work. It still repeats. I don't know how to remove a card from the array once it's used.

This is probably not like it ought to be done.

CODE


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

namespace DeckOfCards3
{
    public partial class Form1 : Form
    {
        Random RandomClass = new Random();
        TextBox[] boxes = null;
        CardDeck deck = new CardDeck();
        CardDeck card = new CardDeck();

        public class CardDeck
        {

            public string Deal()
            {
                //create array to hold all card values
                string[] values = new string[] {"A♥","A♦","A♣","A♠","K♥","K♦","K♣","K♠","Q♥","Q♦","Q♣","Q♠","J♥","J♦","J♣","J♠",
                 "10♥","10♦","10♣","10♠","9♥","9♦","9♣","9♠","8♥","8♦","8♣","8♠","7♥","7♦","7♣","7♠","6♥","6♦","6♣","6♠",
                 "5♥","5♦","5♣","5♠","4♥","4♦","4♣","4♠","3♥","3♦","3♣","3♠","2♥","2♦","2♣","2♠"};
              

                 Random RandomClass = new Random();
                int acard = RandomClass.Next(51);
                return values[acard];
                // Remove the element at acard
               // values.RemoveAt(acard);//this doesn't work because it isn't arrayList
                

            }
        }
        // public CardDeck Deal()
        //  {

        // }

        public Form1()
        {
            InitializeComponent();

            //place all textboxes into an array for easier access later
            boxes = new TextBox[] { textBox1, textBox2, textBox3, textBox4, textBox5,
                textBox6, textBox7, textBox8, textBox9, textBox10, textBox11, textBox12,
                textBox13, textBox14, textBox15, textBox16, textBox17, textBox18,
                textBox19, textBox20, textBox21, textBox22, textBox23, textBox24,
                textBox25, textBox26, textBox27, textBox28, textBox29, textBox30,
                textBox31, textBox32, textBox33, textBox34, textBox35, textBox36,
                textBox37, textBox38, textBox39, textBox40, textBox41, textBox42,
                textBox43, textBox44, textBox45, textBox46, textBox47, textBox48,
                textBox49, textBox50, textBox51, textBox52 };

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //fill the deck with all 52 card values
            // deck.Fill();

        }

        private void button1_Click(object sender, EventArgs e)
        {


          
            // this removes a card at random from the deck and returns that value
            for (int i = 0; i < 52; i++)
            {
                string card = deck.Deal();
                if (card == null)
                {
                    boxes[i].Text = "Out of Cards";
                }
                else
                {
                    boxes[i].Text = card.ToString();
                    //remove each card from array as it's added to textbox
      

                }

                //remove a card at random from the deck and returns that value

                //  card = deck.Deal();
                //deck.Deal();
            }
        }
    }
}


User is offlineProfile CardPM
+Quote Post

baavgai
RE: Making A Deck Of Cards
16 May, 2008 - 07:02 AM
Post #10

Dreaming Coder
Group Icon

Joined: 16 Oct, 2007
Posts: 2,015



Thanked: 105 times
Dream Kudos: 475
Expert In: C, C++, Java, C#, ASP.NET, PHP, Perl, Python, Oracle, SQL Server, MySql, HTML, JavaScript, Lua

My Contributions
I'm afraid you're not really following the "CardDeck object as a container for cards that's depleated" idea. You called a RemoveAt method that's found in collections; let's use that:

csharp

// here, our CardDeck class is extends a string collection class, since our cards are being represented by strings.
class CardDeck : List<string> {
// hold the suit and value lists for easy population
private static string[] cardValues = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
private static string[] cardSuits = { "S", "H", "C", "D" };

// we'll need a randomize, we'll create it for the object,
// so we don't have to keep creating and dropping it.
private Random rnd = new Random();

public CardDeck() {
// fill the list, using our suit and value lists
foreach (string cardSuit in cardSuits) {
foreach (string cardValue in cardValues) {
this.Add(cardValue + cardSuit);
}
}
}

public string DealCard() {
// if we're out of card, throw a null
if (this.Count == 0) { return null; }

// get a random index, based on the number of entries we currently have
int cardIndex = rnd.Next(this.Count);
// save the value we picked to a variable
string card = this[cardIndex];
// remove the card we picked from our list
this.RemoveAt(cardIndex);
// return the card
return card;
}
}

// test code
// create and instance of CardDeck
// it starts out full of cards
CardDeck deck = new CardDeck();
// while it has cards, print them
while (deck.Count > 0) {
Debug.WriteLine(deck.DealCard());
}


User is offlineProfile CardPM
+Quote Post

hyperionza
RE: Making A Deck Of Cards
16 May, 2008 - 03:47 PM
Post #11

New D.I.C Head
*

Joined: 15 Sep, 2007
Posts: 30


My Contributions
No idea if its still the topic, or even still relevant to topic, its 0130AM and im exhausted but anyway...
Ive had to do a similar thing (shuffling and dealing a deck of cards) as part of my AI honours project and i think that the priciple can be applied here (or maybe not...) so modifying the code that i have and adding in bits and pieces from the posts above...

CODE
for (int i = 0; i < 52; i++)
            {
                int place = r.Next(1, 53)); // randomly pick a textbox from the array
               if (boxes[place].Text == "") boxes[place].Text = card[i].ToString();
               else i--; //yes i know im cheating, if there is something already in the box, make it think <i> is 1 less so it repeats the placing of card[i]
            }


ok that looks nothing like my code now wink2.gif

btw :
the object "card" is an array, obviously, of a class, and its ToString() method just produces a string representation of the card held at index i.

i sincerely hope that made sense, it should provide a way of stopping duplicates from happening. as you must assign each card at most and at least once to an empty textbox

good luck
User is offlineProfile CardPM
+Quote Post

OliveOyl3471
RE: Making A Deck Of Cards
17 May, 2008 - 04:12 PM
Post #12

It's all about the code ♥
Group Icon

Joined: 11 Jul, 2007
Posts: 1,606



Thanked: 17 times
Dream Kudos: 150
My Contributions
QUOTE(hyperionza @ 16 May, 2008 - 04:47 PM) *

No idea if its still the topic, or even still relevant to topic, its 0130AM and im exhausted but anyway...
Ive had to do a similar thing (shuffling and dealing a deck of cards) as part of my AI honours project and i think that the priciple can be applied here (or maybe not...) so modifying the code that i have and adding in bits and pieces from the posts above...

CODE
for (int i = 0; i < 52; i++)
            {
                int place = r.Next(1, 53)); // randomly pick a textbox from the array
               if (boxes[place].Text == "") boxes[place].Text = card[i].ToString();
               else i--; //yes i know im cheating, if there is something already in the box, make it think <i> is 1 less so it repeats the placing of card[i]
            }


ok that looks nothing like my code now wink2.gif

btw :
the object "card" is an array, obviously, of a class, and its ToString() method just produces a string representation of the card held at index i.

i sincerely hope that made sense, it should provide a way of stopping duplicates from happening. as you must assign each card at most and at least once to an empty textbox

good luck


Yes it makes sense, and yes it is on topic.
And, yes, I tried your suggestion and it works! bigsmile.gif

I just couldn't get it to work the way you showed me, baavgai.

I tried both of these, but could only make the second one work. 1. to select a card at random and fill the textboxes in order. and 2. to select a textbox at random and load the cards in order.

Thank you so much, both of you, for all of your help. I know it takes a lot of time to do this and I really appreciate it.

smile.gif icon_up.gif

my finished program (and yours, lol):

CODE

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

namespace DeckOfCards3
{
    public partial class Form1 : Form
    {
        Random RandomClass = new Random();
        TextBox[] boxes = null;
        
        Random r = new Random();
        string[] cards = new string[] {"A♥","A♦","A♣","A♠","K♥","K♦","K♣","K♠","Q♥","Q♦","Q♣","Q♠","J♥","J♦","J♣","J♠",
                 "10♥","10♦","10♣","10♠","9♥",&#