Jump to content
New account registrations are disabed. This website is now an archive. Read more here.
  • 0
Shaily

How to use random numbers with no repeats?

Question

I'm working on a personal project in RMXP, a maze-style game. In the first level, there are five chests. One of them has a key, one has a power-up, the rest are empty. I know how to make these things work, but I'm trying to randomise which chests have what without repeats or missing things out.

 

I've tried setting up a variable for the key with a random number between 1 and 5, and having each chest check for a different number in that range, only giving a key if it matches. However, I don't want to have a chest give more than one thing, for example a key AND a power-up (and/or a spell, which appears in later levels) from the same chest. I can't think of a way to set this up without having a mess of commands that is impossible to keep track of and keep free from errors.

 

Ideally, what I'd like to do is to set each level with a list of numbers to determine what is in a chest (1 = key, 2 = power-up, 3 = empty, etc.). Then I want each chest in the room to randomly select a number from that list, but without any repeats or missing numbers. It's the second part I'm having trouble with. Is there a way? Am I missing something? Any help with this would be appreciated!

Share this post


Link to post
Share on other sites

7 answers to this question

Recommended Posts

  • 0

I can't think of a fast and clean way to do this with events, however using scripts you can try this:

# Adds a new method to sample an item from an array, put in an entry anywhere in the script editor
class Array
 def sample!
i = rand(self.size)
return self.delete_at(i)
 end
end
# Code to execute whenever randomizing the item's position
# Sets an array of possible chest numbers
chests = [1, 2, 3, 4, 5]
# Picks a chest number and remove it from the array
$game_variables[A] = chests.sample!
$game_variables[b] = chests.sample!

Replace A and B with variables ID, in which you wish to put the chest number that contains the key/power-up. Then set the events as follows:

Conditional branch: if Variable #A == <chest number>
 Give Item: Key
 Exit Event Processing
Branch end
Conditional branch: if Variable #B == <chest number>
 Give Item: Power-up
 Exit Event Processing
Branch end

Changing the chest number for each event.

 

This way you ensure the same chest number cannot be drawn twice.

Edited by Moonpearl

Share this post


Link to post
Share on other sites
  • 0

Just create a linear array of numbers, the do a random slice.

array = (1..56).to_a
number = array.slice!(rand(array.size))

 

You can simply store the array in a $game_variable or something.

Share this post


Link to post
Share on other sites
  • 0

@Moonpearl: Thanks! I'll give this a try. I'm not completely new to scripting, but I'm not particularly good at it. Would I be able to put that script in a Call Script command in each level, as the levels will have different numbers of chests in them? I'm assuming that when I later want to add spells, I would add

 

$game_variables[C] = chests.sample

 

to the end of the script?

 

@ForeverZer0: I'm not great with scripting. How does slicing work? I can't seem to find a solid reference explaining the term.

 

Thanks for the help!

Share this post


Link to post
Share on other sites
  • 0

@Moonpearl: Thanks! I'll give this a try. I'm not completely new to scripting, but I'm not particularly good at it. Would I be able to put that script in a Call Script command in each level, as the levels will have different numbers of chests in them?

Absolutely, except for the Array#sample method definition stuff which should be put inside the script editor.

 

I'm assuming that when I later want to add spells, I would add

 

$game_variables[C] = chests.sample

Exactly. As long as you make a new array each time, you can sample it as many times as you like.

 

@ForeverZer0: I'm not great with scripting. How does slicing work? I can't seem to find a solid reference explaining the term.

 

Thanks for the help!

ForeverZer0's suggestion is a different solution, maybe a more elegant one, which does exactly the same as my sampling (that is, pick an element from the array at random, then delete it from the array). The reason I use the sample method is that it's supposed to be included in Ruby, only RMXP's Ruby version is too old for that. So what I do adding a sample method is merely catch up with modern versions of Ruby.

Edited by Moonpearl

Share this post


Link to post
Share on other sites
  • 0

The "sample" method wasn't added until version 1.9(.1?). If it was available, it would be the easiest solution, but being that is osn't readily available, I personally would choose the "slice" method instead of extending the Array class. Sample could be used for other things, so both ways are good.

 

As for your question, "slice" basically just takes an element from an array using its index and returns it, pretty much what you do when you reference an array element using array[iNDEX]. It does have a little more functionality than that for taking multiple elements, etc, but in this case, the most handy thing is that it has a destructive form of the method (slice!). This means that it actually modifies the original array when it is called. It is a Ruby convention using an exclamation point in a method name means it is destructive, and it will usually, if not always have a form that does the same thing but doesn't modify the original. Some examples are "compact" and "compact", "sort" and "sort!", etc.

 

For more about the slice method, check out this link.

http://ruby-doc.org/core-1.8.7/Array.html

 

Its some documentation for Ruby 1.8.7, which is not much newer than the RMXP version of Ruby, so most things that are there will work in RGSS. Enterbrain did trim down much of Ruby and removed some classes before compiling, but Array and Enumerable were left alone, just some of the less used classes got the axe.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...