144 lines
2.9 KiB
Lua
144 lines
2.9 KiB
Lua
|
|
local S = namegen.S
|
|
|
|
|
|
|
|
-- <name of the generator>: <graph data>
|
|
namegen.graphs = {}
|
|
|
|
namegen.load = function( generator_name , graph_file )
|
|
if not graph_file then
|
|
graph_file = namegen.path .. "/graphs/" .. generator_name .. ".json"
|
|
end
|
|
|
|
local file = io.open( graph_file , "r" )
|
|
|
|
if not file then return false end
|
|
|
|
local str = file:read( "*a" )
|
|
local graph_data = minetest.parse_json( str )
|
|
namegen.graphs[ generator_name ] = graph_data
|
|
return true
|
|
end
|
|
|
|
|
|
|
|
namegen.generate = function( generator_name , can_load )
|
|
local graph_data = namegen.graphs[ generator_name ]
|
|
|
|
if not graph_data then
|
|
if can_load then
|
|
namegen.load( generator_name )
|
|
if not namegen.load( generator_name ) then
|
|
--error( "Generator " .. generator_name .. " not found (can_load=true)." )
|
|
return nil
|
|
end
|
|
graph_data = namegen.graphs[ generator_name ]
|
|
else
|
|
--error( "Generator " .. generator_name .. " not found." )
|
|
return nil
|
|
end
|
|
end
|
|
|
|
return namegen.generate_from_graph( graph_data )
|
|
end
|
|
|
|
|
|
|
|
function table_path( src , path_array )
|
|
local ptr = src
|
|
|
|
for i = 1 , #path_array , 1 do
|
|
ptr = ptr[ path_array[ i ] ]
|
|
end
|
|
|
|
return ptr
|
|
end
|
|
|
|
function table_has_at_least( src , count )
|
|
for k,v in pairs( src ) do
|
|
count = count - 1
|
|
if count <= 0 then return true end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
namegen.generate_from_graph = function( data , options )
|
|
local key , leaf , r
|
|
local atomCount = 0
|
|
local graph = data.graph
|
|
|
|
local str = ""
|
|
local chain = {}
|
|
for i = 1 , data.order , 1 do chain[ i ] = "" end
|
|
|
|
while true do
|
|
leaf = table_path( graph , chain )
|
|
if not leaf then
|
|
--error( 'unexpected error, leaf not found...' )
|
|
return nil
|
|
end
|
|
|
|
--if atomCount < data.atomMin and leaf.next[""] and ( table_has_at_least( leaf.next , 2 ) or rebranchCount ) then
|
|
if atomCount < data.atomMin and leaf.next[""] and table_has_at_least( leaf.next , 2 ) then
|
|
|
|
-- missing rebranching code here
|
|
|
|
r = math.random( 1 , leaf.sum - leaf.next[""] )
|
|
|
|
for k,v in pairs( leaf.next ) do
|
|
key = k
|
|
if key ~= "" then
|
|
r = r - leaf.next[ key ]
|
|
if r <= 0 then break end
|
|
end
|
|
end
|
|
|
|
if r > 0 then
|
|
error( "unexpected internal error: 'r' is still positive" )
|
|
return nil
|
|
end
|
|
elseif atomCount >= data.atomMax and leaf.next[""] then
|
|
-- We want to exit and it is possible
|
|
key = "" ;
|
|
else
|
|
-- Normal case
|
|
r = math.random( 1 , leaf.sum )
|
|
|
|
for k,v in pairs( leaf.next ) do
|
|
key = k
|
|
r = r - leaf.next[ key ] ;
|
|
if r <= 0 then break end
|
|
end
|
|
|
|
if r > 0 then
|
|
--error( "unexpected internal error: 'r' is still positive" )
|
|
return nil
|
|
end
|
|
end
|
|
|
|
if str == "" then
|
|
str = str .. key
|
|
else
|
|
str = str .. data.sampleJoint .. key
|
|
end
|
|
|
|
if key == "" then break end
|
|
|
|
atomCount = atomCount + 1
|
|
|
|
--if rebranchCount and atomCount >= data.order then rebranchCount = 0 end
|
|
|
|
table.insert( chain , 1 , key )
|
|
table.remove( chain )
|
|
end
|
|
|
|
if data.sampleAppend then
|
|
str = str .. data.sampleAppend
|
|
end
|
|
|
|
return str
|
|
end
|
|
|