0

Please look at the next code, Lua.

randomNumber = {
  new = function(self,o)
  o = o or {}
  setmetatable(o, self)
  self.__index = self
  return o
  end,

  math.randomseed(os.time()),
  
  getNum = math.random()
}

for i = 1, 10 do
  x = randomNumber:new()
  print(x.getNum)
end

The output results are as follows.

0.13782639400248
0.13782639400248
0.13782639400248
0.13782639400248
0.13782639400248
0.13782639400248
0.13782639400248
0.13782639400248
0.13782639400248
0.13782639400248

I want to get 10 different numbers. Can someone help me? Thank you in advance.

2 Answers2

0

Let's take a look at your table constructor

randomNumber = {
  new = function(self,o)  -- this assigns a function to randomNumber["new"]
  o = o or {}             -- that will return a new instance of your class
  setmetatable(o, self)
  self.__index = self
  return o
  end,

  math.randomseed(os.time()), -- this assigns the first of two random seed components
                              -- returned by math.randomseed to randomNumber[1]
  
  getNum = math.random()    -- this assings a random number [0,1) to randomNumber["getNum"]
}

In the loop

for i = 1, 10 do
  x = randomNumber:new()
  print(x.getNum)
end

You create a new instance named x of randomNumber 10 times. You then print x.getNum.

x.getNum is a nil value so Lua will check wether x has a metatable with a __index field. __index refers to randomNumber so Lua will print randomNumber.getNum which is the random number [0,1) which has not changed since we constructed randomNumber.

You need to call math.random every time you want a new random number.

If you want each instance of randomNumber to be constructed with a random number you need to assign o.rn = math.random() in your new function and either access it via x.rn later or add a function getNum to randomNumber.

getNum = function (self) return self.rn end`

so you can print(x:getNum())

I'm not sure if this is more than a exercise with metatables. But having a dedicated class that just holds a single number doesn't make too much sense to me. Just use a number value.

Piglet
  • 27,501
  • 3
  • 20
  • 43
0

The main problem with your code is simply...

In a very fast Lua loop os.time() is not fast enough to set a good random seed.

You have to use something that is faster, like...

-- Lua 5.3 - 5.4
for i = 1, 10 do
 math.randomseed(math.random(math.mininteger, math.maxinteger)) -- Set seed before print()
 print('Seed: ' .. math.randomseed(math.random(math.mininteger, math.maxinteger)), '\nRandom: ' .. math.random(math.maxinteger)) -- Set seed in print()
 math.randomseed(math.random(math.mininteger, math.maxinteger)) -- Set seed after print()
end

That puts out something like...

Seed: -634325252416746990   
Random: 5554602367968798340
Seed: 574322306421972413    
Random: 3317370212892010822
Seed: -5465512503977683870  
Random: 6616070635043877067
Seed: -2566820481734265082  
Random: 2581377472505137533
Seed: -8408106760854456996  
Random: 708876515734960246
Seed: 5641371185711405705   
Random: 4259990225803106481
Seed: -3172432877848732304  
Random: 5472223279668970440
Seed: 5842301042132325387   
Random: 6912957407189525897
Seed: 2126448976574029213   
Random: 6156943198274398962
Seed: 4832369017575479065   
Random: 6054703131408226582

Lua 5.1

-- Lua 5.1
math.randomseed(math.random(os.time()))

for i = 1, 10 do
 math.randomseed(math.random(-99999999, 999999999)) -- Set seed before print()
 print('Random: ' .. tostring(math.random(-999999999, 999999999)))                       
 math.randomseed(math.random(-999999999, 999999999)) -- Set seed after print()
end
koyaanisqatsi
  • 2,585
  • 2
  • 8
  • 15