Author Topic: Random number generator inside While loop  (Read 1346 times)

Legacy_Ivanovich

  • Full Member
  • ***
  • Posts: 142
  • Karma: +0/-0
Random number generator inside While loop
« on: July 28, 2010, 04:28:03 pm »


               Hi folks, I'm trying to insert a random number integer inside a "while" loop, but it continues to give me the same number each and every time (the maxinteger).  It's maddening.  I've tried it with the random function, and with the d4() function, but I always get "3".  Here is the code.  Any help is appreciated.


void main()
{
object oCenter = GetObjectByTag("guardbeacon");
string sWay = "Guard";
string sGuard;
object oArea = GetArea(GetEnteringObject());
string sArea = GetTag(oArea);
string sTarget;
int nCount = 1;
object oTarget;
location lTarget;
int iRand = Random(4);
string sRand;

if (sArea == "AmaristanCoastwood")
{
        if (GetLocalString(oArea, "Guards") != "yes")
        {
            SetLocalString(oArea, "Guards", "yes");
            sGuard = "amarioutcast001";

            oTarget = GetNearestObjectByTag(sWay, oCenter, nCount);
            lTarget = GetLocation(oTarget);

            while (GetIsObjectValid(oTarget))
            {
            CreateObject(OBJECT_TYPE_CREATURE, sGuard, lTarget, FALSE);
            nCount = nCount + 1;
            oTarget = GetNearestObjectByTag(sWay, oCenter, nCount);
            lTarget = GetLocation(oTarget);
            iRand = Random(4);
                if (iRand = 0)
                {
                sGuard = "amarioutcast001";
                }
                if (iRand = 1)
                {
                sGuard = "amarioutcast";
                }
                if (iRand = 2)
                {
                sGuard = "arakirirebel";
                }
                if (iRand = 3)
                {
                sGuard = "dhazaarioutcast";
                }
             sRand = IntToString(iRand);
             SendMessageToPC(GetEnteringObject(), "iRand is " + sRand);
            }
        }
}

}
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Random number generator inside While loop
« Reply #1 on: July 28, 2010, 05:28:15 pm »


               Im using Random(Random(Random(7))); in module onload and randoms number sequence was always different. Also in PW enviroment it will be different. If that won't work, try use Random(GetTimeMiliseconds()); in each area OnEnter, that must work
               
               

               


                     Modifié par ShaDoOoW, 28 juillet 2010 - 04:29 .
                     
                  


            

Legacy_420

  • Sr. Member
  • ****
  • Posts: 370
  • Karma: +0/-0
Random number generator inside While loop
« Reply #2 on: July 28, 2010, 05:29:15 pm »


               The random function isn't truly random unfortunately and will always return the same sequence of numbers unless you first mix it up a bit.

Try putting a line like this in the OnClientEnter event of the Module Properties:

Random(GetTimeMillisecond());

The other problem is that you are using a while statement but you aren't cycling through any objects using GetFirst and GetNext functions. An if statement would be more appropriate than the while.

Lastly, instead of doing a bunch of if statements you may want to use a switch/case:

iRand = Random(4);
switch(iRand);
    {
    case 0:
        sGuard = "amarioutcast001";
        break;
    case 1:
        sGuard = "amarioutcast";
        break;
    case 2:
        sGuard = "arakirirebel";
        break;
    case 3:
        sGuard = "dhazaarioutcast";
        break;
    }

-420
               
               

               
            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
Random number generator inside While loop
« Reply #3 on: July 28, 2010, 07:32:38 pm »


               IMO Random works just fine. I think your main problem is that these:

if (iRand = 0)

should be:

if (iRand == 0)

If you want to see the randomness this is how I tested it. I took a part of what you had there and stuck it in a while loop to run 100 times. You will see that you get a pretty even mix. Here's the script:

void main()
{
int iLoops = 100;
int iGuard1;
int iGuard2;
int iGuard3;
int iGuard4;
string sGuard;

while (iLoops >0)
    {
    int iRand = Random(4);
    if (iRand == 0)
        {
        sGuard = "amarioutcast001";
        iGuard1++;
        }
    if (iRand == 1)
        {
        sGuard = "amarioutcast";
        iGuard2++;
        }
    if (iRand == 2)
        {
        sGuard = "arakirirebel";
        iGuard3++;
        }
    if (iRand == 3)
        {
        sGuard = "dhazaarioutcast";
        iGuard4++;
        }
    iLoops--;
    }

string sGuard1 = IntToString(iGuard1);
string sGuard2 = IntToString(iGuard2);
string sGuard3 = IntToString(iGuard3);
string sGuard4 = IntToString(iGuard4);
//sRand = IntToString(iRand);
//SendMessageToPC(GetEnteringObject(), "iRand is " + sRand);
SendMessageToPC(GetEnteringObject(), "Guard1 =" + sGuard1 +
                                     "\\\\\\\\nGuard2 =" + sGuard2 +
                                     "\\\\\\\\nGuard3 =" + sGuard3 +
                                     "\\\\\\\\nGuard4 =" + sGuard4);
}

Hope this helps. Good luck.

EDIT: Please note that for some reason when you put a "\\" in a post here it adds three more to it. There should only be one in front of the "n"s  where it says "nGuard2", "nGuard3" and "nGuard4". Not sure why this happens but it can be very problematic to some scripts if people don't catch it.
               
               

               


                     Modifié par GhostOfGod, 28 juillet 2010 - 06:44 .
                     
                  


            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
Random number generator inside While loop
« Reply #4 on: July 28, 2010, 07:46:11 pm »


               Oh for crying out loud. Ok it added more of those when i edited it. This is something that needs to be fixed. But anyway there should only be one just in front of the "n"s. Sorry bout this second post but i didn't want a bunch more on there.
               
               

               
            

Legacy_TheSpiritedLass

  • Hero Member
  • *****
  • Posts: 1118
  • Karma: +0/-0
Random number generator inside While loop
« Reply #5 on: July 28, 2010, 08:49:13 pm »


               *groans*  Nice catch Ghost.  classic problem.



The NWN compilier should have thrown a total fit over that logic issue, Ivanovich.  Not that I just did that myself earlier this week to know that.  Nope, not me.  Uh uh.  *whistles innocently*
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Random number generator inside While loop
« Reply #6 on: July 28, 2010, 10:19:07 pm »


               umm sorry was trying to post a single slash.  I faild.  Back to the drawing board. 




 
               
               

               


                     Modifié par Lightfoot8, 28 juillet 2010 - 09:24 .
                     
                  


            

Legacy_Ivanovich

  • Full Member
  • ***
  • Posts: 142
  • Karma: +0/-0
Random number generator inside While loop
« Reply #7 on: July 30, 2010, 08:52:50 pm »


               I appreciate all the feedback.  It would seem I have a problem even before I get to the random number issue.  I put the above script in the OnEnter part of an area.  It locks up and does not load the module when this is the case - regardless of whether or not I am starting in that area.  I've narrowed it down to the "CreateObject" inside the script.



All I'm trying to do is - when a PC enters an area - have guards spawn on waypoints already layed out in the module.  I've tried the PersistentObject function, to no avail (it did not like the area as the persistent object.



if the creature is "creature001" and the waypoint is "guard" and there are 3 waypoints (but the number could vary in different zones), how on God's green Earth can I simply get the guards to spawn on variable number of waypoints named "Guard" as the PC enters the zone?



This really shouldn't be that difficult, yet I seem to hit a wall each time.
               
               

               
            

Legacy_Ivanovich

  • Full Member
  • ***
  • Posts: 142
  • Karma: +0/-0
Random number generator inside While loop
« Reply #8 on: July 30, 2010, 09:09:29 pm »


               This is the script I'm using.  I've commented out the createobject because if I do not, the module doesn't load.  At all.  



I've read the response from "420" above, but I cannot figure how else to create the loop without a "while".

               
               

               
            

Legacy_Ivanovich

  • Full Member
  • ***
  • Posts: 142
  • Karma: +0/-0
Random number generator inside While loop
« Reply #9 on: July 30, 2010, 09:09:35 pm »


               void main()

{

object oPC = GetEnteringObject();

object oCenter = GetNearestObjectByTag("x3_plc_evlaltar", oPC);

string sWay = "Guard";

string sGuard;

object oArea = OBJECT_SELF;

string sArea = GetTag(oArea);

string sTarget;

int nCount = 1;

object oTarget;

location lTarget;

int iRand = Random(4);

string sRand;







if (sArea == "AmaristanTownofAbbala")

{

           sGuard = "arakhirisoldier1";



           oTarget = GetNearestObjectByTag(sWay, oCenter, nCount);

           lTarget = GetLocation(oTarget);



       if (GetLocalString(oArea, "Guards") != "yes")

       {

           while (GetIsObjectValid(oTarget))

           {

           SendMessageToPC(oPC, "Pass");

           //CreateObject(OBJECT_TYPE_CREATURE, sGuard, lTarget, FALSE);

           nCount = nCount + 1;

           oTarget = GetNearestObjectByTag(sWay, oCenter, nCount);

           lTarget = GetLocation(oTarget);

           }

        }



        SetLocalString(oArea, "Guards", "Yes");

}

}
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Random number generator inside While loop
« Reply #10 on: July 30, 2010, 09:29:25 pm »


               Your problem is simple. The OnEnter Event for the area Fires every time something enters the area, Not just a PC. So when the script first runs and creates another object in the area, this new object entering the area also fires the Event and creates another object entering the area. around and around we go. The loop never stops and your module locks up.

To fix put a check at the top of the script to exit the script if the Entering object is not a PC.

object oPC = GetEnteringObject();

If (!GetIsPC(oPC)) return;
               
               

               


                     Modifié par Lightfoot8, 30 juillet 2010 - 08:29 .
                     
                  


            

Legacy_Ivanovich

  • Full Member
  • ***
  • Posts: 142
  • Karma: +0/-0
Random number generator inside While loop
« Reply #11 on: July 30, 2010, 09:36:51 pm »


               Here's a new script for you:



string sMan = "The Man"

object oHelper = LastForumHelper();



SendMessageToForumHelper(oHelper, "You = " + sMan + "!!  Thanks!");



               
               

               
            

Legacy_420

  • Sr. Member
  • ****
  • Posts: 370
  • Karma: +0/-0
Random number generator inside While loop
« Reply #12 on: July 30, 2010, 11:18:51 pm »


               Good catch Lightfoot8, sometimes it's the simplest solutions that are the hardest to see.

Ivanovich wrote...

I've read the response from "420" above, but I cannot figure how else to create the loop without a "while".

What I meant was that if you want to use a while loop the format should look something like this:

void main()
{
object oTarget = GetFirstObjectInArea(OBJECT_SELF);
while(GetIsObjectValid(oTarget))
    {
    if(GetTag(oTarget) == "TargetTag")
        {
        //Do something to the target then break out of the loop
        break;
        }
    oTarget = GetNextObjectInArea(OBJECT_SELF);
    }
}

There are a bunch of helpful GetFirst/GetNext related functions:

GetFirstEffect()
GetFirstFactionMember() [Used to cycle through party members]
GetFirstInPersistentObject() [Used to cycle through objects in a trigger or an AoE]
GetFirstItemInInventory()
GetFirstItemProperty()
GetFirstObjectInArea()
GetFirstObjectInShape() [Also used for auras]
GetFirstPC()

In addition you can always use the iLoops method posted by GhostOfGod if you are working with a static number of objects.

-420
               
               

               


                     Modifié par 420, 30 juillet 2010 - 10:19 .
                     
                  


            

Legacy_Ivanovich

  • Full Member
  • ***
  • Posts: 142
  • Karma: +0/-0
Random number generator inside While loop
« Reply #13 on: July 31, 2010, 01:44:03 am »


               I stayed away from the GetFirstObjectInArea because of the amount of objects in the area.  It might be a cumbersome script on the server.



               
               

               
            

Legacy_Ivanovich

  • Full Member
  • ***
  • Posts: 142
  • Karma: +0/-0
Random number generator inside While loop
« Reply #14 on: July 31, 2010, 01:51:29 am »


               Here's an additional question.  On Exiting the area, I've got this:

object oPC = GetExitingObject();
object oCenter = GetNearestObjectByTag("guardbeacon", oPC);

but oCenter is always blank, as if it's not picked up.  The item "guardbeacon" is in the area the PC just exited.  But it seems that if I put this script in the OnExit part of the area, it never finds the "guardbeacon" with this function.  Thoughts?

I also tried it with

object oCenter = GetNearestObjectByTag("guardbeacon", OBJECT_SELF);

But the area doesn't get it either.
               
               

               


                     Modifié par Ivanovich, 31 juillet 2010 - 12:52 .