|
|||
|
Last things Term Project Specs PLP Team Assignments Key control code Including Blackjack Including game prototype How to Lingo Sample How to Lingo Summary Blackjack project How to Lingo midterm Fallout Game, Part 1 Walker-scroller project Lingo Walker project Unique random selection Case assignment Scripted animation Hints for Part 3 Term project Timeline vs. scripting Materials from UB Course "How To Lingo" Project Syllabus |
Selecting Unique Random ValuesWe can use the simple random() statement in Lingo to pick a number out of a certain range when needed. In unconstrained selection (for instance, rolling dice), we can pick the same number over and over. But in many cases, especially in game development, we need to be sure that the same number never comes up twice. Sometimes we even need to rule out certain selections for three or more turns. Here are two techniques for improving random number selection. The first uses an exclusion algorithm to shift the range of selection around the number previously selected. It is very efficient and a good choice for first-order constraint (i.e., preventing any number from coming up twice). It can't be applied directly, however, to higher levels of constraint (preventing a number from coming up again in three turns, four turns, etc.); so I'll also explain a second, scaleable method. This one is a bit less desirable from a programming standpoint, but it should work effectively enough on today's fast PCs.
First-Order Constraint: Range Shifting First add the following lines to your main movie script: global randy, randyOld randy = 0 randyOld = 0 You'll use these two variables (which you can rename as you like) to compare the previous random number selection against the present selection. Since there is no previous selection when your movie starts up, we preload the variables. It is crucial that you assign them the same value. Also note that these variables are global (accessible across scripts), because they must be initialized in the startMovie handler of the main movie script, but must be used elsewhere. Next place the following lines wherever you need to generate a random number: global randy, randyOld maxRand = 10 --or whatever value you prefer loRange = randyOld - 1 hiRange = maxRand - randyOld if hiRange = loRange then randy = randyOld+random(hiRange) end if if hiRange > loRange then randy = randyOld + random(hiRange) else randy = random(loRange) end if randyOld = randy Here's how the script works. First we specify a maximum range for our random number. (You could put this value into a global variable declared in the main movie script; I like to put the assignment in the local script so that I can change it more easily if necessary.) Next we compute two numbers based on the current value of randyOld, the variable that stores the random number selected on the previous execution. The first, loRange, indicates how many numbers we could pick that are lower than the previous selection; hiRange tells us how many numbers are above the last pick. We compare the two ranges. If they are equal (which can only happen if you have an odd number for maxRand, by the way), then we arbitrarily decide to pick from the higher range (you could choose the lower range if you like). To do this we add randyOld, our previous selection, to some number arbitrarily chosen from the range. This puts us at some randomly chosen position above the last selection. If one range is larger than the other, however, we use that one to obtain the greater possibility for selection. This is done simply by choosing a random value from a range defined by our last choice minus one. Finally we set randyOld equal to randy, the random number we just chose, so that we can run the process again. Higher-Order Constraint: Looping Suppose we need a random selection that repeats itself with lower frequency. The algorithm described above won't work, since it splits its range based on only two values, current and previous pick. Here's a method that can work with more than one constraint. It has a certain drawback, which we'll discuss after going through the code. Put these lines into your main movie script: global randy, randyOld, randyOlder randy = 0 randyOld = 0 randyOlder = 0 Use these lines where you need to generate a random number: global randy, randyOld, randyOlder repeat while randy = randyOld or randy = randyOlder randy = random(10) --or whatever value you prefer end repeat randyOlder = randyOld randyOld = randy As you can see, we use the repeat while loop to make Director bring us a fresh number if it presents one we've seen on the last two turns. Once we have an unused selection, we make a record and move on. The order in which the recording variables are refreshed--oldest first--is crucial. The script won't work if you change this order. Now the drawback: this code sends Director into a loop of indefinite duration. Technically, the program could keep selecting the same number over and over, just as you might keep rolling the same number with a pair of dice. Thus your movie could stutter or hang. If your range of random possibilities is reasonably high, though (10 or above), and your level of constraint is reasonably low (repetition banned for no more than three turns), this algorithm should work without detectable pause on a contemporary computer. | ||
|
|||