Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Randomly select a key from a table in Lua

Tags:

lua

lua-table

I want to randomly populate a grid in Lua using a list of possible items, which is defined as follows:

  -- Items
  items = {}
  items.glass = {}
  items.glass.color = colors.blue
  items.brick = {}
  items.brick.color = colors.red
  items.grass = {}
  items.grass.color = colors.green

So the keys of the table are "glass", "brick" and "grass".

How do I randomly select one of these keys if they are not addressable by a numeric index?

like image 641
mydoghasworms Avatar asked Mar 15 '26 11:03

mydoghasworms


2 Answers

Well, I kind of got a workaround, but I would be open to any better suggestions.

The first solution consists of having a secondary table which serves as an index to the first table:

item_index = {"grass", "brick", "glass"}

Then I can randomly store a key of this table (board is a matrix that stores the value of the random entry in item_index):

local index = math.random(1,3)
board[i][j] = item_index[index]

After which I can get details of the original list as follows:

items[board[y][x]].color

The second solution, which I have decided on, involves adding the defined elements as array elements to the original table:

  -- Items
  items = {}
  items.glass = {}
  items.glass.color = colors.blue
  table.insert(items, items.glass)   --- Add item as array item
  items.brick = {}
  items.brick.color = colors.red
  table.insert(items, items.brick)   --- Add item as array item
  items.grass = {}
  items.grass.color = colors.green
  table.insert(items, items.grass)   --- Add item as array item

Then, I can address the elements directly using an index:

  local index = math.random(1,3)
  board[i][j] = items[index]

And they can be retrieved directly without the need for an additional lookup:

  board[y][x].color
like image 157
mydoghasworms Avatar answered Mar 18 '26 04:03

mydoghasworms


Although your second method gives concise syntax, I think the first is easier to maintain. I can't test here, but I think you can get the best of both, won't this work:

local items = {
    glass = {
        color = colors.blue,
    },
    brick = {
        color = colors.red,
    },
    grass = {
         color = colors.green,
    },
}
local item_index = {"grass", "brick", "glass"}
local index = math.random(1,3)
board[i][j] = items[item_index[index]]
print('color:', board[i][j].color)
like image 26
Oliver Avatar answered Mar 18 '26 05:03

Oliver



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!