Advertisement
denvys5

BeeBreader OpenPeripherals

Jan 18th, 2014
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 29.08 KB | None | 0 0
  1. -- BeeAnalyzer 4.4
  2. -- Original code by Direwolf20
  3. -- Hotfix 1 by Mandydax
  4. -- Hotfix 2 by Mikeyhun/MaaadMike
  5. -- 4.0 Major overhaul by MacLeopold
  6. --     Breeds bees with best attributes in this order:
  7. --     fertility, speed, nocturnal, flyer, cave, temperature tolerance, humidity tolerance
  8. --     other attributes are ignored (lifespawn, flowers, effect and territory)
  9. --     Can specify multiple target species to help with keeping to the correct line
  10. -- 4.1 Minor fix for FTB Unleashed, no more inventory module or suckSneaky needed
  11. -- 4.2 Major overhaul 2
  12. --     Added magic bees, removed old bees
  13. --     Added species graph
  14. --     Changed targeting to target parent species
  15. --     Changed breeding to keep stock of good bees to prevent losing attributes
  16. --     Added logging
  17. --     Changed scoring to look for best combination of princess and drone
  18. -- 4.3 Updated targeting
  19. -- 4.4 Switched to OpenPeripherals by Eiktyrner
  20.  
  21. -- attribute scoring for same species tie-breaking -----------------------------
  22.  
  23. scoresFertility = {
  24.   [1] = 0.1,
  25.   [2] = 0.2,
  26.   [3] = 0.3,
  27.   [4] = 0.4
  28. }
  29. scoresSpeed = {
  30.   ["Slowest"] = 0.01,
  31.   ["Slower"] = 0.02,
  32.   ["Slow"] = 0.03,
  33.   ["Normal"]   = 0.04,
  34.   ["Fast"] = 0.05,
  35.   ["Faster"] = 0.06,
  36.   ["Fastest"] = 0.07
  37. }
  38. scoresAttrib = {
  39.   diurnal      =0.004,
  40.   nocturnal    =0.002,
  41.   tolerantFlyer=0.001,
  42.   caveDwelling =0.0001
  43. }
  44. scoresTolerance = {
  45.   ["NONE"]   = 0.00000,
  46.   ["UP_1"]   = 0.00001,
  47.   ["UP_2"]   = 0.00002,
  48.   ["UP_3"]   = 0.00003,
  49.   ["UP_4"]   = 0.00004,
  50.   ["UP_5"]   = 0.00005,
  51.   ["DOWN_1"] = 0.00001,
  52.   ["DOWN_2"] = 0.00002,
  53.   ["DOWN_3"] = 0.00003,
  54.   ["DOWN_4"] = 0.00004,
  55.   ["DOWN_5"] = 0.00005,
  56.   ["BOTH_1"] = 0.00002,
  57.   ["BOTH_2"] = 0.00004,
  58.   ["BOTH_3"] = 0.00006,
  59.   ["BOTH_4"] = 0.00008,
  60.   ["BOTH_5"] = 0.00010
  61. }
  62.  
  63. -- the bee graph ---------------------------------------------------------------
  64.  
  65. bees = {}
  66.  
  67. function addParent(parent, offspring)
  68.   if bees[parent] then
  69.     bees[parent].mutateTo[offspring] = true
  70.   else
  71.     bees[parent] = {
  72.       --name = parent,
  73.       score = nil,
  74.       mutateTo = {[offspring]=true},
  75.       mutateFrom = {}
  76.     }
  77.   end
  78. end
  79.  
  80. function addOffspring(offspring, parentss)
  81.   if bees[offspring] then
  82.     for i, parents in ipairs(parentss) do
  83.       table.insert(bees[offspring].mutateFrom, parents)
  84.     end
  85.   else
  86.     bees[offspring] = {
  87.       score = nil,
  88.       mutateTo = {},
  89.       mutateFrom = parentss
  90.     }
  91.   end
  92.   for i, parents in ipairs(parentss) do
  93.     for i, parent in ipairs(parents) do
  94.       addParent(parent, offspring)
  95.     end
  96.   end
  97. end
  98.  
  99. -- score bees that have no parent combinations as 1
  100. -- iteratively find the next bee up the line and increase the score
  101. function scoreBees()
  102.   -- find all bees with no mutateFrom data
  103.   local beeCount = 0
  104.   local beeScore = 1
  105.   for name, beeData in pairs(bees) do
  106.     if #beeData.mutateFrom == 0 then
  107.       beeData.score = beeScore
  108.     else
  109.       beeCount = beeCount + 1
  110.     end
  111.   end
  112.   while beeCount > 0 do
  113.     beeScore = beeScore * 4
  114.     -- find all bees where all parent combos are scored
  115.     for name, beeData in pairs(bees) do
  116.       if not beeData.score then
  117.         local scoreBee = true
  118.         for i, beeParents in ipairs(beeData.mutateFrom) do
  119.           local parent1 = bees[beeParents[1]]
  120.           local parent2 = bees[beeParents[2]]
  121.  
  122.           if not parent1.score
  123.               or parent1.score == beeScore
  124.               or not parent2.score
  125.               or parent2.score == beeScore then
  126.             scoreBee = false
  127.             break
  128.           end
  129.         end
  130.         if scoreBee then
  131.           beeData.score = beeScore
  132.           beeCount = beeCount - 1
  133.         end
  134.       end
  135.     end
  136.   end
  137. end
  138.  
  139. -- produce combinations from 1 or 2 lists
  140. function choose(list, list2)
  141.   local newList = {}
  142.   if list2 then
  143.     for i = 1, #list2 do
  144.       for j = 1, #list do
  145.         if list[j] ~= list[i] then
  146.           table.insert(newList, {list[j], list2[i]})
  147.         end
  148.       end
  149.     end
  150.   else
  151.     for i = 1, #list do
  152.       for j = i, #list do
  153.         if list[i] ~= list[j] then
  154.           table.insert(newList, {list[i], list[j]})
  155.         end
  156.       end
  157.     end
  158.   end
  159.   return newList
  160. end
  161.  
  162. -- Forestry Bees ---------------------------------------------------------------
  163.  
  164. -- Agrarian Branch
  165. addOffspring("Rural", {{"Diligent", "Meadows"}})
  166. addOffspring("Farmed", {{"Rural", "Cultivated"}})
  167. -- Apis Branch
  168. addOffspring("Common", choose({"Forest", "Meadows", "Modest", "Marbled", "Tropical", "Wintry", "Marshy", "Water", "Rocky", "Embittered", "Unusual", "Mystical", "Sorcerous", "Attuned"}))
  169. addOffspring("Cultivated", choose({"Common"}, {"Forest", "Meadows", "Modest", "Marbled", "Tropical", "Wintry", "Marshy", "Water", "Rocky", "Embittered", "Unusual", "Mystical", "Sorcerous", "Attuned"}))
  170. -- Austere Branch
  171. addOffspring("Frugal", {{"Sinister", "Modest"}, {"Fiendish", "Modest"}})
  172. addOffspring("Austere", {{"Frugal", "Modest"}})
  173. -- Beastly Branch
  174. addOffspring("Jaded", {{"Ender", "Relic"}})
  175. -- End Branch
  176. addOffspring("Spectral", {{"Hermitic", "Ender"}})
  177. addOffspring("Phantasmal", {{"Spectral", "Ender"}})
  178. -- Festive Branch
  179. addOffspring("Celebratory", {{"Austere", "Excited"}})
  180. addOffspring("Hazardous", {{"Austere", "Desolate"}})
  181. addOffspring("Leporine", {{"Meadows", "Forest"}})
  182. addOffspring("Merry", {{"Wintry", "Forest"}})
  183. addOffspring("Tipsy", {{"Wintry", "Meadows"}})
  184. -- Frozen Branch
  185. addOffspring("Icy", {{"Industrious", "Wintry"}})
  186. addOffspring("Glacial", {{"Icy", "Wintry"}})
  187. addOffspring("Frigid", {{"Diligent", "Wintry"}})
  188. addOffspring("Absolute", {{"Frigid", "Ocean"}})
  189. -- Heroic Branch
  190. addOffspring("Heroic", {{"Steadfast", "Valiant"}})
  191. -- Industrious Branch
  192. addOffspring("Diligent", {{"Cultivated", "Common"}})
  193. addOffspring("Unweary", {{"Diligent", "Cultivated"}})
  194. addOffspring("Industrious", {{"Unweary", "Diligent"}})
  195. -- Infernal Branch
  196. addOffspring("Sinister", {{"Cultivated", "Modest"}, {"Cultivated", "Tropical"}})
  197. addOffspring("Fiendish", {{"Sinister", "Cultivated"}, {"Sinister", "Modest"}, {"Sinister", "Tropical"}})
  198. addOffspring("Demonic", {{"Fiendish", "Sinister"}})
  199. -- Monastic Branch
  200. addOffspring("Secluded", {{"Monastic", "Austere"}})
  201. addOffspring("Hermitic", {{"Secluded", "Monastic"}})
  202. -- Noble Branch
  203. addOffspring("Noble", {{"Cultivated", "Common"}})
  204. addOffspring("Majestic", {{"Noble", "Cultivated"}})
  205. addOffspring("Imperial", {{"Majestic", "Noble"}})
  206. -- Tropical Branch
  207. addOffspring("Exotic", {{"Austere", "Tropical"}})
  208. addOffspring("Edenic", {{"Exotic", "Tropical"}})
  209. -- Vengeful Branch
  210. addOffspring("Vindictive", {{"Monastic", "Demonic"}})
  211. addOffspring("Vengeful", {{"Vindictive", "Demonic"}, {"Vindictive", "Monastic"}})
  212. addOffspring("Avenging", {{"Vengeful", "Vindictive"}})
  213.  
  214. -- Extra Bees ------------------------------------------------------------------
  215.  
  216. -- Agricultural Branch
  217. addOffspring("Bovine", {{"Rural", "Water"}})
  218. addOffspring("Caffeinated", {{"Rural", "Tropical"}})
  219. addOffspring("Citrus", {{"Farmed", "Modest"}})
  220. addOffspring("Fermented", {{"Rural", "Fruity"}})
  221. addOffspring("Minty", {{"Farmed", "Tropical"}})
  222. -- Alloyed Branch
  223. addOffspring("Impregnable", {{"Resilient", "Noble"}})
  224. -- Aquatic Branch
  225. addOffspring("River", {{"Common", "Water"}})
  226. addOffspring("Ocean", {{"Diligent", "Water"}})
  227. addOffspring("Stained", {{"Ocean", "Ebony"}})
  228. -- Barren Branch
  229. addOffspring("Arid", {{"Meadows", "Modest"}})
  230. addOffspring("Barren", {{"Arid", "Common"}})
  231. addOffspring("Desolate", {{"Barren", "Arid"}})
  232. -- Boggy Branch
  233. addOffspring("Damp", {{"Common", "Marshy"}})
  234. addOffspring("Boggy", {{"Damp", "Marshy"}})
  235. addOffspring("Fungal", {{"Boggy", "Damp"}})
  236. -- Caustic Branch
  237. addOffspring("Corrosive", {{"Virulent", "Sticky"}})
  238. addOffspring("Caustic", {{"Corrosive", "Fiendish"}})
  239. addOffspring("Acidic", {{"Caustic", "Corrosive"}})
  240. -- Energetic Branch
  241. addOffspring("Excited", {{"Cultivated", "Valiant"}})
  242. addOffspring("Energetic", {{"Excited", "Valiant"}})
  243. addOffspring("Ecstatic", {{"Energetic", "Excited"}})
  244. -- Fossilized
  245. addOffspring("Fossiled", {{"Primeval", "Growing"}})
  246. addOffspring("Oily", {{"Primeval", "Ocean"}})
  247. addOffspring("Preserved", {{"Primeval", "Boggy"}})
  248. addOffspring("Resinous", {{"Primeval", "Fungal"}})
  249. -- Gemstone Branch
  250. addOffspring("Diamond", {{"Lapis", "Imperial"}})
  251. addOffspring("Emerald", {{"Lapis", "Noble"}})
  252. addOffspring("Ruby", {{"Emerald", "Austere"}})
  253. addOffspring("Sapphire", {{"Emerald", "Ocean"}})
  254. -- Historic Branch
  255. addOffspring("Ancient", {{"Noble", "Diligent"}})
  256. addOffspring("Primeval", {{"Ancient", "Noble"}})
  257. addOffspring("Prehistoric", {{"Primeval", "Majestic"}})
  258. addOffspring("Relic", {{"Prehistoric", "Imperial"}})
  259. -- Hostile Branch
  260. addOffspring("Skeletal", {{"Desolate", "Frugal"}})
  261. addOffspring("Decaying", {{"Desolate", "Modest"}})
  262. addOffspring("Creepy", {{"Desolate", "Austere"}})
  263. -- Metallic Branch
  264. addOffspring("Galvanized", {{"Tarnished", "Cultivated"}})
  265. addOffspring("Invincible", {{"Resilient", "Ender"}})
  266. addOffspring("Lustered", {{"Resilient", "Unweary"}})
  267. -- Nuclear Branch
  268. addOffspring("Unstable", {{"Austere", "Rocky"}})
  269. addOffspring("Nuclear", {{"Unstable", "Rusty"}})
  270. addOffspring("Radioactive", {{"Nuclear", "Glittering"}})
  271. -- Precious Branch
  272. addOffspring("Lapis", {{"Resilient", "Water"}})
  273. addOffspring("Glittering", {{"Corroded", "Imperial"}})
  274. addOffspring("Shining", {{"Rusty", "Imperial"}})
  275. addOffspring("Valuable", {{"Glittering", "Shining"}})
  276. -- Refined Branch
  277. addOffspring("Distilled", {{"Oily", "Industrious"}})
  278. addOffspring("Refined", {{"Distilled", "Oily"}})
  279. addOffspring("Elastic", {{"Refined", "Resinous"}})
  280. addOffspring("Tarry", {{"Refined", "Fossiled"}})
  281. -- Rocky Branch
  282. addOffspring("Tolerant", {{"Diligent", "Rocky"}})
  283. addOffspring("Robust", {{"Tolerant", "Rocky"}})
  284. addOffspring("Resilient", {{"Robust", "Imperial"}})
  285. -- Rusty Branch
  286. addOffspring("Corroded", {{"Resilient", "Forest"}})
  287. addOffspring("Leaden", {{"Resilient", "Unweary"}})
  288. addOffspring("Rusty", {{"Resilient", "Meadows"}})
  289. addOffspring("Tarnished", {{"Resilient", "Marshy"}})
  290. -- Saccharine Branch
  291. addOffspring("Sweetened", {{"Diligent", "Valiant"}})
  292. addOffspring("Sugary", {{"Sweetened", "Diligent"}})
  293. addOffspring("Fruity", {{"Ripening", "Rural"}})
  294. -- Shadow Branch
  295. addOffspring("Shadowed", {{"Tolerant", "Sinister"}})
  296. addOffspring("Darkened", {{"Shadowed", "Embittered"}})
  297. addOffspring("Abyssmal", {{"Darkened", "Shadowed"}})
  298. -- Virulent Branch
  299. addOffspring("Malicious", {{"Sinister", "Tropical"}})
  300. addOffspring("Infectious", {{"Malicious", "Tropical"}})
  301. addOffspring("Virulent", {{"Infectious", "Malicious"}})
  302. -- Viscous Branch
  303. addOffspring("Viscous", {{"Exotic", "Water"}})
  304. addOffspring("Glutinous", {{"Viscous", "Exotic"}})
  305. addOffspring("Sticky", {{"Glutinous", "Viscous"}})
  306. -- Volcanic Branch
  307. addOffspring("Furious", {{"Sinister", "Embittered"}})
  308. addOffspring("Volcanic", {{"Furious", "Embittered"}})
  309. addOffspring("Glowering", {{"Excited", "Furious"}})
  310.  
  311. -- Primary Branch
  312. addOffspring("Bleached", {{"Wintry", "Valiant"}})
  313. addOffspring("Ebony", {{"Rocky", "Valiant"}})
  314. addOffspring("Maroon", {{"Forest", "Valiant"}})
  315. addOffspring("Natural", {{"Tropical", "Valiant"}})
  316. addOffspring("Prussian", {{"Water", "Valiant"}})
  317. addOffspring("Saffron", {{"Meadows", "Valiant"}})
  318. addOffspring("Sepia", {{"Marshy", "Valiant"}})
  319. -- Secondary Branch
  320. addOffspring("Amber", {{"Maroon", "Saffron"}})
  321. addOffspring("Azure", {{"Prussian", "Bleached"}})
  322. addOffspring("Indigo", {{"Maroon", "Prussian"}})
  323. addOffspring("Lavender", {{"Maroon", "Bleached"}})
  324. addOffspring("Lime", {{"Natural", "Bleached"}})
  325. addOffspring("Slate", {{"Ebony", "Bleached"}})
  326. addOffspring("Turquoise", {{"Natural", "Prussian"}})
  327. -- Tertiary Branch
  328. addOffspring("Ashen", {{"Slate", "Bleached"}})
  329. addOffspring("Fuchsia", {{"Indigo", "Lavender"}})
  330.  
  331. -- no branch
  332. addOffspring("Gnawing", {{"Barren", "Forest"}})
  333. addOffspring("Decoposing", {{"Arid", "Common"}, {"Gnawing", "Common"}})
  334. addOffspring("Growing", {{"Diligent", "Forest"}})
  335. addOffspring("Thriving", {{"Growing", "Rural"}})
  336. addOffspring("Blooming", {{"Growing", "Thriving"}})
  337. addOffspring("Ripening", {{"Sugary", "Forest"}})
  338.  
  339. -- Magic Bees ------------------------------------------------------------------
  340.  
  341. -- Abominable Branch
  342. addOffspring("Hateful", {{"Eldritch", "Infernal"}})
  343. addOffspring("Spiteful", {{"Hateful", "Infernal"}})
  344. addOffspring("Withering", {{"Demonic", "Spiteful"}})
  345. -- Alchemical Branch
  346. addOffspring("Minium", {{"Eldritch", "Frugal"}})
  347. -- Arcane Branch
  348. addOffspring("Esoteric", {{"Eldritch", "Cultivated"}})
  349. addOffspring("Mysterious", {{"Eldritch", "Esoteric"}})
  350. addOffspring("Arcane", {{"Mysterious", "Esoteric"}})
  351. -- Aware Branch
  352. addOffspring("Ethereal", {{"Arcane", "Supernatural"}})
  353. addOffspring("Aware", {{"Ethereal", "Attuned"}})
  354. addOffspring("Watery", {{"Ethereal", "Supernatural"}})
  355. addOffspring("Windy", {{"Ethereal", "Supernatural"}})
  356. addOffspring("Firey", {{"Ethereal", "Supernatural"}})
  357. addOffspring("Earthen", {{"Ethereal", "Supernatural"}})
  358. -- Essential Branch
  359. addOffspring("Essence", {{"Arcane", "Ethereal"}})
  360. addOffspring("Arkanen", {{"Essence", "Ethereal"}})
  361. addOffspring("Quintessential", {{"Essence", "Arcane"}})
  362. addOffspring("Vortex", {{"Essence", "Skulking"}})
  363. addOffspring("Wight", {{"Ghastly", "Skulking"}})
  364. addOffspring("Luft", {{"Essence", "Windy"}})
  365. addOffspring("Blitz", {{"Luft", "Windy"}})
  366. addOffspring("Wasser", {{"Essence", "Watery"}})
  367. addOffspring("Eis", {{"Wasser", "Watery"}})
  368. addOffspring("Erde", {{"Essence", "Earthen"}})
  369. addOffspring("Staude", {{"Erde", "Earthen"}})
  370. addOffspring("Feuer", {{"Essence", "Firey"}})
  371. addOffspring("Magma", {{"Feuer", "Firey"}})
  372. -- Extrinsic
  373. addOffspring("Nameless", {{"Oblivion", "Ethereal"}})
  374. addOffspring("Abandoned", {{"Nameless", "Oblivion"}})
  375. addOffspring("Forlorn", {{"Abandoned", "Nameless"}})
  376. addOffspring("Draconic", {{"Abandoned", "Imperial"}})
  377. -- Fleshly Branch
  378. addOffspring("Poultry", {{"Skulking", "Common"}})
  379. addOffspring("Beefy", {{"Skulking", "Common"}})
  380. addOffspring("Porcine", {{"Skulking", "Common"}})
  381. -- Gem Branch
  382. addOffspring("Apatine", {{"Rural", "Cuprum"}})
  383. addOffspring("Diamandi", {{"Austere", "Auric"}})
  384. addOffspring("Esmeraldi", {{"Austere", "Argentum"}})
  385. -- Metallic2 Branch
  386. addOffspring("Cuprum", {{"Industrious", "Meadows"}})
  387. addOffspring("Stannum", {{"Industrious", "Forest"}})
  388. addOffspring("Aluminum", {{"Industrious", "Cultivated"}})
  389. addOffspring("Ardite", {{"Industrious", "Infernal"}})
  390. addOffspring("Argentum", {{"Imperial", "Modest"}})
  391. addOffspring("Cobalt", {{"Imperial", "Infernal"}})
  392. addOffspring("Ferrous", {{"Common", "Industrious"}})
  393. addOffspring("Plumbum", {{"Stannum", "Common"}})
  394. addOffspring("Auric", {{"Minium", "Plumbum"}})
  395. addOffspring("Manyullyn", {{"Ardite", "Cobalt"}})
  396. -- Scholarly Branch
  397. addOffspring("Pupil", {{"Arcane", "Monastic"}})
  398. addOffspring("Scholarly", {{"Arcane", "Pupil"}})
  399. addOffspring("Savant", {{"Scholarly", "Pupil"}})
  400. -- Skulking Branch
  401. addOffspring("Skulking", {{"Eldritch", "Modest"}})
  402. addOffspring("Ghastly", {{"Skulking", "Ethereal"}})
  403. addOffspring("Smouldering", {{"Skulking", "Hateful"}})
  404. addOffspring("Spidery", {{"Skulking", "Tropical"}})
  405. -- Soulful Branch
  406. addOffspring("Spirit", {{"Ethereal", "Aware"}, {"Attuned", "Aware"}})
  407. addOffspring("Soul", {{"Spirit", "Aware"}})
  408. -- Supernatural Branch
  409. addOffspring("Charmed", {{"Eldritch", "Cultivated"}})
  410. addOffspring("Enchanted", {{"Eldritch", "Charmed"}})
  411. addOffspring("Supernatural", {{"Enchanted", "Charmed"}})
  412. -- Thaumic Branch
  413. addOffspring("Aqua", {{"Watery", "Watery"}})
  414. addOffspring("Aura", {{"Windy", "Windy"}})
  415. addOffspring("Ignis", {{"Firey", "Firey"}})
  416. addOffspring("Praecantatio", {{"Ethereal", "Ethereal"}})
  417. addOffspring("Solum", {{"Earthen", "Earthen"}})
  418. addOffspring("Stark", choose({"Earthen", "Firey", "Watery", "Windy"}))
  419. addOffspring("Vis", {{"Eldritch", "Ethereal"}})
  420. addOffspring("Flux", {{"Vis", "Demonic"}})
  421. addOffspring("Attractive", {{"Vis", "Flux"}})
  422. addOffspring("Rejuvenating", {{"Vis", "Imperial"}})
  423. addOffspring("Pure", {{"Vis", "Rejuvenating"}})
  424. addOffspring("Batty", {{"Skulking", "Windy"}})
  425. addOffspring("Brainy", {{"Skulking", "Pupil"}})
  426. addOffspring("Wispy", {{"Ethereal", "Ghastly"}})
  427. -- Time Branch
  428. addOffspring("Timely", {{"Ethereal", "Imperial"}})
  429. addOffspring("Lordly", {{"Timely", "Imperial"}})
  430. addOffspring("Doctoral", {{"Lordly", "Timely"}})
  431. -- Veiled Branch
  432. addOffspring("Eldritch", {{"Mystical", "Cultivated"}, {"Sorcerous", "Cultivated"}, {"Unusual", "Cultivated"}, {"Attuned", "Cultivated"}})
  433.  
  434. scoreBees()
  435.  
  436. -- logging ---------------------------------------------------------------------
  437.  
  438. local logFile = fs.open("bee.log", "w")
  439. function log(msg)
  440.   msg = msg or ""
  441.   logFile.write(tostring(msg))
  442.   logFile.flush()
  443.   io.write(msg)
  444. end
  445. function logLine(msg)
  446.   msg = msg or ""
  447.   logFile.write(msg.."\n")
  448.   logFile.flush()
  449.   io.write(msg.."\n")
  450. end
  451.  
  452. function logTable(table)
  453.   for key, value in pairs (table) do
  454.     logLine(key .. " = " .. tostring(value))
  455.   end
  456. end
  457.  
  458. -- analyzing functions ---------------------------------------------------------
  459.  
  460. -- Fix for some versions returning bees.species.*
  461. function fixName(name)
  462.   return name:gsub("bees%.species%.",""):gsub("^.", string.upper)
  463. end
  464.  
  465. -- Expects the turtle facing apiary
  466. function clearSystem()
  467.   -- clear out apiary
  468.   while turtle.suck() do end
  469.  
  470.   -- clear out analyzer
  471.   turtle.turnLeft()
  472.   while turtle.suck() do end
  473.   turtle.turnRight()
  474. end
  475.  
  476. function getBees()
  477.   -- get bees from apiary
  478.   log("waiting for bees.")
  479.   turtle.select(1)
  480.   while not turtle.suck() do
  481.     sleep(10)
  482.     log(".")
  483.   end
  484.   log("*")
  485.   while turtle.suck() do
  486.     log("*")
  487.   end
  488.   logLine()
  489. end
  490.  
  491. function countBees()
  492.   -- spread dups and fill gaps
  493.   local count = 0
  494.   for i = 1, 16 do
  495.     local slotCount = turtle.getItemCount(i)
  496.     if slotCount == 1 then
  497.       for j = 1, i-1 do
  498.         if turtle.getItemCount(j) == 0 then
  499.           turtle.select(i)
  500.           turtle.transferTo(j)
  501.           break
  502.         end
  503.       end
  504.       count = count + 1
  505.     elseif slotCount > 1 then
  506.       for j = 2, slotCount do
  507.         turtle.select(i)
  508.         for k = 1, 16 do
  509.           if turtle.getItemCount(k) == 0 then
  510.             turtle.transferTo(k, 1)
  511.           end
  512.         end
  513.       end
  514.       if turtle.getItemCount(i) > 1 then
  515.         turtle.dropDown(turtle.getItemCount(i)-1)
  516.       end
  517.     end
  518.   end
  519.   return count
  520. end
  521.  
  522. function breedBees(princessSlot, droneSlot)
  523.    turtle.select(princessSlot)
  524.    turtle.drop()
  525.    turtle.select(droneSlot)
  526.    turtle.drop()
  527. end
  528.  
  529. -- Turns to Analyzer and tries to drop item.
  530. -- If it's not accepted (not a bee)
  531. -- drop to chest.
  532. function ditchProduct()  
  533.   print("ditching product...")
  534.   turtle.turnLeft()
  535.   m = peripheral.wrap("front")
  536.   for i = 1, 16 do
  537.     if turtle.getItemCount(i) > 0 then
  538.       turtle.select(i)
  539.       if not turtle.drop() then
  540.         turtle.dropDown()
  541.       else
  542.         while not turtle.suck() do
  543.           sleep(1)
  544.         end
  545.       end
  546.     end
  547.   end
  548.   turtle.turnRight()
  549. end
  550.  
  551. function swapBee(slot1, slot2, freeSlot)
  552.   turtle.select(slot1)
  553.   turtle.transferTo(freeSlot)
  554.   turtle.select(slot2)
  555.   turtle.transferTo(slot1)
  556.   turtle.select(freeSlot)
  557.   turtle.transferTo(slot2)
  558. end  
  559.  
  560. -- Turn left to Analyzer
  561. function analyzeBees()
  562.   print("analyzing bees...")
  563.   turtle.turnLeft()
  564.  
  565.   local freeSlot
  566.   local princessSlot
  567.   local princessData
  568.   local droneData = {}
  569.   local beealyzer = peripheral.wrap("front")
  570.  
  571.   for i = 1, 16 do
  572.     if turtle.getItemCount(i) > 0 then
  573.       print(".")
  574.       turtle.select(i)
  575.       turtle.drop()
  576.  
  577.       sleep(1) -- To make sure the drone goes through the analyzer
  578.  
  579.       local tableData = beealyzer.getStackInSlot(9)
  580.       local beeData = {}
  581.  
  582.       -- Get bees back into turtle after grabbing values
  583.       while not turtle.suck() do
  584.         sleep(1)
  585.       end
  586.  
  587.       -- Check if it's a drone or princess
  588.       for key, value in pairs (tableData) do
  589.         if key == "rawName" then
  590.           if string.find(value, "princess") then
  591.             beeData["type"] = "princess"
  592.           else
  593.             beeData["type"] = "drone"
  594.           end
  595.         end
  596.       end
  597.  
  598.       -- Active values
  599.       for key, value in pairs (tableData.beeInfo.active) do
  600.         if key == "species" then
  601.           beeData["speciesPrimary"] = value
  602.         else
  603.           beeData[key] = value
  604.         end
  605.       end
  606.      
  607.       -- Inactive values
  608.       for key, value in pairs (tableData.beeInfo.inactive) do
  609.         if key == "species" then
  610.           beeData["speciesSecondary"] = value
  611.         end
  612.       end
  613.  
  614.       if not beeData["speciesPrimary"] then
  615.         print("Bee "..i.." not correctly analyzed")
  616.       else
  617.         beeData["speciesPrimary"] = fixName(beeData["speciesPrimary"])
  618.         beeData["speciesSecondary"] = fixName(beeData["speciesSecondary"])
  619.         if beeData["type"] == "princess" then
  620.           princessData = beeData
  621.           princessSlot = i
  622.         else
  623.           droneData[i] = beeData
  624.         end
  625.       end
  626.     else
  627.       freeSlot = i
  628.     end
  629.   end
  630.  
  631.   if princessData then
  632.     if princessSlot ~= 1 then
  633.       swapBee(1, princessSlot, freeSlot)
  634.       droneData[princessSlot] = droneData[1]
  635.       droneData[1] = nil
  636.       princessSlot = 1
  637.     end
  638.     -- bubble sort drones
  639.     print("sorting drones...")
  640.     for i = 2, 16 do
  641.       if turtle.getItemCount(i) > 0 and droneData[i] then
  642.         droneData[i].score = scoreBee(princessData, droneData[i])
  643.         for j = i - 1, 2, -1 do
  644.           if droneData[j+1].score > droneData[j].score then
  645.             swapBee(j+1, j, freeSlot)
  646.             droneData[j+1], droneData[j] = droneData[j], droneData[j+1]
  647.           end
  648.         end
  649.       end
  650.     end
  651.     printHeader()
  652.     princessData.slot = 1
  653.     printBee(princessData)
  654.     for i = 2, 16 do
  655.       if droneData[i] then
  656.         droneData[i].slot = i
  657.         printBee(droneData[i])
  658.       end
  659.     end
  660.   end
  661.   logLine()
  662.   turtle.turnRight()
  663.   return princessData, droneData
  664. end
  665.  
  666. function scoreBee(princessData, droneData)
  667.   local droneSpecies = {droneData["speciesPrimary"], droneData["speciesSecondary"]}
  668.   -- check for untargeted species
  669.   if not bees[droneSpecies[1]].targeted or not bees[droneSpecies[2]].targeted then
  670.     return 0
  671.   end
  672.   local princessSpecies = {princessData["speciesPrimary"], princessData["speciesSecondary"]}
  673.   local max = math.max
  674.   local score
  675.   local maxScore = 0
  676.   for _, combo in ipairs({{princessSpecies[1], droneSpecies[1]}
  677.                          ,{princessSpecies[1], droneSpecies[2]}
  678.                          ,{princessSpecies[2], droneSpecies[1]}
  679.                          ,{princessSpecies[2], droneSpecies[2]}}) do
  680.     -- find maximum score for each combo
  681.     score = max(bees[combo[1]].score, bees[combo[2]].score)
  682.     for name, beeData in pairs(bees) do
  683.       if beeData.targeted then
  684.         for i, parents in ipairs(beeData.mutateFrom) do
  685.           if combo[1] == parents[1] and combo[2] == parents[2]
  686.               or combo[2] == parents[1] and combo[1] == parents[2] then
  687.             if beeData.score > score then
  688.               --log(" "..name:sub(1,3).."="..tostring(beeData.score))
  689.             end
  690.             -- deduct 1 to make potential scores less than base scores
  691.             score = max(score, beeData.score - 1)
  692.           end
  693.         end
  694.       end
  695.     end
  696.     maxScore = maxScore + score
  697.   end
  698.   -- add one for each combination that results in the maximum score
  699.   score = maxScore
  700.   -- score attributes
  701.   score = score + max(scoresFertility[droneData["fertility"]], scoresFertility[princessData["fertility"]])
  702.   score = score + math.min(scoresSpeed[droneData["speed"]], scoresSpeed[princessData["speed"]])
  703.   if droneData["diurnal"] or princessData["diurnal"] then score = score + scoresAttrib["diurnal"] end
  704.   if droneData["nocturnal"] or princessData["nocturnal"] then score = score + scoresAttrib["nocturnal"] end
  705.   if droneData["tolerantFlyer"] or princessData["tolerantFlyer"] then score = score + scoresAttrib["tolerantFlyer"] end
  706.   if droneData["caveDwelling"] or princessData["caveDwelling"] then score = score + scoresAttrib["caveDwelling"] end
  707.   score = score + max(scoresTolerance[droneData["temperatureTolerance"]], scoresTolerance[princessData["temperatureTolerance"]])
  708.   score = score + max(scoresTolerance[droneData["humidityTolerance"]], scoresTolerance[princessData["humidityTolerance"]])
  709.   return score
  710. end
  711.  
  712. function printHeader()
  713.   logLine()
  714.   logLine("typ species f spd d n f c tmp hmd score")
  715.   logLine("-|-|-------|-|---|-|-|-|-|---|---|-----")
  716. end
  717.  
  718. toleranceString = {
  719.   ["NONE"] = "    ",
  720.   ["UP_1"] = " +1 ",
  721.   ["UP_2"] = " +2 ",
  722.   ["UP_3"] = " +3 ",
  723.   ["DOWN_1"] = " -1 ",
  724.   ["DOWN_2"] = " -2 ",
  725.   ["DOWN_3"] = " -3 ",
  726.   ["BOTH_1"] = "+-1 ",
  727.   ["BOTH_2"] = "+-2 ",
  728.   ["BOTH_3"] = "+-3 "
  729. }
  730.  
  731. speedString = {
  732.   ["Slowest"] = "0.3",
  733.   ["Slower"] = "0.6",
  734.   ["Slow"] = "0.8",
  735.   ["Normal"] = "1.0",
  736.   ["Fast"] = "1.2",
  737.   ["Faster"] = "1.4",
  738.   ["Fastest"] = "1.7"
  739. }
  740.  
  741. function printBee(beeData)
  742.   log(beeData["slot"] < 10 and beeData["slot"].." " or beeData["slot"])
  743.   if (beeData["type"] == "princess") then
  744.     log("P ")
  745.   else
  746.     log("d ")
  747.   end
  748.   log(beeData["speciesPrimary"]:gsub("bees%.species%.",""):sub(1,3)..":"..beeData["speciesSecondary"]:gsub("bees%.species%.",""):sub(1,3).." ")
  749.   log(tostring(beeData["fertility"]).." ")
  750.   log(speedString[beeData["speed"]].." ")
  751.   if beeData["diurnal"] then
  752.     log("d ")
  753.   else
  754.     log("  ")
  755.   end
  756.   if beeData["nocturnal"] then
  757.     log("n ")
  758.   else
  759.     log("  ")
  760.   end
  761.   if beeData["tolerantFlyer"] then
  762.     log("f ")
  763.   else
  764.     log("  ")
  765.   end
  766.   if beeData["caveDwelling"] then
  767.     log("c ")
  768.   else
  769.     log("  ")
  770.   end
  771.   log(toleranceString[beeData["temperatureTolerance"]])
  772.   log(toleranceString[beeData["humidityTolerance"]])
  773.   if beeData.score then
  774.     logLine(string.format("%5.1d", beeData.score).." ")
  775.   else
  776.     logLine()
  777.   end
  778. end
  779.  
  780. function dropExcess(droneData)
  781.   print("dropping excess...")
  782.   local count = 0
  783.   for i = 1, 16 do
  784.     if turtle.getItemCount(i) > 0 then
  785.       -- check for untargeted species
  786.       if droneData[i] and (not bees[droneData[i]["speciesPrimary"]].targeted
  787.           or not bees[droneData[i]["speciesSecondary"]].targeted) then
  788.         turtle.select(i)
  789.         turtle.dropDown()
  790.       else
  791.         count = count + 1
  792.       end
  793.       -- drop drones over 9 to clear space for newly bred bees and product
  794.       if count > 9 then
  795.         turtle.select(i)
  796.         turtle.dropDown()
  797.         count = count - 1
  798.       end
  799.     end
  800.   end  
  801. end
  802.  
  803. function isPurebred(princessData, droneData)
  804.   -- check if princess and drone are exactly the same and no chance for mutation
  805.   if princessData["speciesPrimary"] ~= princessData["speciesSecondary"] then
  806.     return false
  807.   end
  808.   for key, value in pairs(princessData) do
  809.     if value ~= droneData[key] and key ~= "territory" and key ~= "type" and key ~= "slot" then
  810.       return false
  811.     end
  812.   end
  813.   return true
  814. end
  815.  
  816. function getUnknown(princessData, droneData)
  817.   -- lists species that are not in the bee graph
  818.   local unknownSpecies = {}
  819.   if not bees[princessData["speciesPrimary"]] then
  820.     table.insert(unknownSpecies, princessData["speciesPrimary"])
  821.   end
  822.   if not bees[princessData["speciesSecondary"]] then
  823.     table.insert(unknownSpecies, princessData["speciesSecondary"])
  824.   end
  825.   for _, beeData in pairs(droneData) do
  826.     if not bees[beeData["speciesPrimary"]] then
  827.       table.insert(unknownSpecies, beeData["speciesPrimary"])
  828.     end
  829.     if not bees[beeData["speciesSecondary"]] then
  830.       table.insert(unknownSpecies, beeData["speciesSecondary"])
  831.     end
  832.   end
  833.   return unknownSpecies
  834. end
  835.  
  836. -- targeting -------------------------------------------------------------------
  837.  
  838. -- set species and all parents to targeted
  839. function targetBee(name)
  840.   local bee = bees[name]
  841.   if bee and not bee.targeted then
  842.     bee.targeted = true
  843.     for i, parents in ipairs(bee.mutateFrom) do
  844.       for j, parent in ipairs(parents) do
  845.         targetBee(parent)
  846.       end
  847.     end
  848.   end
  849. end
  850.  
  851. -- set bee graph entry to targeted if species was specified on the command line
  852. -- otherwise set all entries to targeted
  853. tArgs = { ... }
  854. if #tArgs > 0 then
  855.   logLine("targeting bee species:")
  856.   for i, target in ipairs(tArgs) do
  857.     targetBee(target)
  858.     for name, data in pairs(bees) do
  859.       if data.targeted and data.score > 1 then
  860.         logLine(name .. string.rep(" ", 20-#name), data.score)
  861.       end
  862.     end
  863.   end
  864. else
  865.   for _, beeData in pairs(bees) do
  866.     beeData.targeted = true
  867.   end
  868. end
  869.  
  870. -- breeding loop ---------------------------------------------------------------
  871.  
  872. logLine("Clearing system...")
  873. clearSystem()
  874. while true do
  875.   ditchProduct()
  876.   countBees()
  877.   princessData, droneData = analyzeBees()
  878.   if princessData then
  879.     if isPurebred(princessData, droneData[2]) then
  880.       logLine("Bees are purebred")
  881.       turtle.turnRight()
  882.       break
  883.     end
  884.     local unknownSpecies = getUnknown(princessData, droneData)
  885.     if #unknownSpecies > 0 then
  886.       logLine("Please add new species to bee graph:")
  887.       for _, species in ipairs(unknownSpecies) do
  888.         logLine("  "..species)
  889.       end
  890.       turtle.turnRight()
  891.       break
  892.     end
  893.     breedBees(1, 2)
  894.     dropExcess(droneData)
  895.   end
  896.   getBees()
  897. end
  898. logFile.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement