From eeddae8e5d3d2e39b80585f9f15504f74750ab2f Mon Sep 17 00:00:00 2001 From: StochasticMouse Date: Tue, 8 Oct 2024 22:14:20 +0200 Subject: [PATCH] generalized gene structure via serialization --- forestry_bees/apiary.lua | 2 +- forestry_bees/helper.lua | 108 +++++++++++++++++++++++++------------ forestry_bees/register.lua | 10 ++-- 3 files changed, 79 insertions(+), 41 deletions(-) diff --git a/forestry_bees/apiary.lua b/forestry_bees/apiary.lua index 9b5869d..ea63930 100644 --- a/forestry_bees/apiary.lua +++ b/forestry_bees/apiary.lua @@ -130,7 +130,7 @@ local function apiary_node_timer(pos,elapsed) src_time = src_time + el 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 for _,drop in pairs(drops) do inv:add_item("dst",drop) diff --git a/forestry_bees/helper.lua b/forestry_bees/helper.lua index 2b6e2ab..1889c05 100644 --- a/forestry_bees/helper.lua +++ b/forestry_bees/helper.lua @@ -1,7 +1,18 @@ -function forestry_bees.Bee(bee_type,active_gene,inactive_gene) - local itemstack = ItemStack({name = forestry_bees.bee_name(bee_type,active_gene)}) - itemstack:get_meta():set_string("active_gene",active_gene) - itemstack:get_meta():set_string("inactive_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_type_gene)}) + --itemstack:get_meta():set_string("active_type_gene",active_type_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 end @@ -16,8 +27,8 @@ function forestry_bees.calculate_drop(bee_type) --later we will take as input al return out_table end -function forestry_bees.bee_name(bee_type,active_gene) - return "forestry_bees:"..active_gene.."_"..bee_type +function forestry_bees.bee_name(bee_type,active_type_gene) + return "forestry_bees:"..active_type_gene.."_"..bee_type end function forestry_bees.stacks_in_inv(inv,listname) @@ -32,18 +43,30 @@ function forestry_bees.stacks_in_inv(inv,listname) end function forestry_bees.breed_princess_drone(princess,drone) - local princess_meta = princess:get_meta() - local drone_meta = drone:get_meta() - local queen = forestry_bees.Bee("queen", - princess_meta:get_string("active_gene"), - princess_meta:get_string("inactive_gene")) + --local princess_meta = princess:get_meta() + local princess_genes = minetest.deserialize(princess:get_meta():get_string("genes")) --princess_meta["genes"] + --local drone_meta = drone:get_meta() + local drone_genes = minetest.deserialize(drone:get_meta():get_string("genes")) + local queen = forestry_bees.Bee("queen",princess_genes) local queen_meta = queen:get_meta() - queen_meta:set_string("drone_active_gene",drone_meta:get_string("active_gene")) - queen_meta:set_string("drone_inactive_gene",drone_meta:get_string("inactive_gene")) + queen_meta:set_string("drone_genes",minetest.serialize(drone_genes)) return queen 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_table2 = {} --check every possible mutation to see if we may obtain it @@ -59,16 +82,9 @@ local function final_gene(type1,type2) end end end - --if we got no mutations then the eligible out_types are the input_types - output = {} - --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 + + local output = final_gene(type1,type2) + if next(out_table1) then --if a mutation accurred in gene 1 output[1] = out_table1[math.random(#out_table1)] end @@ -80,21 +96,43 @@ local function final_gene(type1,type2) return output 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) --given a queen calculates the correct princess + drone output local meta = queen:get_meta() - local mother_genes = {meta:get_string("active_gene"),meta:get_string("inactive_gene")} - local father_genes = {meta:get_string("drone_active_gene"),meta:get_string("drone_inactive_gene")} - local mother_chosen_gene = mother_genes[math.random(#mother_genes)] - local father_chosen_gene = father_genes[math.random(#father_genes)] - local genes = final_gene(mother_chosen_gene, father_chosen_gene) - local princess = forestry_bees.Bee("princess", genes[1], genes[2]) + local mother_genes = minetest.deserialize(meta:get_string("genes")) + local father_genes = minetest.deserialize(meta:get_string("drone_genes")) + local genes = output_genes(mother_genes,father_genes) + --local genes = final_gene(mother_chosen_gene, father_chosen_gene) + local princess = forestry_bees.Bee("princess", genes) local dronelist = {} - for i=1,4 do --in future bees will have fertility and this number should change, so a little bit of futureproofing - mother_chosen_gene = mother_genes[math.random(#mother_genes)] - father_chosen_gene = father_genes[math.random(#father_genes)] - local genes = final_gene(mother_chosen_gene, father_chosen_gene) - local drone = forestry_bees.Bee("drone", genes[1], genes[2]) + local fertility = mother_genes["fertility"][1] + for i=1,fertility do + local genes = output_genes(mother_genes,father_genes) + local drone = forestry_bees.Bee("drone", genes) table.insert(dronelist, drone) end return princess, dronelist diff --git a/forestry_bees/register.lua b/forestry_bees/register.lua index ca5ab0c..1cefd4d 100644 --- a/forestry_bees/register.lua +++ b/forestry_bees/register.lua @@ -9,7 +9,7 @@ end local function printbeestats(itemstack, user, pointed_thing) local meta = itemstack:get_meta() 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 local function register_bee(name, color1, color2) @@ -55,8 +55,8 @@ minetest.register_node("forestry_bees:forest_beehive", { drop = { max_items = 3, items = { - {tool_groups = {"scoop_tool"}, rarity = 2, items = {forestry_bees.Bee("princess","forest","forest")}}, - {tool_groups = {"scoop_tool"}, rarity = 2, items = {forestry_bees.Bee("drone","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", {type_gene = {"forest","forest"}, fertility = {2,2}})}}, {tool_groups = {"scoop_tool"}, rarity = 2, items = {"forestry_bees:honey_comb"}} } } @@ -77,8 +77,8 @@ minetest.register_node("forestry_bees:meadow_beehive", { drop = { max_items = 3, items = { - {tool_groups = {"scoop_tool"}, rarity = 2, items = {forestry_bees.Bee("princess","meadow","meadow")}}, - {tool_groups = {"scoop_tool"}, rarity = 2, items = {forestry_bees.Bee("drone","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", {type_gene = {"meadow","meadow"}, fertility = {3,3}})}}, {tool_groups = {"scoop_tool"}, rarity = 2, items = {"forestry_bees:honey_comb"}} } }