ctf_map: Re-implement random map selection in a better way (#498)
This commit is contained in:
parent
28a9444ecb
commit
a37df650d6
1 changed files with 78 additions and 15 deletions
|
@ -206,6 +206,72 @@ local function load_map_meta(idx, dirname, meta)
|
||||||
return map
|
return map
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- List of shuffled map indices, used in conjunction with random map selection
|
||||||
|
local shuffled_order = {}
|
||||||
|
local shuffled_idx
|
||||||
|
|
||||||
|
math.randomseed(os.time())
|
||||||
|
|
||||||
|
-- Fisher-Yates shuffling algorithm, used for shuffling map selection order
|
||||||
|
-- Adapted from snippet provided in https://stackoverflow.com/a/35574006
|
||||||
|
local function shuffle_maps(idx_to_avoid)
|
||||||
|
-- Reset shuffled_idx
|
||||||
|
shuffled_idx = 1
|
||||||
|
|
||||||
|
-- Create table of ordered indices
|
||||||
|
shuffled_order = {}
|
||||||
|
for i = 1, #ctf_map.available_maps, 1 do
|
||||||
|
shuffled_order[i] = i
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Shuffle table
|
||||||
|
for i = #ctf_map.available_maps, 1, -1 do
|
||||||
|
local j = math.random(i)
|
||||||
|
shuffled_order[i], shuffled_order[j] = shuffled_order[j], shuffled_order[i]
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Prevent the last map of the previous cycle from becoming the first in the next cycle
|
||||||
|
if shuffled_order[1] == idx_to_avoid then
|
||||||
|
local k = math.random(#ctf_map.available_maps - 1)
|
||||||
|
shuffled_order[1], shuffled_order[k + 1] = shuffled_order[k + 1], shuffled_order[1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local random_selection_mode = false
|
||||||
|
local function select_map()
|
||||||
|
local idx
|
||||||
|
|
||||||
|
-- If next_idx exists, return the same
|
||||||
|
if ctf_map.next_idx then
|
||||||
|
idx = ctf_map.next_idx
|
||||||
|
ctf_map.next_idx = nil
|
||||||
|
return idx
|
||||||
|
end
|
||||||
|
|
||||||
|
if random_selection_mode then
|
||||||
|
-- Get the real idx stored in table shuffled_order at index [shuffled_idx]
|
||||||
|
idx = shuffled_order[shuffled_idx]
|
||||||
|
shuffled_idx = shuffled_idx + 1
|
||||||
|
|
||||||
|
-- If shuffled_idx overflows, re-shuffle map selection order
|
||||||
|
if shuffled_idx > #ctf_map.available_maps then
|
||||||
|
shuffle_maps(shuffled_order[#ctf_map.available_maps])
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Choose next map index, but don't select the same one again
|
||||||
|
if ctf_map.map then
|
||||||
|
idx = math.random(#ctf_map.available_maps - 1)
|
||||||
|
if idx >= ctf_map.map.idx then
|
||||||
|
idx = idx + 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
idx = math.random(#ctf_map.available_maps)
|
||||||
|
end
|
||||||
|
ctf_map.next_idx = (idx % #ctf_map.available_maps) + 1
|
||||||
|
end
|
||||||
|
return idx
|
||||||
|
end
|
||||||
|
|
||||||
local function load_maps()
|
local function load_maps()
|
||||||
local idx = 1
|
local idx = 1
|
||||||
ctf_map.available_maps = {}
|
ctf_map.available_maps = {}
|
||||||
|
@ -225,9 +291,19 @@ local function load_maps()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if not next(ctf_map.available_maps) then
|
if not next(ctf_map.available_maps) then
|
||||||
error("No maps found in directory " .. ctf_map.mapdir)
|
error("No maps found in directory " .. ctf_map.mapdir)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Determine map selection mode depending on number of available maps
|
||||||
|
-- If random, then shuffle the map selection order
|
||||||
|
random_selection_mode = #ctf_map.available_maps >=
|
||||||
|
(tonumber(minetest.settings:get("ctf_map.random_selection_threshold")) or 10)
|
||||||
|
if random_selection_mode then
|
||||||
|
shuffle_maps()
|
||||||
|
end
|
||||||
|
|
||||||
return ctf_map.available_maps
|
return ctf_map.available_maps
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -295,21 +371,8 @@ end
|
||||||
ctf_match.register_on_new_match(function()
|
ctf_match.register_on_new_match(function()
|
||||||
minetest.clear_objects({ mode = "quick" })
|
minetest.clear_objects({ mode = "quick" })
|
||||||
|
|
||||||
-- Choose next map index, but don't select the same one again
|
-- Select map
|
||||||
local idx
|
local idx = select_map()
|
||||||
if ctf_map.next_idx then
|
|
||||||
idx = ctf_map.next_idx
|
|
||||||
elseif ctf_map.map then
|
|
||||||
idx = math.random(#ctf_map.available_maps - 1)
|
|
||||||
if idx >= ctf_map.map.idx then
|
|
||||||
idx = idx + 1
|
|
||||||
end
|
|
||||||
else
|
|
||||||
idx = math.random(#ctf_map.available_maps)
|
|
||||||
end
|
|
||||||
ctf_map.next_idx = (idx % #ctf_map.available_maps) + 1
|
|
||||||
|
|
||||||
-- Load meta data
|
|
||||||
ctf_map.map = ctf_map.available_maps[idx]
|
ctf_map.map = ctf_map.available_maps[idx]
|
||||||
ctf_map.map.idx = idx
|
ctf_map.map.idx = idx
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue