Function that affects controls

Hello, I have an important question; why do I get an error running my following code. But first let me explain what I did. I have my main "Form1.h" header in which I wrote the following class:

public ref class MyCommands
    {
        static int MyInt;
        static int CardsDrawn;
        public:
            void DrawCard()
            {
                Random^ r = gcnew Random;
                if (CardsDrawn < 56)
                {
                    bool Finished;
                    while (Finished == false)
                    {
                        MyInt = r->Next(0,56);
                        String^ key = imageList1->Images->Keys[MyInt];
                        if (key->Contains("used") == false)
                        {
                            listView1->Items->Add(key, imageList1->Images->IndexOf(imageList1->Images[MyInt]));
                            imageList1->Images->SetKeyName(imageList1->Images->IndexOf(imageList1->Images[MyInt]), key + "used");
                            CardsDrawn++;
                            Finished = true;
                        }
                        else
                        {
                        }
                    }
                }
                else
                {
                    MessageBox::Show("There are no more cards left", "Oops!", MessageBoxButtons::OK, MessageBoxIcon::Error);
                }
            }
    };

Now in my form I wanted to use the command DrawCard();

                  MyCommands^ MC;
                 MC->DrawCard();


All of this compiles fine and runs untill the function DrawCard is called. When the function is called everything still works ok untill it reaches the line where it says "listView1->Items->Add(key, imageList1->Images->IndexOf(imageList1->Images[MyInt]))". When that line is reached I get the following error message:
///////////////////////////////////////
An unhandled exception of type 'System.NotSupportedException' occurred in System.Windows.Forms.dll

Addiotional Information: Specified method is not supported
///////////////////////////////////////
Break        Continue
///////////////////////////////////////

What does this mean What's wrong

**  - by the way - the class is declared after the creation of the controls and I have a ListView called listView1 and a ImageList called imageList1.

With Thanks,
        Gal Beniamini.


Answer this question

Function that affects controls

  • Jerry Liu

    OK, so now we've established your exact problem, now we can solve it using whatever means are necessary.

    You're current algorithm suffers from a flaw. When the card you are about to draw is already marked as used, you draw a new random card and you repeat generating random numbers until you get one that isn't marked as used.

    Let's say there's only one card left in the deck (let's say it's the 26th card), and you need to deal out that card. You're generating a random number from 1 to 56, which you're hoping is 26. If it isn't, what you then do is pick another random from 1 to 56 (which you're hoping will be 26). See the problem now It's like rolling the dice until you get a 6, or playing the lottery every week until you'll get a jackpot (Sure, by playing every day, there'll be that one day where you'll get lucky and win, but that could take a while and could cost you a lot of money).

    What I would do is instead of keeping tabs on what cards are drawn, I would keep tabs on what cards are left. To generate the random number, I would do:

    MyInt = r->Next(0, CardsLeft);

    This gives me a number between 0 and CardsLeft. Next, I would create a method to get the nth unused card from the deck:

    int GetNthUnusedCard(int n)
    {
      int i = 0;
      while(n > 0)
      {
        String ^key = imageList1->Images->KeysIdea;
        ++i;
        if(key->Contains("used") == false)
        {
          --n;
        }
        if(i > imageList1->Images->Count)
        {/* n is too large. */
          throw gcnew ArgumentOutOfRangeException();
        }
      }
      return i;
    }

    Now that I have the index of the card I want to deal, I would deal it:

    int i = GetNthUnusedCard(MyInt);
    listView1->Items->Add(key, i);

    then I would wrap this in a loop to deal all 56 cards.

    Did you notice that we passed in the index of the ith unused card. What you did was instead of passing the index directly, you did this weird roundabout method of getting the index of the image which matches the ith image.

    /* You did: */
    listView1->Items->Add(key, imageList1->Images->IndexOf(imageList1->Images[MyInt]));

    /* When you could have just done: */
    listView1->Items->Add(key, MyInt);

    And what I wanted to know is: why Why did you take this long winded approach to getting the index. What's so special about the long winded method that makes it different from the direct method

     



  • mcerisano

    Hello OShah, thanks for your answer, but before I start please let me make myself clearer. What I intended to do was a function that draws a card from the deck. Might I add, just to clarify the matter a bit, that I have an imageList which contains 56 images with according names. When a card is drawn - I add to the key of the image the word "used" then when I randomize another number - if the specified number's key is "used" I randomize again until I get to the desired result. Now after I get to an un-used image's index, I want to add to a listBox on my form an item with the same name and image randomized. Then I want to add to the key of the image in the imageList in my form the word "used" so it won't be randomized again. Help would be much appreciated.

    With Thanks,

                        Gal Beniamini.


  • forester

    The docs for ImageListCollection.IndexOf (http://msdn2.microsoft.com/en-us/library/e48hdxxc(en-US,VS.80).aspx) say this method is not currently supported, and that's probably where you're getting the NotSupportedException. Implementing an IndexOf() requires an equals operator. Question: What makes two images (or an icon and an image, since ImageList supports both icons and images) equal to each other

    .Net does provide an IndexOfKey as an alternative for searching (search by key instead of search by image)... but in your case, didn't you want to return MyInt rather than IndexOf(Images[MyInt]); (sorry if my understanding is wrong, but that is my understanding)

     



  • Function that affects controls