我想使用可能的项目列表在Lua中随机填充网格,其定义如下:
-- Items
items = {}
items.glass = {}
items.glass.color = colors.blue
items.brick = {}
items.brick.color = colors.red
items.grass = {}
items.grass.color = colors.green
所以桌子上的钥匙是“玻璃”,“砖头”和“草”。
如果这些键无法通过数字索引寻址,我如何随机选择其中一个键?
答案 0 :(得分:1)
嗯,我有一种解决方法,但我会接受任何更好的建议。
第一个解决方案包括一个辅助表,它作为第一个表的索引:
item_index = {"grass", "brick", "glass"}
然后我可以随机存储该表的一个键(board
是一个矩阵,用于存储item_index
中随机条目的值:
local index = math.random(1,3)
board[i][j] = item_index[index]
之后我可以按如下方式获取原始列表的详细信息:
items[board[y][x]].color
我决定使用的第二个解决方案涉及将已定义的元素作为数组元素添加到原始表中:
-- 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
然后,我可以使用索引直接处理元素:
local index = math.random(1,3)
board[i][j] = items[index]
可以直接检索它们而无需额外查找:
board[y][x].color
答案 1 :(得分:0)
虽然你的第二种方法提供了简洁的语法,但我认为第一种方法更容易维护。我无法在这里进行测试,但我认为你可以充分利用这两方面的优势,赢得这项工作:
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)
答案 2 :(得分:0)
如果您的桌子不是太大而且您可以随意中断。此方法假定您知道表中的条目数(如果表具有非数字键,则不等于#table值)。
所以找到表的长度,然后在random(1, length(table))
处中断,如下:
local items = {} ....
items.grass.color = colors.green
local numitems = 0 -- find the size of the table
for k,v in pairs(items) do
numitems = numitems + 1
end
local randval = math.random(1, numitems) -- get a random point
local randentry
local count = 0
for k,v in pairs(items) do
count = count + 1
if(count == randentry) then
randentry = {key = k, val = v}
break
end
end
货物:您不必跟踪钥匙。它可以是任何表格,您不需要维护它。 坏的和丑陋的:它是O(n) - 两个线性通道。所以,如果你有大桌子,它根本不是理想的。
答案 3 :(得分:0)
以上答案假设你知道所有的密钥是什么,这不是我今天早些时候能够做到的。我的解决方案:
function table.randFrom( t )
local choice = "F"
local n = 0
for i, o in pairs(t) do
n = n + 1
if math.random() < (1/n) then
choice = o
end
end
return choice
end
说明:我们不能使用table.getn(t)来获取表的大小,因此我们随时跟踪它。第一项将有1/1 = 1的机会被选中;第二个1/2 = 0.5,依此类推......
如果展开N个项目,则第N个项目将有1 / N的机会被选中。第一项将有1 - (1/2) - (1/3) - (1/4) - ...... - (1 / N)不被替换的机会(记住,它总是首先被选中) 。该系列收敛于1 - (N-1)/ N = 1 / N,等于最后一个项目的选择机会。
因此,数组中的每个项具有相同的被选择的可能性;它是随机的。这也是在O(n)时间运行,这不是很好,但如果你不知道你的索引名称,它是你能做的最好的。