I am designing a weighted random spawner system that will pick an item from the table based on weights. My question is related to the table design. Obviously the table below is a dictionary in which I have keys with duplicate names. This is because the name is the object that it is, a car. But each car has some attributes that are important. I wont normally be indexing this table for data inside, so I don’t need to pick which car by name, I just pick one at random based on the weights.
Would this be considered bad table design? A dictionary with duplicate key names?
table = {
car = {
weight = 1,
color = "red",
value = 100
},
car = {
weight = 5,
color = "blue",
value = 50
},
car = {
weight = 10,
color = "green",
value = 10
}
}
Though I don’t know which part of your post you’re referring to, you are mostly correct, and your code example would be a good solution if that’s how he wants to access it.
I don’t think he can even create a table the way he’s doing it though, I think all of those ‘car’ keys will overwrite each other and he’ll end up with only a single entry.
The only thing I can suggest that could change, is implement names of the vehicles into your table. As @jvdad2222 mentioned before, if you want to get a specific car, you are going to have to do something like this:
car1 = table[1]
I recommend naming your car tables to something like these:
BlueCar = {
weight = 5,
color = "blue",
value = 50
},
RedCar = {
weight = 5,
color = "blue",
value = 50
},
or
["Blue car"] = {
weight = 5,
color = "blue",
value = 50
},
["Red car"] = {
weight = 5,
color = "blue",
value = 50
},
I don’t see anything wrong with your table, what you are doing is perfectly fine(assuming it’s an example table)! @Ethanthegrand14
Variable naming is just personal preference.
A table with duplicate keys is cannot exist, keys must be unique. Since the cars are unique, and the purpose of this table is to assign non-unique weights to those unique cars, I would use the cars objects as keys and the weights as values.
local weightedCars = {
[{
color = "red",
value = 100
}] = 1;
[{
color = "blue",
value = 50
}] = 5;
[{
color = "green",
value = 10
}] = 10;
}
Now picking a random weighted car would look like this:
local function randomWeightedCar()
local totalWeight = 0
local seed
for _, weight in pairs(weightedCars) do
totalWeight += weight
end
seed = math.random() * totalWeight
for car, weight in pairs(weightedCars) do
if seed <= weight then
return car
end
seed -= weight
end
end
local function test()
local colorsPicked = {}
for i = 1, 1600 do
local color = randomWeightedCar().color
if not colorsPicked[color] then
colorsPicked[color] = 0
end
colorsPicked[color] += 1
end
for color, count in pairs(colorsPicked) do
print("picked a car with color", color, count, "times")
end
end
test()
-- output
20:59:13.136 picked a car with color red 103 times - Server - Script:49
20:59:13.136 picked a car with color blue 492 times - Server - Script:49
20:59:13.137 picked a car with color green 1005 times - Server - Script:49