generalized gene structure via serialization

This commit is contained in:
StochasticMouse 2024-10-08 22:14:20 +02:00
parent c772d18e71
commit eeddae8e5d
3 changed files with 79 additions and 41 deletions

View File

@ -130,7 +130,7 @@ local function apiary_node_timer(pos,elapsed)
src_time = src_time + el src_time = src_time + el
if can_live then --chance to drop honeycomb if can_live then --chance to drop honeycomb
local drops = forestry_bees.calculate_drop(monarchlist[1]:get_meta():get_string("active_gene")) local drops = forestry_bees.calculate_drop(minetest.deserialize(monarchlist[1]:get_meta():get_string("genes"))["type_gene"][1])
if (not (next(drops) == nil)) and inv:get_size("dst") - forestry_bees.stacks_in_inv(inv,"dst") >= #drops then if (not (next(drops) == nil)) and inv:get_size("dst") - forestry_bees.stacks_in_inv(inv,"dst") >= #drops then
for _,drop in pairs(drops) do for _,drop in pairs(drops) do
inv:add_item("dst",drop) inv:add_item("dst",drop)

View File

@ -1,7 +1,18 @@
function forestry_bees.Bee(bee_type,active_gene,inactive_gene) --function forestry_bees.Bee(bee_type,active_type_gene,inactive_type_gene,active_fertility_gene,inactive_fertility_gene)
local itemstack = ItemStack({name = forestry_bees.bee_name(bee_type,active_gene)}) --local itemstack = ItemStack({name = forestry_bees.bee_name(bee_type,active_type_gene)})
itemstack:get_meta():set_string("active_gene",active_gene) --itemstack:get_meta():set_string("active_type_gene",active_type_gene)
itemstack:get_meta():set_string("inactive_gene",inactive_gene) --itemstack:get_meta():set_string("inactive_type_gene",inactive_type_gene)
--itemstack:get_meta():set_string("active_fertility_gene",active_fertility_gene)
--itemstack:get_meta():set_string("inactive_fertility_gene",inactive_fertility_gene)
--return itemstack
--end
function forestry_bees.Bee(bee_type,genes)
local itemstack = ItemStack({name = forestry_bees.bee_name(bee_type,genes["type_gene"][1])}) --the "1" is cuz the table genes["type_gene"] has 2 entries: active and inactive
itemstack:get_meta():set_string("genes", minetest.serialize(genes))
--for gene_type,gene in pairs(genes) do
-- itemstack:get_meta():set_string(gene_type,gene)
--end
return itemstack return itemstack
end end
@ -16,8 +27,8 @@ function forestry_bees.calculate_drop(bee_type) --later we will take as input al
return out_table return out_table
end end
function forestry_bees.bee_name(bee_type,active_gene) function forestry_bees.bee_name(bee_type,active_type_gene)
return "forestry_bees:"..active_gene.."_"..bee_type return "forestry_bees:"..active_type_gene.."_"..bee_type
end end
function forestry_bees.stacks_in_inv(inv,listname) function forestry_bees.stacks_in_inv(inv,listname)
@ -32,18 +43,30 @@ function forestry_bees.stacks_in_inv(inv,listname)
end end
function forestry_bees.breed_princess_drone(princess,drone) function forestry_bees.breed_princess_drone(princess,drone)
local princess_meta = princess:get_meta() --local princess_meta = princess:get_meta()
local drone_meta = drone:get_meta() local princess_genes = minetest.deserialize(princess:get_meta():get_string("genes")) --princess_meta["genes"]
local queen = forestry_bees.Bee("queen", --local drone_meta = drone:get_meta()
princess_meta:get_string("active_gene"), local drone_genes = minetest.deserialize(drone:get_meta():get_string("genes"))
princess_meta:get_string("inactive_gene")) local queen = forestry_bees.Bee("queen",princess_genes)
local queen_meta = queen:get_meta() local queen_meta = queen:get_meta()
queen_meta:set_string("drone_active_gene",drone_meta:get_string("active_gene")) queen_meta:set_string("drone_genes",minetest.serialize(drone_genes))
queen_meta:set_string("drone_inactive_gene",drone_meta:get_string("inactive_gene"))
return queen return queen
end end
local function final_gene(type1,type2) local function final_gene(gene1,gene2)
local output = {}
--randomly choose if the genes are 1,2 or 2,1
if math.random(2)==2 then
output[1] = gene1
output[2] = gene2
else
output[1] = gene2
output[2] = gene1
end
return output
end
local function mutation(type1,type2)
local out_table1 = {} local out_table1 = {}
local out_table2 = {} local out_table2 = {}
--check every possible mutation to see if we may obtain it --check every possible mutation to see if we may obtain it
@ -59,16 +82,9 @@ local function final_gene(type1,type2)
end end
end end
end end
--if we got no mutations then the eligible out_types are the input_types
output = {} local output = final_gene(type1,type2)
--randomly choose if the genes are 1,2 or 2,1
if math.random(2)==2 then
output[1] = type1
output[2] = type2
else
output[1] = type2
output[2] = type1
end
if next(out_table1) then --if a mutation accurred in gene 1 if next(out_table1) then --if a mutation accurred in gene 1
output[1] = out_table1[math.random(#out_table1)] output[1] = out_table1[math.random(#out_table1)]
end end
@ -80,21 +96,43 @@ local function final_gene(type1,type2)
return output return output
end end
local function choose_genes(genes)
--from the table "genes" we for each entry randomly choose 1,2 and keep that gene
--returning a table
local output = {}
for key,gene_pair in pairs(genes) do
output[key] = gene_pair[math.random(2)]
end
return output
end
local function output_genes(mother_genes,father_genes)
local mother_chosen_genes = choose_genes(mother_genes)
local father_chosen_genes = choose_genes(father_genes)
local genes = {}
for key,_ in pairs(mother_chosen_genes) do
if key == "type_gene" then
genes[key] = mutation(mother_chosen_genes[key], father_chosen_genes[key])
else
genes[key] = final_gene(mother_chosen_genes[key], father_chosen_genes[key])
end
end
return genes
end
function forestry_bees.apiary_result(queen) function forestry_bees.apiary_result(queen)
--given a queen calculates the correct princess + drone output --given a queen calculates the correct princess + drone output
local meta = queen:get_meta() local meta = queen:get_meta()
local mother_genes = {meta:get_string("active_gene"),meta:get_string("inactive_gene")} local mother_genes = minetest.deserialize(meta:get_string("genes"))
local father_genes = {meta:get_string("drone_active_gene"),meta:get_string("drone_inactive_gene")} local father_genes = minetest.deserialize(meta:get_string("drone_genes"))
local mother_chosen_gene = mother_genes[math.random(#mother_genes)] local genes = output_genes(mother_genes,father_genes)
local father_chosen_gene = father_genes[math.random(#father_genes)] --local genes = final_gene(mother_chosen_gene, father_chosen_gene)
local genes = final_gene(mother_chosen_gene, father_chosen_gene) local princess = forestry_bees.Bee("princess", genes)
local princess = forestry_bees.Bee("princess", genes[1], genes[2])
local dronelist = {} local dronelist = {}
for i=1,4 do --in future bees will have fertility and this number should change, so a little bit of futureproofing local fertility = mother_genes["fertility"][1]
mother_chosen_gene = mother_genes[math.random(#mother_genes)] for i=1,fertility do
father_chosen_gene = father_genes[math.random(#father_genes)] local genes = output_genes(mother_genes,father_genes)
local genes = final_gene(mother_chosen_gene, father_chosen_gene) local drone = forestry_bees.Bee("drone", genes)
local drone = forestry_bees.Bee("drone", genes[1], genes[2])
table.insert(dronelist, drone) table.insert(dronelist, drone)
end end
return princess, dronelist return princess, dronelist

View File

@ -9,7 +9,7 @@ end
local function printbeestats(itemstack, user, pointed_thing) local function printbeestats(itemstack, user, pointed_thing)
local meta = itemstack:get_meta() local meta = itemstack:get_meta()
local name = itemstack:get_name() local name = itemstack:get_name()
minetest.chat_send_player(user:get_player_name(), "Name:"..string.sub(string.match(name, ":.*"),2)..", Active:"..meta:get_string("active_gene")..", Inactive:"..meta:get_string("inactive_gene")) minetest.chat_send_player(user:get_player_name(), "Name:"..string.sub(string.match(name, ":.*"),2)..", Active:"..minetest.deserialize(meta:get_string("genes"))["type_gene"][1]..", Inactive:"..minetest.deserialize(meta:get_string("genes"))["type_gene"][2])
end end
local function register_bee(name, color1, color2) local function register_bee(name, color1, color2)
@ -55,8 +55,8 @@ minetest.register_node("forestry_bees:forest_beehive", {
drop = { drop = {
max_items = 3, max_items = 3,
items = { items = {
{tool_groups = {"scoop_tool"}, rarity = 2, items = {forestry_bees.Bee("princess","forest","forest")}}, {tool_groups = {"scoop_tool"}, rarity = 2, items = {forestry_bees.Bee("princess", {type_gene = {"forest","forest"}, fertility = {2,2}})}},
{tool_groups = {"scoop_tool"}, rarity = 2, items = {forestry_bees.Bee("drone","forest","forest")}}, {tool_groups = {"scoop_tool"}, rarity = 2, items = {forestry_bees.Bee("drone", {type_gene = {"forest","forest"}, fertility = {2,2}})}},
{tool_groups = {"scoop_tool"}, rarity = 2, items = {"forestry_bees:honey_comb"}} {tool_groups = {"scoop_tool"}, rarity = 2, items = {"forestry_bees:honey_comb"}}
} }
} }
@ -77,8 +77,8 @@ minetest.register_node("forestry_bees:meadow_beehive", {
drop = { drop = {
max_items = 3, max_items = 3,
items = { items = {
{tool_groups = {"scoop_tool"}, rarity = 2, items = {forestry_bees.Bee("princess","meadow","meadow")}}, {tool_groups = {"scoop_tool"}, rarity = 2, items = {forestry_bees.Bee("princess", {type_gene = {"meadow","meadow"}, fertility = {3,3}})}},
{tool_groups = {"scoop_tool"}, rarity = 2, items = {forestry_bees.Bee("drone","meadow","meadow")}}, {tool_groups = {"scoop_tool"}, rarity = 2, items = {forestry_bees.Bee("drone", {type_gene = {"meadow","meadow"}, fertility = {3,3}})}},
{tool_groups = {"scoop_tool"}, rarity = 2, items = {"forestry_bees:honey_comb"}} {tool_groups = {"scoop_tool"}, rarity = 2, items = {"forestry_bees:honey_comb"}}
} }
} }