1
0
mirror of https://github.com/Refactorio/RedMew.git synced 2025-03-17 21:08:08 +02:00
* Add tests for map poll winner.

* Add option to overwrite map poll mod pack
This commit is contained in:
grilledham 2023-05-06 15:44:19 +01:00 committed by GitHub
parent eae8e6f078
commit 6a07a97fbf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 243 additions and 82 deletions

View File

@ -16,7 +16,8 @@ Public.game_types = game_types
local memory = {
mod_pack_text = '',
restarting = nil,
use_map_poll_result = nil
use_map_poll_result = nil,
overwrite_mod_pack = nil
}
local start_game_data = {
type = game_types.scenario,
@ -207,6 +208,14 @@ function Public.set_use_map_poll_result_option(state)
memory.use_map_poll_result = state
end
function Public.get_overwrite_modpack_option()
return memory.overwrite_mod_pack
end
function Public.set_overwrite_modpack_option(state)
memory.overwrite_mod_pack = state
end
local main_frame_name = Gui.uid_name()
local close_button_name = Gui.uid_name()
local scenario_radio_button_name = Gui.uid_name()
@ -215,6 +224,7 @@ local name_textfield_name = Gui.uid_name()
local set_mod_pack_checkbox_name = Gui.uid_name()
local mod_pack_name_textfield_name = Gui.uid_name()
local use_map_poll_result_checkbox_name = Gui.uid_name()
local overwrite_mod_pack_checkbox_name = Gui.uid_name()
Public._main_frame_name = main_frame_name
Public._close_button_name = close_button_name
@ -224,6 +234,7 @@ Public._name_textfield_name = name_textfield_name
Public._set_mod_pack_checkbox_name = set_mod_pack_checkbox_name
Public._mod_pack_name_textfield_name = mod_pack_name_textfield_name
Public._use_map_poll_result_checkbox_name = use_map_poll_result_checkbox_name
Public._overwrite_mod_pack_checkbox_name = overwrite_mod_pack_checkbox_name
local function value_of_type_or_deafult(value, value_type, default)
if type(value) == value_type then
@ -345,6 +356,15 @@ local function draw_main_frame(player)
}
end
if memory.overwrite_mod_pack ~= nil then
main_frame.add {
type = 'checkbox',
name = overwrite_mod_pack_checkbox_name,
caption = 'Overwrite map poll mod pack',
state = memory.overwrite_mod_pack
}
end
local bottom_flow = main_frame.add {
type = 'flow',
direction = 'horizontal'
@ -404,6 +424,11 @@ Gui.on_checked_state_changed(use_map_poll_result_checkbox_name, function(event)
memory.use_map_poll_result = use_map_poll_result_checkbox.state
end)
Gui.on_checked_state_changed(overwrite_mod_pack_checkbox_name, function(event)
local overwrite_mod_pack_checkbox = event.element
memory.overwrite_mod_pack = overwrite_mod_pack_checkbox.state
end)
Gui.on_text_changed(mod_pack_name_textfield_name, function(event)
local text = event.element.text
start_game_data.mod_pack = text

View File

@ -1,6 +1,7 @@
local Poll = require 'features.gui.poll'
local Global = require 'utils.global'
local Event = require 'utils.event'
local PollUtils = require 'utils.poll_utils'
local Server = require 'features.server'
local Ranks = require 'resources.ranks'
@ -16,63 +17,78 @@ end)
local normal_mod_pack = 'danger_ore23'
local bobs_mod_pack = 'danger_ore_bobs2'
local maps = {{
name = 'danger-ore-deadlock-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'terraforming (default)'
}, {
name = 'danger-ore-one-direction-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'one direction (line)'
}, {
name = 'danger-ore-3way-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = '3-way (T shape)'
}, {
name = 'danger-ore-chessboard-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'chessboard (random squares)'
}, {
name = 'danger-ore-chessboard-uniform-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'chessboard uniform (fixed squares)'
}, {
name = 'danger-ore-circles-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'circles (ore rings)'
}, {
name = 'danger-ore-gradient-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'gradient (smooth ore ratios)'
}, {
name = 'danger-ore-split-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'split (4x sectors)'
}, {
name = 'danger-ore-hub-spiral-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'hub-spiral (with void)'
}, {
name = 'danger-ore-spiral-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'spiral (without void)'
}, {
name = 'danger-ore-landfill-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'landfill (all tiles)'
}, {
name = 'danger-ore-patches-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'patches (ore islands in coal)'
}, {
name = 'danger-ore-xmas-tree-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'xmas tree (triangle)'
}, {
name = 'danger-bobs-ores',
mod_pack = bobs_mod_pack,
display_name = 'bob\'s mod (default map)'
}}
local maps = {
{
name = 'danger-ore-deadlock-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'terraforming (default)'
},
{
name = 'danger-ore-one-direction-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'one direction (line)'
},
{
name = 'danger-ore-3way-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = '3-way (T shape)'
},
{
name = 'danger-ore-chessboard-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'chessboard (random squares)'
},
{
name = 'danger-ore-chessboard-uniform-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'chessboard uniform (fixed squares)'
},
{
name = 'danger-ore-circles-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'circles (ore rings)'
},
{
name = 'danger-ore-gradient-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'gradient (smooth ore ratios)'
},
{
name = 'danger-ore-split-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'split (4x sectors)'
},
{
name = 'danger-ore-hub-spiral-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'hub-spiral (with void)'
},
{
name = 'danger-ore-spiral-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'spiral (without void)'
},
{
name = 'danger-ore-landfill-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'landfill (all tiles)'
},
{
name = 'danger-ore-patches-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'patches (ore islands in coal)'
},
{
name = 'danger-ore-xmas-tree-beltboxes-ore-only',
mod_pack = normal_mod_pack,
display_name = 'xmas tree (triangle)'
},
{
name = 'danger-bobs-ores',
mod_pack = bobs_mod_pack,
display_name = 'bob\'s mod (default map)'
}
}
Event.add(Server.events.on_server_started, function()
if data.created then
@ -107,32 +123,11 @@ function Public.get_next_map()
end
local answers = poll_data.answers
local vote_counts = {}
for i, answer_data in pairs(answers) do
vote_counts[i] = answer_data.voted_count
end
local max_count = 0
for i = 1, #vote_counts do
local count = vote_counts[i] or 0
if count > max_count then
max_count = count
end
end
if max_count == 0 then
local chosen_index = PollUtils.get_poll_winner(answers)
if chosen_index == nil then
return nil
end
local max_indexes = {}
for i = 1, #vote_counts do
local count = vote_counts[i] or 0
if count == max_count then
max_indexes[#max_indexes + 1] = i
end
end
local chosen_index = max_indexes[math.random(#max_indexes)]
return maps[chosen_index]
end

View File

@ -19,6 +19,7 @@ return function(config)
Restart.set_start_game_data({type = Restart.game_types.scenario, name = config.scenario_name or 'danger-ore-next'})
Restart.set_use_map_poll_result_option(true)
Restart.set_overwrite_modpack_option(false)
local function can_restart(player)
if player.admin then
@ -202,7 +203,14 @@ return function(config)
return
end
Restart.set_start_game_data({type = Restart.game_types.scenario, name = map_data.name, mod_pack = map_data.mod_pack})
local mod_pack_to_use
if Restart.get_overwrite_modpack_option() then
mod_pack_to_use = Restart.get_start_game_data().mod_pack
else
mod_pack_to_use = map_data.mod_pack
end
Restart.set_start_game_data({type = Restart.game_types.scenario, name = map_data.name, mod_pack = mod_pack_to_use})
end
Restart.register(can_restart, restart_callback, restart_requested)

37
utils/poll_utils.lua Normal file
View File

@ -0,0 +1,37 @@
local Public = {}
--- Returns the index for the answer with the most votes.
-- If there is a tie one index from the ties is picked randomly usign rng
-- Returns nil if passed in zero answers.
-- rng defaults to math.random if not provided.
function Public.get_poll_winner(answers, rng)
local rand = rng or math.random
local vote_counts = {}
for i, answer_data in pairs(answers) do
vote_counts[i] = answer_data.voted_count or 0
end
local max_count = -math.huge
for i = 1, #vote_counts do
local count = vote_counts[i]
if count > max_count then
max_count = count
end
end
if max_count == -math.huge then
return nil
end
local max_indexes = {}
for i = 1, #vote_counts do
local count = vote_counts[i]
if count == max_count then
max_indexes[#max_indexes + 1] = i
end
end
return max_indexes[rand(#max_indexes)]
end
return Public

View File

@ -0,0 +1,96 @@
local Declare = require 'utils.test.declare'
local PollUtils = require 'utils.poll_utils'
local Assert = require 'utils.test.assert'
Declare.module({
'utils',
'poll_utils',
'get_poll_winner'
}, function()
Declare.test('picks most voted answer', function()
-- Arrange
local answers = {
{
voted_count = 0
},
{
voted_count = 3
},
{
voted_count = 1
}
}
-- Act
local actual = PollUtils.get_poll_winner(answers)
-- Assert
Assert.equal(2, actual)
end)
Declare.test('picks from tied answers', function()
-- Arrange
local answers = {
{
voted_count = 0
},
{
voted_count = 3
},
{
voted_count = 1
},
{
voted_count = 3
}
}
local rng = function(count)
Assert.equal(2, count)
return 2 -- pick last.
end
-- Act
local actual = PollUtils.get_poll_winner(answers, rng)
-- Assert
Assert.equal(4, actual)
end)
Declare.test('picks from tied answers all zero', function()
-- Arrange
local answers = {
{
voted_count = 0
},
{
voted_count = 0
},
{
voted_count = 0
}
}
local rng = function(count)
Assert.equal(3, count)
return 2 -- pick middle.
end
-- Act
local actual = PollUtils.get_poll_winner(answers, rng)
-- Assert
Assert.equal(2, actual)
end)
Declare.test('returns nil when no answers', function()
-- Arrange
local answers = {}
-- Act
local actual = PollUtils.get_poll_winner(answers)
-- Assert
Assert.equal(nil, actual)
end)
end)