Skip to content

Instantly share code, notes, and snippets.

@zenlor
Created November 1, 2013 16:30
Show Gist options
  • Select an option

  • Save zenlor/7267981 to your computer and use it in GitHub Desktop.

Select an option

Save zenlor/7267981 to your computer and use it in GitHub Desktop.
-- BeeAnalyzer 4.3
-- Original code by Direwolf20
-- Hotfix 1 by Mandydax
-- Hotfix 2 by Mikeyhun/MaaadMike
-- 4.0 Major overhaul by MacLeopold
-- Breeds bees with best attributes in this order:
-- fertility, speed, nocturnal, flyer, cave, temperature tolerance, humidity tolerance
-- other attributes are ignored (lifespawn, flowers, effect and territory)
-- Can specify multiple target species to help with keeping to the correct line
-- 4.1 Minor fix for FTB Unleashed, no more inventory module or suckSneaky needed
-- 4.2 Major overhaul 2
-- Added magic bees, removed old bees
-- Added species graph
-- Changed targeting to target parent species
-- Changed breeding to keep stock of good bees to prevent losing attributes
-- Added logging
-- Changed scoring to look for best combination of princess and drone
-- 4.3 Updated targeting
-- attribute scoring for same species tie-breaking -----------------------------
scoresFertility = {
[1] = 0.1,
[2] = 0.2,
[3] = 0.3,
[4] = 0.4
}
scoresSpeed = {
["0.3"] = 0.01,
["0.6"] = 0.02,
["0.8"] = 0.03,
["1"] = 0.04,
["1.2"] = 0.05,
["1.4"] = 0.06,
["1.7"] = 0.07
}
scoresAttrib = {
diurnal =0.004,
nocturnal =0.002,
tolerantFlyer=0.001,
caveDwelling =0.0001
}
scoresTolerance = {
["NONE"] = 0.00000,
["UP_1"] = 0.00001,
["UP_2"] = 0.00002,
["UP_3"] = 0.00003,
["DOWN_1"] = 0.00001,
["DOWN_2"] = 0.00002,
["DOWN_3"] = 0.00003,
["BOTH_1"] = 0.00002,
["BOTH_2"] = 0.00004,
["BOTH_3"] = 0.00006
}
-- the bee graph ---------------------------------------------------------------
bees = {}
function addParent(parent, offspring)
if bees[parent] then
bees[parent].mutateTo[offspring] = true
else
bees[parent] = {
--name = parent,
score = nil,
mutateTo = {[offspring]=true},
mutateFrom = {}
}
end
end
function addOffspring(offspring, parentss)
if bees[offspring] then
for i, parents in ipairs(parentss) do
table.insert(bees[offspring].mutateFrom, parents)
end
else
bees[offspring] = {
score = nil,
mutateTo = {},
mutateFrom = parentss
}
end
for i, parents in ipairs(parentss) do
for i, parent in ipairs(parents) do
addParent(parent, offspring)
end
end
end
-- score bees that have no parent combinations as 1
-- iteratively find the next bee up the line and increase the score
function scoreBees()
-- find all bees with no mutateFrom data
local beeCount = 0
local beeScore = 1
for name, beeData in pairs(bees) do
if #beeData.mutateFrom == 0 then
beeData.score = beeScore
else
beeCount = beeCount + 1
end
end
while beeCount > 0 do
beeScore = beeScore * 4
-- find all bees where all parent combos are scored
for name, beeData in pairs(bees) do
if not beeData.score then
local scoreBee = true
for i, beeParents in ipairs(beeData.mutateFrom) do
local parent1 = bees[beeParents[1]]
local parent2 = bees[beeParents[2]]
if not parent1.score
or parent1.score == beeScore
or not parent2.score
or parent2.score == beeScore then
scoreBee = false
break
end
end
if scoreBee then
beeData.score = beeScore
beeCount = beeCount - 1
end
end
end
end
end
-- produce combinations from 1 or 2 lists
function choose(list, list2)
local newList = {}
if list2 then
for i = 1, #list2 do
for j = 1, #list do
if list[j] ~= list[i] then
table.insert(newList, {list[j], list2[i]})
end
end
end
else
for i = 1, #list do
for j = i, #list do
if list[i] ~= list[j] then
table.insert(newList, {list[i], list[j]})
end
end
end
end
return newList
end
-- Forestry Bees ---------------------------------------------------------------
-- Agrarian Branch
addOffspring("Rural", {{"Diligent", "Meadows"}})
addOffspring("Farmed", {{"Rural", "Cultivated"}})
-- Apis Branch
addOffspring("Common", choose({"Forest", "Meadows", "Modest", "Marbled", "Tropical", "Wintry", "Marshy", "Water", "Rocky", "Embittered", "Unusual", "Mystical", "Sorcerous", "Attuned"}))
addOffspring("Cultivated", choose({"Common"}, {"Forest", "Meadows", "Modest", "Marbled", "Tropical", "Wintry", "Marshy", "Water", "Rocky", "Embittered", "Unusual", "Mystical", "Sorcerous", "Attuned"}))
-- Austere Branch
addOffspring("Frugal", {{"Sinister", "Modest"}, {"Fiendish", "Modest"}})
addOffspring("Austere", {{"Frugal", "Modest"}})
-- Beastly Branch
addOffspring("Jaded", {{"Ender", "Relic"}})
-- End Branch
addOffspring("Spectral", {{"Hermitic", "Ender"}})
addOffspring("Phantasmal", {{"Spectral", "Ender"}})
-- Festive Branch
addOffspring("Celebratory", {{"Austere", "Excited"}})
addOffspring("Hazardous", {{"Austere", "Desolate"}})
addOffspring("Leporine", {{"Meadows", "Forest"}})
addOffspring("Merry", {{"Wintry", "Forest"}})
addOffspring("Tipsy", {{"Wintry", "Meadows"}})
-- Frozen Branch
addOffspring("Icy", {{"Industrious", "Wintry"}})
addOffspring("Glacial", {{"Icy", "Wintry"}})
addOffspring("Frigid", {{"Diligent", "Wintry"}})
addOffspring("Absolute", {{"Frigid", "Ocean"}})
-- Heroic Branch
addOffspring("Heroic", {{"Steadfast", "Valiant"}})
-- Industrious Branch
addOffspring("Diligent", {{"Cultivated", "Common"}})
addOffspring("Unweary", {{"Diligent", "Cultivated"}})
addOffspring("Industrious", {{"Unweary", "Diligent"}})
-- Infernal Branch
addOffspring("Sinister", {{"Cultivated", "Modest"}, {"Cultivated", "Tropical"}})
addOffspring("Fiendish", {{"Sinister", "Cultivated"}, {"Sinister", "Modest"}, {"Sinister", "Tropical"}})
addOffspring("Demonic", {{"Fiendish", "Sinister"}})
-- Monastic Branch
addOffspring("Secluded", {{"Monastic", "Austere"}})
addOffspring("Hermitic", {{"Secluded", "Monastic"}})
-- Noble Branch
addOffspring("Noble", {{"Cultivated", "Common"}})
addOffspring("Majestic", {{"Noble", "Cultivated"}})
addOffspring("Imperial", {{"Majestic", "Noble"}})
-- Tropical Branch
addOffspring("Exotic", {{"Austere", "Tropical"}})
addOffspring("Edenic", {{"Exotic", "Tropical"}})
-- Vengeful Branch
addOffspring("Vindictive", {{"Monastic", "Demonic"}})
addOffspring("Vengeful", {{"Vindictive", "Demonic"}, {"Vindictive", "Monastic"}})
addOffspring("Avenging", {{"Vengeful", "Vindictive"}})
-- Extra Bees ------------------------------------------------------------------
-- Agricultural Branch
addOffspring("Bovine", {{"Rural", "Water"}})
addOffspring("Caffeinated", {{"Rural", "Tropical"}})
addOffspring("Citrus", {{"Farmed", "Modest"}})
addOffspring("Fermented", {{"Rural", "Fruity"}})
addOffspring("Minty", {{"Farmed", "Tropical"}})
-- Alloyed Branch
addOffspring("Impregnable", {{"Resilient", "Noble"}})
-- Aquatic Branch
addOffspring("River", {{"Common", "Water"}})
addOffspring("Ocean", {{"Diligent", "Water"}})
addOffspring("Stained", {{"Ocean", "Ebony"}})
-- Barren Branch
addOffspring("Arid", {{"Meadows", "Modest"}})
addOffspring("Barren", {{"Arid", "Common"}})
addOffspring("Desolate", {{"Barren", "Arid"}})
-- Boggy Branch
addOffspring("Damp", {{"Common", "Marshy"}})
addOffspring("Boggy", {{"Damp", "Marshy"}})
addOffspring("Fungal", {{"Boggy", "Damp"}})
-- Caustic Branch
addOffspring("Corrosive", {{"Virulent", "Sticky"}})
addOffspring("Caustic", {{"Corrosive", "Fiendish"}})
addOffspring("Acidic", {{"Caustic", "Corrosive"}})
-- Energetic Branch
addOffspring("Excited", {{"Cultivated", "Valiant"}})
addOffspring("Energetic", {{"Excited", "Valiant"}})
addOffspring("Ecstatic", {{"Energetic", "Excited"}})
-- Fossilized
addOffspring("Fossiled", {{"Primeval", "Growing"}})
addOffspring("Oily", {{"Primeval", "Ocean"}})
addOffspring("Preserved", {{"Primeval", "Boggy"}})
addOffspring("Resinous", {{"Primeval", "Fungal"}})
-- Gemstone Branch
addOffspring("Diamond", {{"Lapis", "Imperial"}})
addOffspring("Emerald", {{"Lapis", "Noble"}})
addOffspring("Ruby", {{"Emerald", "Austere"}})
addOffspring("Sapphire", {{"Emerald", "Ocean"}})
-- Historic Branch
addOffspring("Ancient", {{"Noble", "Diligent"}})
addOffspring("Primeval", {{"Ancient", "Noble"}})
addOffspring("Prehistoric", {{"Primeval", "Majestic"}})
addOffspring("Relic", {{"Prehistoric", "Imperial"}})
-- Hostile Branch
addOffspring("Skeletal", {{"Desolate", "Frugal"}})
addOffspring("Decaying", {{"Desolate", "Modest"}})
addOffspring("Creepy", {{"Desolate", "Austere"}})
-- Metallic Branch
addOffspring("Galvanized", {{"Tarnished", "Cultivated"}})
addOffspring("Invincible", {{"Resilient", "Ender"}})
addOffspring("Lustered", {{"Resilient", "Unweary"}})
-- Nuclear Branch
addOffspring("Unstable", {{"Austere", "Rocky"}})
addOffspring("Nuclear", {{"Unstable", "Rusty"}})
addOffspring("Radioactive", {{"Nuclear", "Glittering"}})
-- Precious Branch
addOffspring("Lapis", {{"Resilient", "Water"}})
addOffspring("Glittering", {{"Corroded", "Imperial"}})
addOffspring("Shining", {{"Rusty", "Imperial"}})
addOffspring("Valuable", {{"Glittering", "Shining"}})
-- Refined Branch
addOffspring("Distilled", {{"Oily", "Industrious"}})
addOffspring("Refined", {{"Distilled", "Oily"}})
addOffspring("Elastic", {{"Refined", "Resinous"}})
addOffspring("Tarry", {{"Refined", "Fossiled"}})
-- Rocky Branch
addOffspring("Tolerant", {{"Diligent", "Rocky"}})
addOffspring("Robust", {{"Tolerant", "Rocky"}})
addOffspring("Resilient", {{"Robust", "Imperial"}})
-- Rusty Branch
addOffspring("Corroded", {{"Resilient", "Forest"}})
addOffspring("Leaden", {{"Resilient", "Unweary"}})
addOffspring("Rusty", {{"Resilient", "Meadows"}})
addOffspring("Tarnished", {{"Resilient", "Marshy"}})
-- Saccharine Branch
addOffspring("Sweetened", {{"Diligent", "Valiant"}})
addOffspring("Sugary", {{"Sweetened", "Diligent"}})
addOffspring("Fruity", {{"Ripening", "Rural"}})
-- Shadow Branch
addOffspring("Shadowed", {{"Tolerant", "Sinister"}})
addOffspring("Darkened", {{"Shadowed", "Embittered"}})
addOffspring("Abyssmal", {{"Darkened", "Shadowed"}})
-- Virulent Branch
addOffspring("Malicious", {{"Sinister", "Tropical"}})
addOffspring("Infectious", {{"Malicious", "Tropical"}})
addOffspring("Virulent", {{"Infectious", "Malicious"}})
-- Viscous Branch
addOffspring("Viscous", {{"Exotic", "Water"}})
addOffspring("Glutinous", {{"Viscous", "Exotic"}})
addOffspring("Sticky", {{"Glutinous", "Viscous"}})
-- Volcanic Branch
addOffspring("Furious", {{"Sinister", "Embittered"}})
addOffspring("Volcanic", {{"Furious", "Embittered"}})
addOffspring("Glowering", {{"Excited", "Furious"}})
-- Primary Branch
addOffspring("Bleached", {{"Wintry", "Valiant"}})
addOffspring("Ebony", {{"Rocky", "Valiant"}})
addOffspring("Maroon", {{"Forest", "Valiant"}})
addOffspring("Natural", {{"Tropical", "Valiant"}})
addOffspring("Prussian", {{"Water", "Valiant"}})
addOffspring("Saffron", {{"Meadows", "Valiant"}})
addOffspring("Sepia", {{"Marshy", "Valiant"}})
-- Secondary Branch
addOffspring("Amber", {{"Maroon", "Saffron"}})
addOffspring("Azure", {{"Prussian", "Bleached"}})
addOffspring("Indigo", {{"Maroon", "Prussian"}})
addOffspring("Lavender", {{"Maroon", "Bleached"}})
addOffspring("Lime", {{"Natural", "Bleached"}})
addOffspring("Slate", {{"Ebony", "Bleached"}})
addOffspring("Turquoise", {{"Natural", "Prussian"}})
-- Tertiary Branch
addOffspring("Ashen", {{"Slate", "Bleached"}})
addOffspring("Fuchsia", {{"Indigo", "Lavender"}})
-- no branch
addOffspring("Gnawing", {{"Barren", "Forest"}})
addOffspring("Decoposing", {{"Arid", "Common"}, {"Gnawing", "Common"}})
addOffspring("Growing", {{"Diligent", "Forest"}})
addOffspring("Thriving", {{"Growing", "Rural"}})
addOffspring("Blooming", {{"Growing", "Thriving"}})
addOffspring("Ripening", {{"Sugary", "Forest"}})
-- Magic Bees ------------------------------------------------------------------
-- Abominable Branch
addOffspring("Hateful", {{"Eldritch", "Infernal"}})
addOffspring("Spiteful", {{"Hateful", "Infernal"}})
addOffspring("Withering", {{"Demonic", "Spiteful"}})
-- Alchemical Branch
addOffspring("Minium", {{"Eldritch", "Frugal"}})
-- Arcane Branch
addOffspring("Esoteric", {{"Eldritch", "Cultivated"}})
addOffspring("Mysterious", {{"Eldritch", "Esoteric"}})
addOffspring("Arcane", {{"Mysterious", "Esoteric"}})
-- Aware Branch
addOffspring("Ethereal", {{"Arcane", "Supernatural"}})
addOffspring("Aware", {{"Ethereal", "Attuned"}})
addOffspring("Watery", {{"Ethereal", "Supernatural"}})
addOffspring("Windy", {{"Ethereal", "Supernatural"}})
addOffspring("Firey", {{"Ethereal", "Supernatural"}})
addOffspring("Earthen", {{"Ethereal", "Supernatural"}})
-- Essential Branch
addOffspring("Essence", {{"Arcane", "Ethereal"}})
addOffspring("Arkanen", {{"Essence", "Ethereal"}})
addOffspring("Quintessential", {{"Essence", "Arcane"}})
addOffspring("Vortex", {{"Essence", "Skulking"}})
addOffspring("Wight", {{"Ghastly", "Skulking"}})
addOffspring("Luft", {{"Essence", "Windy"}})
addOffspring("Blitz", {{"Luft", "Windy"}})
addOffspring("Wasser", {{"Essence", "Watery"}})
addOffspring("Eis", {{"Wasser", "Watery"}})
addOffspring("Erde", {{"Essence", "Earthen"}})
addOffspring("Staude", {{"Erde", "Earthen"}})
addOffspring("Feuer", {{"Essence", "Firey"}})
addOffspring("Magma", {{"Feuer", "Firey"}})
-- Extrinsic
addOffspring("Nameless", {{"Oblivion", "Ethereal"}})
addOffspring("Abandoned", {{"Nameless", "Oblivion"}})
addOffspring("Forlorn", {{"Abandoned", "Nameless"}})
addOffspring("Draconic", {{"Abandoned", "Imperial"}})
-- Fleshly Branch
addOffspring("Poultry", {{"Skulking", "Common"}})
addOffspring("Beefy", {{"Skulking", "Common"}})
addOffspring("Porcine", {{"Skulking", "Common"}})
-- Gem Branch
addOffspring("Apatine", {{"Rural", "Cuprum"}})
addOffspring("Diamandi", {{"Austere", "Auric"}})
addOffspring("Esmeraldi", {{"Austere", "Argentum"}})
-- Metallic2 Branch
addOffspring("Cuprum", {{"Industrious", "Meadows"}})
addOffspring("Stannum", {{"Industrious", "Forest"}})
addOffspring("Aluminum", {{"Industrious", "Cultivated"}})
addOffspring("Ardite", {{"Industrious", "Infernal"}})
addOffspring("Argentum", {{"Imperial", "Modest"}})
addOffspring("Cobalt", {{"Imperial", "Infernal"}})
addOffspring("Ferrous", {{"Common", "Industrious"}})
addOffspring("Plumbum", {{"Stannum", "Common"}})
addOffspring("Auric", {{"Minium", "Plumbum"}})
addOffspring("Manyullyn", {{"Ardite", "Cobalt"}})
-- Scholarly Branch
addOffspring("Pupil", {{"Arcane", "Monastic"}})
addOffspring("Scholarly", {{"Arcane", "Pupil"}})
addOffspring("Savant", {{"Scholarly", "Pupil"}})
-- Skulking Branch
addOffspring("Skulking", {{"Eldritch", "Modest"}})
addOffspring("Ghastly", {{"Skulking", "Ethereal"}})
addOffspring("Smouldering", {{"Skulking", "Hateful"}})
addOffspring("Spidery", {{"Skulking", "Tropical"}})
-- Soulful Branch
addOffspring("Spirit", {{"Ethereal", "Aware"}, {"Attuned", "Aware"}})
addOffspring("Soul", {{"Spirit", "Aware"}})
-- Supernatural Branch
addOffspring("Charmed", {{"Eldritch", "Cultivated"}})
addOffspring("Enchanted", {{"Eldritch", "Charmed"}})
addOffspring("Supernatural", {{"Enchanted", "Charmed"}})
-- Thaumic Branch
addOffspring("Aqua", {{"Watery", "Watery"}})
addOffspring("Aura", {{"Windy", "Windy"}})
addOffspring("Ignis", {{"Firey", "Firey"}})
addOffspring("Praecantatio", {{"Ethereal", "Ethereal"}})
addOffspring("Solum", {{"Earthen", "Earthen"}})
addOffspring("Stark", choose({"Earthen", "Firey", "Watery", "Windy"}))
addOffspring("Vis", {{"Eldritch", "Ethereal"}})
addOffspring("Flux", {{"Vis", "Demonic"}})
addOffspring("Attractive", {{"Vis", "Flux"}})
addOffspring("Rejuvenating", {{"Vis", "Imperial"}})
addOffspring("Pure", {{"Vis", "Rejuvenating"}})
addOffspring("Batty", {{"Skulking", "Windy"}})
addOffspring("Brainy", {{"Skulking", "Pupil"}})
addOffspring("Wispy", {{"Ethereal", "Ghastly"}})
-- Time Branch
addOffspring("Timely", {{"Ethereal", "Imperial"}})
addOffspring("Lordly", {{"Timely", "Imperial"}})
addOffspring("Doctoral", {{"Lordly", "Timely"}})
-- Veiled Branch
addOffspring("Eldritch", {{"Mystical", "Cultivated"}, {"Sorcerous", "Cultivated"}, {"Unusual", "Cultivated"}, {"Attuned", "Cultivated"}})
scoreBees()
-- logging ---------------------------------------------------------------------
local logFile = fs.open("bee.log", "w")
function log(msg)
msg = msg or ""
logFile.write(tostring(msg))
logFile.flush()
io.write(msg)
end
function logLine(msg)
msg = msg or ""
logFile.write(msg.."\n")
logFile.flush()
io.write(msg.."\n")
end
-- analyzing functions ---------------------------------------------------------
-- Fix for some versions returning bees.species.*
function fixName(name)
return name:gsub("bees%.species%.",""):gsub("^.", string.upper)
end
function clearSystem()
-- orient turtle
while true do
local p = peripheral.wrap("front")
if p and p.isMember then
break
end
turtle.turnRight()
end
-- clear out analyzer
turtle.turnLeft()
while turtle.suckUp() do end
-- clear out beealyzer
turtle.turnRight()
turtle.suck()
-- clear out apiary
turtle.turnRight()
while turtle.suck() do end
end
function getBees()
-- get bees from apiary
log("waiting for bees.")
turtle.select(1)
while not turtle.suck() do
sleep(10)
log(".")
end
log("*")
while turtle.suck() do
log("*")
end
logLine()
end
function countBees()
-- spread dups and fill gaps
local count = 0
for i = 1, 16 do
local slotCount = turtle.getItemCount(i)
if slotCount == 1 then
for j = 1, i-1 do
if turtle.getItemCount(j) == 0 then
turtle.select(i)
turtle.transferTo(j)
break
end
end
count = count + 1
elseif slotCount > 1 then
for j = 2, slotCount do
turtle.select(i)
for k = 1, 16 do
if turtle.getItemCount(k) == 0 then
turtle.transferTo(k, 1)
end
end
end
if turtle.getItemCount(i) > 1 then
turtle.dropDown(turtle.getItemCount(i)-1)
end
end
end
return count
end
function breedBees(princessSlot, droneSlot)
turtle.select(princessSlot)
turtle.drop()
turtle.select(droneSlot)
turtle.drop()
end
function ditchProduct()
print("ditching product...")
turtle.turnLeft()
m = peripheral.wrap("front")
for i = 1, 16 do
if turtle.getItemCount(i) > 0 then
turtle.select(i)
turtle.drop()
if not m.isMember() then
turtle.suck()
turtle.dropDown()
else
turtle.suck()
end
end
end
turtle.turnRight()
end
function scanBees()
log("scanning bees")
turtle.turnLeft()
turtle.turnLeft()
for i = 1, 16 do
if turtle.getItemCount(i) > 0 then
log(".")
turtle.select(i)
turtle.drop()
while not turtle.suckUp() do
sleep(1)
end
end
end
logLine()
turtle.turnRight()
turtle.turnRight()
end
function swapBee(slot1, slot2, freeSlot)
turtle.select(slot1)
turtle.transferTo(freeSlot)
turtle.select(slot2)
turtle.transferTo(slot1)
turtle.select(freeSlot)
turtle.transferTo(slot2)
end
function analyzeBees()
logLine("analyzing bees...")
local freeSlot
local princessSlot
local princessData
local droneData = {}
turtle.turnLeft()
local beealyzer = peripheral.wrap("front")
for i = 1, 16 do
if turtle.getItemCount(i) > 0 then
turtle.select(i)
turtle.drop()
local beeData = beealyzer.analyze()
turtle.suck()
if not beeData["speciesPrimary"] then
print("Bee "..i.." not correctly analyzed")
else
beeData["speciesPrimary"] = fixName(beeData["speciesPrimary"])
beeData["speciesSecondary"] = fixName(beeData["speciesSecondary"])
if beeData["type"] == "princess" then
princessData = beeData
princessSlot = i
else
droneData[i] = beeData
end
end
else
freeSlot = i
end
end
if princessData then
if princessSlot ~= 1 then
swapBee(1, princessSlot, freeSlot)
droneData[princessSlot] = droneData[1]
droneData[1] = nil
princessSlot = 1
end
-- bubble sort drones
print("sorting drones...")
for i = 2, 16 do
if turtle.getItemCount(i) > 0 and droneData[i] then
droneData[i].score = scoreBee(princessData, droneData[i])
for j = i - 1, 2, -1 do
if droneData[j+1].score > droneData[j].score then
swapBee(j+1, j, freeSlot)
droneData[j+1], droneData[j] = droneData[j], droneData[j+1]
end
end
end
end
printHeader()
princessData.slot = 1
printBee(princessData)
for i = 2, 16 do
if droneData[i] then
droneData[i].slot = i
printBee(droneData[i])
end
end
end
logLine()
turtle.turnRight()
return princessData, droneData
end
function scoreBee(princessData, droneData)
local droneSpecies = {droneData["speciesPrimary"], droneData["speciesSecondary"]}
-- check for untargeted species
if not bees[droneSpecies[1]].targeted or not bees[droneSpecies[2]].targeted then
return 0
end
local princessSpecies = {princessData["speciesPrimary"], princessData["speciesSecondary"]}
local max = math.max
local score
local maxScore = 0
for _, combo in ipairs({{princessSpecies[1], droneSpecies[1]}
,{princessSpecies[1], droneSpecies[2]}
,{princessSpecies[2], droneSpecies[1]}
,{princessSpecies[2], droneSpecies[2]}}) do
-- find maximum score for each combo
score = max(bees[combo[1]].score, bees[combo[2]].score)
for name, beeData in pairs(bees) do
if beeData.targeted then
for i, parents in ipairs(beeData.mutateFrom) do
if combo[1] == parents[1] and combo[2] == parents[2]
or combo[2] == parents[1] and combo[1] == parents[2] then
if beeData.score > score then
--log(" "..name:sub(1,3).."="..tostring(beeData.score))
end
-- deduct 1 to make potential scores less than base scores
score = max(score, beeData.score - 1)
end
end
end
end
maxScore = maxScore + score
end
-- add one for each combination that results in the maximum score
score = maxScore
-- score attributes
score = score + max(scoresFertility[droneData["fertility"]], scoresFertility[princessData["fertility"]])
score = score + math.min(scoresSpeed[tostring(droneData["speed"])], scoresSpeed[tostring(princessData["speed"])])
if droneData["diurnal"] or princessData["diurnal"] then score = score + scoresAttrib["diurnal"] end
if droneData["nocturnal"] or princessData["nocturnal"] then score = score + scoresAttrib["nocturnal"] end
if droneData["tolerantFlyer"] or princessData["tolerantFlyer"] then score = score + scoresAttrib["tolerantFlyer"] end
if droneData["caveDwelling"] or princessData["caveDwelling"] then score = score + scoresAttrib["caveDwelling"] end
score = score + max(scoresTolerance[droneData["toleranceTemperature"]], scoresTolerance[princessData["toleranceTemperature"]])
score = score + max(scoresTolerance[droneData["toleranceHumidity"]], scoresTolerance[princessData["toleranceHumidity"]])
return score
end
function printHeader()
logLine()
logLine("typ species f spd d n f c tmp hmd score")
logLine("-|-|-------|-|---|-|-|-|-|---|---|-----")
end
toleranceString = {
["NONE"] = " ",
["UP_1"] = " +1 ",
["UP_2"] = " +2 ",
["UP_3"] = " +3 ",
["DOWN_1"] = " -1 ",
["DOWN_2"] = " -2 ",
["DOWN_3"] = " -3 ",
["BOTH_1"] = "+-1 ",
["BOTH_2"] = "+-2 ",
["BOTH_3"] = "+-3 "
}
function printBee(beeData)
log(beeData["slot"] < 10 and beeData["slot"].." " or beeData["slot"])
if (beeData["type"] == "princess") then
log("P ")
else
log("d ")
end
log(beeData["speciesPrimary"]:gsub("bees%.species%.",""):sub(1,3)..":"..beeData["speciesSecondary"]:gsub("bees%.species%.",""):sub(1,3).." ")
log(tostring(beeData["fertility"]).." ")
log(beeData["speed"] == 1 and "1.0 " or tostring(beeData["speed"]).." ")
if beeData["diurnal"] then
log("d ")
else
log(" ")
end
if beeData["nocturnal"] then
log("n ")
else
log(" ")
end
if beeData["tolerantFlyer"] then
log("f ")
else
log(" ")
end
if beeData["caveDwelling"] then
log("c ")
else
log(" ")
end
log(toleranceString[beeData["toleranceTemperature"]])
log(toleranceString[beeData["toleranceHumidity"]])
if beeData.score then
logLine(string.format("%5.1d", beeData.score).." ")
else
logLine()
end
end
function dropExcess(droneData)
print("dropping excess...")
local count = 0
for i = 1, 16 do
if turtle.getItemCount(i) > 0 then
-- check for untargeted species
if droneData[i] and (not bees[droneData[i]["speciesPrimary"]].targeted
or not bees[droneData[i]["speciesSecondary"]].targeted) then
turtle.select(i)
turtle.dropDown()
else
count = count + 1
end
-- drop drones over 9 to clear space for newly bred bees and product
if count > 9 then
turtle.select(i)
turtle.dropDown()
count = count - 1
end
end
end
end
function isPurebred(princessData, droneData)
-- check if princess and drone are exactly the same and no chance for mutation
if princessData["speciesPrimary"] ~= princessData["speciesSecondary"] then
return false
end
for key, value in pairs(princessData) do
if value ~= droneData[key] and key ~= "territory" and key ~= "type" and key ~= "slot" then
return false
end
end
return true
end
function getUnknown(princessData, droneData)
-- lists species that are not in the bee graph
local unknownSpecies = {}
if not bees[princessData["speciesPrimary"]] then
table.insert(unknownSpecies, princessData["speciesPrimary"])
end
if not bees[princessData["speciesSecondary"]] then
table.insert(unknownSpecies, princessData["speciesSecondary"])
end
for _, beeData in pairs(droneData) do
if not bees[beeData["speciesPrimary"]] then
table.insert(unknownSpecies, beeData["speciesPrimary"])
end
if not bees[beeData["speciesSecondary"]] then
table.insert(unknownSpecies, beeData["speciesSecondary"])
end
end
return unknownSpecies
end
-- targeting -------------------------------------------------------------------
-- set species and all parents to targeted
function targetBee(name)
local bee = bees[name]
if bee and not bee.targeted then
bee.targeted = true
for i, parents in ipairs(bee.mutateFrom) do
for j, parent in ipairs(parents) do
targetBee(parent)
end
end
end
end
-- set bee graph entry to targeted if species was specified on the command line
-- otherwise set all entries to targeted
tArgs = { ... }
if #tArgs > 0 then
logLine("targeting bee species:")
for i, target in ipairs(tArgs) do
targetBee(target)
for name, data in pairs(bees) do
if data.targeted and data.score > 1 then
logLine(name .. string.rep(" ", 20-#name), data.score)
end
end
end
else
for _, beeData in pairs(bees) do
beeData.targeted = true
end
end
-- breeding loop ---------------------------------------------------------------
logLine("Clearing system...")
clearSystem()
while true do
ditchProduct()
countBees()
scanBees()
princessData, droneData = analyzeBees()
if princessData then
if isPurebred(princessData, droneData[2]) then
logLine("Bees are purebred")
turtle.turnRight()
break
end
local unknownSpecies = getUnknown(princessData, droneData)
if #unknownSpecies > 0 then
logLine("Please add new species to bee graph:")
for _, species in ipairs(unknownSpecies) do
logLine(" "..species)
end
turtle.turnRight()
break
end
breedBees(1, 2)
dropExcess(droneData)
end
getBees()
end
logFile.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment