Jump to content


Photo

Random Numbers & For Loops


  • This topic is locked This topic is locked
7 replies to this topic

#1 DeathDealer2BK

DeathDealer2BK

    GMC Member

  • New Member
  • 2 posts
  • Version:GM8

Posted 19 May 2012 - 06:18 AM

I was wondering if any one could give me a hand with this script I have been working on, any help would be much appreciated.
the script is supposed to pick a number between 1-5 and assign it to an array[0...4] while not picking the same number twice
but it does not work, it sometimes picks them right, unfortunately it mostly picks duplicates.
Might be something I'm over looking so hopefully someone might be able spot it.


Script

var a, aS, i, ii, rnum, r1, r2;

aS = argument0;
r1 = argument1;
r2 = argument2;


//Init a global array to store the numbers in or clear it if it exist.
for (a=0; a<aS a+=1) 
    {
     global.calllist[a]=0;
    }

    for (ii=0; ii<aS; ii+=1)
        {
            rnum = irandom_range(r1,r2);//Pick an initial random number between r1 - r2. 
            for (i=0; i<aS; i+=1;)
                {
                    if rnum = global.calllist[i]//Verify that the numbers in the list are not the same.
                        {
                            i = 0;
                            global.skipbacks += 1;//Some debug code to see how many times it took to get a non-duplicate number
                            rnum = irandom_range(r1,r2);//The number was the same a one in the list pick a new one.
                        }
                     
                }
            global.calllist[ii] = rnum; //add the resulting number to the list and loop again
        }



  • 0

#2 Canite

Canite

    Canigget

  • GMC Member
  • 1358 posts
  • Version:GM8

Posted 19 May 2012 - 07:45 AM

I just implemented this script and it works perfectly every time. I imagine your problem lies elsewhere.. I see that your script allows you to put any numbers into r1 and r2, but it would have to be a number range larger than your aS value (which I think you know because this would not create duplicate numbers but would instead freeze the game).
Anyways, post any other code you have relating to this or relating to the variable global.calllist[]. If you have pro, you could also make it more efficient by using a ds_list instead of an array, but as is, this works.

Edit: I just changed it to match yours exactly ( I was using a size of 4 and picking numbers between 1 and 5, I changed it to a size of 5), and I got a repeated number, looking into it now..

Edit #2: Aha!! I found your problem. The issue is that when you "reset" the loop to check for the new random number, you set i to 0, but 1 is then added to i at the end of that loop, causing it to skip the check for the very first number. I fixed this by changing it to this:
var a, aS, i, ii, rnum, r1, r2;

aS = argument0;
r1 = argument1;
r2 = argument2;


//Init a global array to store the numbers in or clear it if it exist.
for (a=0; a<aS a+=1) 
    {
     global.calllist[a]=0;
    }

    for (ii=0; ii<aS; ii+=1)
        {
            rnum = irandom_range(r1,r2);//Pick an initial random number between r1 - r2. 
            for (i=0; i<aS; i+=1;)
                {
                    if rnum = global.calllist[i]//Verify that the numbers in the list are not the same.
                        {
                            i = -1; // 1 will be added to i at the end of the loop, so set to -1 so it is 0 when the loop ends
                            global.skipbacks += 1;//Some debug code to see how many times it took to get a non-duplicate number
                            rnum = irandom_range(r1,r2);//The number was the same a one in the list pick a new one.
                        }
                     
                }
            global.calllist[ii] = rnum; //add the resulting number to the list and loop again
        }
You seem to have a pretty nice understanding of GML for only being your first post, so I think you'll do fine. Goodluck! :happy:

Edited by Canite, 19 May 2012 - 07:56 AM.

  • 0

#3 Dark Matter

Dark Matter

    RPG Expert

  • GMC Member
  • 3196 posts
  • Version:GM:Studio

Posted 19 May 2012 - 02:10 PM

You seem to have a pretty nice understanding of GML for only being your first post, so I think you'll do fine.

I think this is a bit misleading. Just because you've only just joined, or posted on, the GMC, doesn't mean you'll be a complete beginner. I only joined when I discovered a question about GML I couldn't answer, and was definitely more advanced than many people with much higher post counts. I know that this will also apply to many other people. I don't think, therefore, that comment was really justified.
  • 0

#4 brac37

brac37

    GMC Member

  • GMC Member
  • 768 posts
  • Version:GM7

Posted 19 May 2012 - 07:05 PM

Making a list of length n with n numbers can be done far more efficiently by initializing with 1 to n and next shuffle it.
  • 0

#5 Gamer3D

Gamer3D

    Human* me = this;

  • GMC Member
  • 1619 posts
  • Version:GM:Studio

Posted 19 May 2012 - 08:35 PM

Making a list of length n with n numbers can be done far more efficiently by initializing with 1 to n and next shuffle it.

Except it's not that the numbers have to be in random order (they will eventually but that's not the point yet) but that the numbers must be random integers in [r1, r2] without duplicates.

Establishing the numbers before shuffling would permit us to use an ascending order, but that's not particularly helpful unless we want to slightly improve the efficiency of his algorithm for large lists.

Since I posted that, I might as well reply to the other topic of discussion here. If I recall correctly, I joined so that I could answer a question about another language's semantics (Wanted to know how to access pixels directly) (Yeah, yeah. I was young and didn't think about it) but apart from that, I don't recall wanting to ask any questions.
  • 0

#6 Canite

Canite

    Canigget

  • GMC Member
  • 1358 posts
  • Version:GM8

Posted 19 May 2012 - 11:50 PM


You seem to have a pretty nice understanding of GML for only being your first post, so I think you'll do fine.

I think this is a bit misleading. Just because you've only just joined, or posted on, the GMC, doesn't mean you'll be a complete beginner. I only joined when I discovered a question about GML I couldn't answer, and was definitely more advanced than many people with much higher post counts. I know that this will also apply to many other people. I don't think, therefore, that comment was really justified.


It was just a last comment. I noticed it was his first post and said that from what he wrote he should be fine. It might have been unnecessary, but I was merely boosting his confidence and surely did no harm..
  • 0

#7 DeathDealer2BK

DeathDealer2BK

    GMC Member

  • New Member
  • 2 posts
  • Version:GM8

Posted 20 May 2012 - 02:53 AM

Thanks that totally fixed my problem Canite I never thought to make it negative number, I just
figured it would through an array out bounds error and yes I know a little about GML, I've been messing around with it for like 7 years or so
although I'm no pro. :whistle:
  • 0

#8 Yourself

Yourself

    The Ultimate Pronoun

  • Retired Staff
  • 7343 posts
  • Version:Unknown

Posted 20 May 2012 - 06:02 PM

Except it's not that the numbers have to be in random order (they will eventually but that's not the point yet) but that the numbers must be random integers in [r1, r2] without duplicates.


But it's still the same problem. Take all the integers in [r1, r2], put them in a random order, and then take the first k of them if you don't want all of them. You don't even really have to shuffle all integers, either. So, assuming you have an array called values with n elements that you want to pick k items from without replacement:

var i, r, t;

for( i = 0; i < k; i += 1 )
{
    r = irandom_range( i, n - 1 );
    t = values[i];
    values[i] = values[r];
    values[r] = t;
}

Now the first k elements in the values array contain a random sample. This is the simplest and fastest way to perform a random sample without replacement. If the set you're selecting from is too large to fit in an array, however, you're going to have to brute-force it and search through all your previous selections to see what's been selected. A linear search would be the most memory efficient but also the slowest. To make it faster you'd need to store an additional data structure that allows you to search quickly to see if you've already selected a particular integer. If we had hash maps I'd recommend that, but a ds_map would work fine (or if you really like arrays you can store an additional sorted array). But this is essentially what your code is trying to do.
  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users