Skip to content

Commit

Permalink
Start a Lua mathx module to hold round, shuffle, random, and a few ot…
Browse files Browse the repository at this point in the history
…her things
  • Loading branch information
CelticMinstrel committed Mar 23, 2021
1 parent 7c95e9d commit dc86c43
Show file tree
Hide file tree
Showing 9 changed files with 237 additions and 151 deletions.
99 changes: 99 additions & 0 deletions data/lua/core/mathx.lua
@@ -0,0 +1,99 @@
--[========[Additional mathematical functions]========]
print("Loading mathx module...")

function mathx.random_choice(possible_values, random_func)
random_func = random_func or mathx.random
assert(type(possible_values) == "table" or type(possible_values) == "string",
string.format("mathx.random_choice expects a string or table as parameter, got %s instead",
type(possible_values)))

local items = {}
local num_choices = 0

if type(possible_values) == "string" then
-- split on commas
for word in possible_values:split() do
-- does the word contain two dots? If yes, that's a range
local dots_start, dots_end = word:find("%.%.")
if dots_start then
-- split on the dots if so and cast to numbers
local low = tonumber(word:sub(1, dots_start-1))
local high = tonumber(word:sub(dots_end+1))
-- perhaps someone passed a string as part of the range, intercept the issue
if not (low and high) then
wesnoth.message("Malformed range: " .. word)
table.insert(items, word)
num_choices = num_choices + 1
else
if low > high then
-- low is greater than high, swap them
low, high = high, low
end

-- if both ends represent the same number, then just use that number
if low == high then
table.insert(items, low)
num_choices = num_choices + 1
else
-- insert a table representing the range
table.insert(items, {low, high})
-- how many items does the range contain? Increase difference by 1 because we include both ends
num_choices = num_choices + (high - low) + 1
end
end
else
-- handle as a string
table.insert(items, word)
num_choices = num_choices + 1
end
end
else
num_choices = #possible_values
items = possible_values
-- We need to parse ranges separately anyway
for i, val in ipairs(possible_values) do
if type(val) == "table" then
assert(#val == 2 and type(val[1]) == "number" and type(val[2]) == "number", "Malformed range for helper.rand")
if val[1] > val[2] then
val = {val[2], val[1]}
end
num_choices = num_choices + (val[2] - val[1])
end
end
end

local idx = random_func(1, num_choices)

for i, item in ipairs(items) do
if type(item) == "table" then -- that's a range
local elems = item[2] - item[1] + 1 -- amount of elements in the range, both ends included
if elems >= idx then
return item[1] + elems - idx
else
idx = idx - elems
end
else -- that's a single element
idx = idx - 1
if idx == 0 then
return item
end
end
end

return nil
end

function mathx.shuffle(t, random_func)
random_func = random_func or mathx.random
-- since tables are passed by reference, this is an in-place shuffle
-- it uses the Fisher-Yates algorithm, also known as Knuth shuffle
assert(type(t) == "table", string.format("mathx.shuffle expects a table as parameter, got %s instead", type(t)))
local length = #t
for index = length, 2, -1 do
local random = random_func(1, index)
t[index], t[random] = t[random], t[index]
end
end

wesnoth.random = wesnoth.deprecate_api('wesnoth.random', 'mathx.random', 1, nil, mathx.random)
wesnoth.get_time_stamp = wesnoth.deprecate_api('wesnoth.get_time_stamp', 'mathx.current_timestamp', 1, nil, mathx.current_timestamp)
111 changes: 3 additions & 108 deletions data/lua/helper.lua
Expand Up @@ -86,114 +86,6 @@ function helper.adjacent_tiles(x, y, with_borders)
end
end

function helper.rand (possible_values, random_func)
random_func = random_func or wesnoth.random
assert(type(possible_values) == "table" or type(possible_values) == "string",
string.format("helper.rand expects a string or table as parameter, got %s instead",
type(possible_values)))

local items = {}
local num_choices = 0

if type(possible_values) == "string" then
-- split on commas
for word in possible_values:gmatch("[^,]+") do
-- does the word contain two dots? If yes, that's a range
local dots_start, dots_end = word:find("%.%.")
if dots_start then
-- split on the dots if so and cast as numbers
local low = tonumber(word:sub(1, dots_start-1))
local high = tonumber(word:sub(dots_end+1))
-- perhaps someone passed a string as part of the range, intercept the issue
if not (low and high) then
wesnoth.message("Malformed range: " .. possible_values)
table.insert(items, word)
num_choices = num_choices + 1
else
if low > high then
-- low is greater than high, swap them
low, high = high, low
end

-- if both ends represent the same number, then just use that number
if low == high then
table.insert(items, low)
num_choices = num_choices + 1
else
-- insert a table representing the range
table.insert(items, {low, high})
-- how many items does the range contain? Increase difference by 1 because we include both ends
num_choices = num_choices + (high - low) + 1
end
end
else
-- handle as a string
table.insert(items, word)
num_choices = num_choices + 1
end
end
else
num_choices = #possible_values
items = possible_values
-- We need to parse ranges separately anyway
for i, val in ipairs(possible_values) do
if type(val) == "table" then
assert(#val == 2 and type(val[1]) == "number" and type(val[2]) == "number", "Malformed range for helper.rand")
if val[1] > val[2] then
val = {val[2], val[1]}
end
num_choices = num_choices + (val[2] - val[1])
end
end
end

local idx = random_func(1, num_choices)

for i, item in ipairs(items) do
if type(item) == "table" then -- that's a range
local elems = item[2] - item[1] + 1 -- amount of elements in the range, both ends included
if elems >= idx then
return item[1] + elems - idx
else
idx = idx - elems
end
else -- that's a single element
idx = idx - 1
if idx == 0 then
return item
end
end
end

return nil
end

function helper.round( number )
-- code converted from util.hpp, round_portable function
-- round half away from zero method
if number >= 0 then
number = math.floor( number + 0.5 )
else
number = math.ceil ( number - 0.5 )
end

return number
end

function helper.shuffle( t, random_func )
random_func = random_func or wesnoth.random
-- since tables are passed by reference, this is an in-place shuffle
-- it uses the Fisher-Yates algorithm, also known as Knuth shuffle
assert(
type( t ) == "table",
string.format( "helper.shuffle expects a table as parameter, got %s instead", type( t ) ) )
local length = #t
for index = length, 2, -1 do
local random = random_func( 1, index )
t[index], t[random] = t[random], t[index]
end
end

-- Compatibility and deprecations
helper.distance_between = wesnoth.deprecate_api('helper.distance_between', 'wesnoth.map.distance_between', 1, nil, wesnoth.map.distance_between)
helper.get_child = wesnoth.deprecate_api('helper.get_child', 'wml.get_child', 1, nil, wml.get_child)
Expand All @@ -217,5 +109,8 @@ helper.shallow_parsed = wesnoth.deprecate_api('helper.shallow_parsed', 'wml.shal
helper.set_wml_var_metatable = wesnoth.deprecate_api('helper.set_wml_var_metatable', 'wml.variable.proxy', 2, nil, helper.set_wml_var_metatable)
helper.set_wml_tag_metatable = wesnoth.deprecate_api('helper.set_wml_tag_metatable', 'wml.tag', 2, nil, helper.set_wml_tag_metatable)
helper.get_user_choice = wesnoth.deprecate_api('helper.get_user_choice', 'gui.get_user_choice', 1, nil, gui.get_user_choice)
helper.rand = wesnoth.deprecate_api('helper.rand', 'mathx.random_choice', 1, nil, mathx.random_choice)
helper.round = wesnoth.deprecate_api('helper.round', 'mathx.round', 1, nil, mathx.round)
helper.shuffle = wesnoth.deprecate_api('helper.shuffle', 'mathx.shuffle', 1, nil, mathx.shuffle)

return helper
8 changes: 8 additions & 0 deletions projectfiles/VC16/wesnoth.vcxproj
Expand Up @@ -2674,6 +2674,13 @@
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Test_Debug|x64'">$(IntDir)Scripting\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Test_Release|x64'">$(IntDir)Scripting\</ObjectFileName>
</ClCompile>
<ClCompile Include="..\..\src\scripting\lua_mathx.cpp">
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)Scripting\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='ReleaseDEBUG|x64'">$(IntDir)Scripting\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)Scripting\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Test_Debug|x64'">$(IntDir)Scripting\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Test_Release|x64'">$(IntDir)Scripting\</ObjectFileName>
</ClCompile>
<ClCompile Include="..\..\src\scripting\lua_kernel_base.cpp">
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)Scripting\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='ReleaseDEBUG|x64'">$(IntDir)Scripting\</ObjectFileName>
Expand Down Expand Up @@ -4007,6 +4014,7 @@
<ClInclude Include="..\..\src\scripting\lua_gui2.hpp" />
<ClInclude Include="..\..\src\scripting\lua_wml.hpp" />
<ClInclude Include="..\..\src\scripting\lua_stringx.hpp" />
<ClInclude Include="..\..\src\scripting\lua_mathx.hpp" />
<ClInclude Include="..\..\src\scripting\lua_kernel_base.hpp" />
<ClInclude Include="..\..\src\scripting\lua_map_location_ops.hpp" />
<ClInclude Include="..\..\src\scripting\lua_pathfind_cost_calculator.hpp" />
Expand Down
6 changes: 6 additions & 0 deletions projectfiles/VC16/wesnoth.vcxproj.filters
Expand Up @@ -1557,6 +1557,9 @@
<ClCompile Include="..\..\src\scripting\lua_stringx.cpp">
<Filter>Scripting</Filter>
</ClCompile>
<ClCompile Include="..\..\src\scripting\lua_mathx.cpp">
<Filter>Scripting</Filter>
</ClCompile>
<ClCompile Include="..\..\src\scripting\lua_widget.cpp">
<Filter>Scripting</Filter>
</ClCompile>
Expand Down Expand Up @@ -3048,6 +3051,9 @@
<ClInclude Include="..\..\src\scripting\lua_stringx.hpp">
<Filter>Scripting</Filter>
</ClInclude>
<ClInclude Include="..\..\src\scripting\lua_mathx.hpp">
<Filter>Scripting</Filter>
</ClInclude>
<ClInclude Include="..\..\src\scripting\lua_widget.hpp">
<Filter>Scripting</Filter>
</ClInclude>
Expand Down
Expand Up @@ -1034,6 +1034,7 @@
91E3570A1CACC9B200774252 /* playcampaign.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EC2F600B1A048E210018C9D6 /* playcampaign.cpp */; };
91E3570B1CACC9B200774252 /* singleplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EC2F600C1A048E220018C9D6 /* singleplayer.cpp */; };
91ECD5D21BA11A5200B25CF1 /* unit_creator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91ECD5D01BA11A5200B25CF1 /* unit_creator.cpp */; };
91F8E12E260A25E2002312BA /* lua_mathx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91F8E12D260A25E1002312BA /* lua_mathx.cpp */; };
91FAC70A1C7FBC3400DAB2C3 /* lua_formula_bridge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91FAC7091C7FBC2C00DAB2C3 /* lua_formula_bridge.cpp */; };
91FBBAD81CB6BC3F00470BFE /* filesystem_sdl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91FBBAD71CB6BC3F00470BFE /* filesystem_sdl.cpp */; };
91FBBADB1CB6D1B700470BFE /* markov_generator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91FBBAD91CB6D1B700470BFE /* markov_generator.cpp */; };
Expand Down Expand Up @@ -2207,6 +2208,8 @@
91ECD5D11BA11A5200B25CF1 /* unit_creator.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = unit_creator.hpp; sourceTree = "<group>"; };
91EF6BFC1C9E22E400E2A733 /* const_clone.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = const_clone.hpp; sourceTree = "<group>"; };
91EF6C001C9E22E400E2A733 /* reference_counter.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = reference_counter.hpp; sourceTree = "<group>"; };
91F8E12C260A25E1002312BA /* lua_mathx.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = lua_mathx.hpp; sourceTree = "<group>"; };
91F8E12D260A25E1002312BA /* lua_mathx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_mathx.cpp; sourceTree = "<group>"; };
91FAC7081C7F931900DAB2C3 /* lua_formula_bridge.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = lua_formula_bridge.hpp; sourceTree = "<group>"; };
91FAC7091C7FBC2C00DAB2C3 /* lua_formula_bridge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_formula_bridge.cpp; sourceTree = "<group>"; };
91FBBAD71CB6BC3F00470BFE /* filesystem_sdl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = filesystem_sdl.cpp; sourceTree = "<group>"; };
Expand Down Expand Up @@ -4630,9 +4633,12 @@
91B621E91B76BB1500B00E0F /* lua_kernel_base.hpp */,
ECA4A6791A1EC319006BCCF2 /* lua_map_location_ops.cpp */,
91B621EA1B76BB1800B00E0F /* lua_map_location_ops.hpp */,
91F8E12D260A25E1002312BA /* lua_mathx.cpp */,
91F8E12C260A25E1002312BA /* lua_mathx.hpp */,
9190B73A1CA0554900B0EF66 /* lua_pathfind_cost_calculator.hpp */,
ECFB61831DA0A0C50055D3F8 /* lua_preferences.cpp */,
ECFB61841DA0A0C50055D3F8 /* lua_preferences.hpp */,
46E2D99525022D46003D99F3 /* lua_ptr.hpp */,
ECC2FFF91A51A00900023AF4 /* lua_race.cpp */,
91B621EB1B76BB1D00B00E0F /* lua_race.hpp */,
ECA4A67A1A1EC319006BCCF2 /* lua_rng.cpp */,
Expand All @@ -4650,7 +4656,6 @@
91B621EE1B76BB2C00B00E0F /* lua_unit_type.hpp */,
9193FC801D5C2CF7004F6C07 /* lua_unit.cpp */,
9193FC811D5C2CF8004F6C07 /* lua_unit.hpp */,
46E2D99525022D46003D99F3 /* lua_ptr.hpp */,
46E2D98D25022BF5003D99F3 /* lua_widget_attributes.cpp */,
46E2D98A25022BF4003D99F3 /* lua_widget_attributes.hpp */,
46E2D98E25022BF5003D99F3 /* lua_widget_methods.cpp */,
Expand Down Expand Up @@ -5290,6 +5295,7 @@
46685C9D219D518B0009CFFE /* schema_validator.cpp in Sources */,
ECF0F80123A09929004A2011 /* lua_stringx.cpp in Sources */,
46F92DE72174F6A400602C1C /* game_delete.cpp in Sources */,
91F8E12E260A25E2002312BA /* lua_mathx.cpp in Sources */,
6295C3C4150FC9750077D8C5 /* map_fragment.cpp in Sources */,
EC4E3B1D19B2D7AD0049CBD7 /* map_generator.cpp in Sources */,
B5599B2C0EC62181008DD061 /* label.cpp in Sources */,
Expand Down
1 change: 1 addition & 0 deletions source_lists/wesnoth
Expand Up @@ -321,6 +321,7 @@ scripting/lua_formula_bridge.cpp
scripting/lua_gui2.cpp
scripting/lua_wml.cpp
scripting/lua_stringx.cpp
scripting/lua_mathx.cpp
scripting/lua_kernel_base.cpp
scripting/lua_map_location_ops.cpp
scripting/lua_preferences.cpp
Expand Down

0 comments on commit dc86c43

Please sign in to comment.