Advertisement
Guest User

Bee Breeding with Attributes (credit to Direwolf20 for idea)

a guest
Jul 19th, 2013
1,218
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 15.64 KB | None | 0 0
  1. -- BeeAnalyzer 4.0
  2. -- Original code by Direwolf20
  3. -- Hotfix 1 by Mandydax
  4. -- Hotfix 2 by Mikeyhun/MaaadMike
  5. -- 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.  
  11. local targetSpecies = { ... }
  12.  
  13. local currslot = 1
  14. local princess = 0
  15. local bestDrone = 0
  16. local data={}
  17. local currData = {}
  18. local princessData = {}
  19. local droneData = {}
  20. local countBees = 0
  21. local beeTable = {}
  22. local currScore = 0
  23. local toleranceTable = {}
  24. local toleranceString = {}
  25. local needsUpdate = ""
  26. local needPrincess = false
  27.  
  28. s = peripheral.wrap("right")
  29.  
  30. -- Scores for all bees
  31.  
  32. -- Mundane Bees
  33. beeTable["Forest"] = 1
  34. beeTable["Meadows"] = 1
  35. beeTable["Modest"] = 2
  36. beeTable["Tropical"] = 2
  37. beeTable["Wintry"] = 2
  38. beeTable["Marshy"] = 2
  39. beeTable["Embittered"] = 2
  40.  
  41. -- End Branch
  42. beeTable["Ender"] = 2
  43.  
  44. -- Common Branch
  45. beeTable["Common"] = 2
  46. beeTable["Cultivated"] = 4
  47.  
  48. -- Noble Branch
  49. beeTable["Noble"] = 8
  50. beeTable["Majestic"] = 16
  51. beeTable["Imperial"] = 32
  52.  
  53. -- Industrious Branch
  54. beeTable["Diligent"] = 8
  55. beeTable["Unweary"] = 16
  56. beeTable["Industrious"] = 32
  57.  
  58. -- Heroic Branch
  59. beeTable["Steadfast"] = 8
  60. beeTable["Valiant"] = 16
  61. beeTable["Heroic"] = 32
  62.  
  63. -- Infernal Branch
  64. beeTable["Sinister"] = 8
  65. beeTable["Fiendish"] = 16
  66. beeTable["Demonic"] = 32
  67.  
  68. -- Austere Branch
  69. beeTable["Frugal"] = 16
  70. beeTable["Austere"] = 32
  71.  
  72. -- Tropical Branch
  73. beeTable["Exotic"] = 16
  74. beeTable["Edenic"] = 32
  75.  
  76. -- Wintry Branch
  77. beeTable["Icy"] = 16
  78. beeTable["Glacial"] = 32
  79. beeTable["Frigid"] = 16
  80. beeTable["Absolute"] = 32
  81.  
  82. -- Festive Branch
  83. beeTable["Leporine"] = 32
  84. beeTable["Merry"] = 32
  85. beeTable["Tipsy"] = 32
  86. beeTable["Celebratory"] = 64
  87.  
  88. -- Agrarian Branch
  89. beeTable["Rural"] = 8
  90. beeTable["Farmed"] = 16
  91.  
  92. -- Boggy Branch
  93. beeTable["Swamp"] = 16
  94. beeTable["Boggy"] = 32
  95. beeTable["Fungal"] = 64
  96.  
  97. -- Extra Bees
  98.  
  99. -- Agricultural Branch
  100. beeTable["Fermented"] = 16
  101. beeTable["Bovine"] = 16
  102. beeTable["Caffeine"] = 16
  103. beeTable["Citrus"] = 32
  104. beeTable["Minty"] = 32
  105.  
  106. -- Barren Branch
  107. beeTable["Arid"] = 8
  108. beeTable["Barren"] = 16
  109. beeTable["Desolate"] = 32
  110.  
  111. -- Hostile Branch
  112. beeTable["Decaying"] = 64
  113. beeTable["Skeletal"] = 64
  114. beeTable["Creepy"] = 64
  115.  
  116. -- Rocky Branch
  117. beeTable["Rocky"] = 2
  118. beeTable["Tolerant"] = 8
  119. beeTable["Hardy"] = 16
  120. beeTable["Resilient"] = 32
  121.  
  122. -- Rusty Branch
  123. beeTable["Rusty"] = 64
  124. beeTable["Corroded"] = 64
  125. beeTable["Tarnished"] = 64
  126. beeTable["Leaden"] = 64
  127.  
  128. -- Metallic Branch
  129. beeTable["Lustered"] = 64
  130. beeTable["Galvanized"] = 128
  131. beeTable["Invincible"] = 64
  132.  
  133. -- Alloyed Branch
  134. beeTable["Impregnable"] = 64
  135. beeTable["Resolute"] = 128
  136. beeTable["Brazen"] = 256
  137. beeTable["Fortified"] = 128
  138. beeTable["Lustrous"] = 64
  139.  
  140. -- Precious Branch
  141. beeTable["Shining"] = 128
  142. beeTable["Glittering"] = 256
  143. beeTable["Precious"] = 512
  144. beeTable["Valuable"] = 512
  145.  
  146. -- Mineral Branch
  147. beeTable["Lapis"] = 64
  148. beeTable["Sodalite"] = 128
  149. beeTable["Pyrite"] = 128
  150. beeTable["Bauxite"] = 64
  151. beeTable["Cinnabar"] = 64
  152. beeTable["Sphalerite"] = 128
  153.  
  154. -- Gemstone Branch
  155. beeTable["Emerald"] = 128
  156. beeTable["Ruby"] = 256
  157. beeTable["Sapphire"] = 256
  158. beeTable["Olivine"] = 256
  159. beeTable["Diamond"] = 512
  160.  
  161. -- Nuclear Branch
  162. beeTable["Unstable"] = 64
  163. beeTable["Nuclear"] = 128
  164. beeTable["Radioactive"] = 256
  165.  
  166. -- Historic Branch
  167. beeTable["Ancient"] = 16
  168. beeTable["Primeval"] = 32
  169. beeTable["Prehistoric"] = 64
  170. beeTable["Relic"] = 128
  171.  
  172. -- Fossilized Branch
  173. beeTable["Fossiled"] = 64
  174. beeTable["Resinous"] = 64
  175. beeTable["Oily"] = 64
  176. beeTable["Preserved"] = 64
  177.  
  178. -- Refined Branch
  179. beeTable["Distilled"] = 128
  180. beeTable["Refined"] = 256
  181. beeTable["Tarry"] = 512
  182. beeTable["Elastic"] = 512
  183.  
  184. -- Aquatic Branch
  185. beeTable["Water"] = 2
  186. beeTable["River"] = 8
  187. beeTable["Ocean"] = 8
  188. beeTable["Stained"] = 16
  189.  
  190. -- Saccharine Branch
  191. beeTable["Sweetened"] = 16
  192. beeTable["Sugary"] = 32
  193. beeTable["Fruity"] = 64
  194.  
  195. -- Classical Branch
  196. beeTable["Marbled"] = 2
  197. beeTable["Gothic"] = 64
  198. beeTable["Renaissance"] = 128
  199. beeTable["Classical"] = 256
  200.  
  201. -- Volcanic Branch
  202. beeTable["Angry"] = 16
  203. beeTable["Furious"] = 32
  204. beeTable["Volcanic"] = 64
  205. beeTable["Glowering"] = 64
  206.  
  207. -- Viscous Branch
  208. beeTable["Viscous"] = 32
  209. beeTable["Glutinous"] = 64
  210. beeTable["Sticky"] = 128
  211.  
  212. -- Virulent Branch
  213. beeTable["Malicious"] = 16
  214. beeTable["Infectious"] = 32
  215. beeTable["Virulent"] = 64
  216.  
  217. -- Caustic Branch
  218. beeTable["Corrosive"] = 128
  219. beeTable["Caustic"] = 256
  220. beeTable["Acidic"] = 512
  221.  
  222. -- Energetic Branch
  223. beeTable["Excited"] = 32
  224. beeTable["Energetic"] = 64
  225. beeTable["Ecstatic"] = 128
  226.  
  227. -- Shadow Branch
  228. beeTable["Shadowed"] = 64
  229. beeTable["Darkened"] = 128
  230. beeTable["Abyssmal"] = 256
  231.  
  232. -- Primary Branch
  233. beeTable["Maroon"] = 32
  234. beeTable["Saffron"] = 32
  235. beeTable["Prussian"] = 32
  236. beeTable["Natural"] = 32
  237. beeTable["Ebony"] = 32
  238. beeTable["Bleached"] = 32
  239. beeTable["Sepia"] = 32
  240.  
  241. -- Secondary Branch
  242. beeTable["Amber"] = 64
  243. beeTable["Turquoise"] = 64
  244. beeTable["Indigo"] = 64
  245. beeTable["Slate"] = 64
  246. beeTable["Azure"] = 64
  247. beeTable["Lavender"] = 64
  248. beeTable["Lime"] = 64
  249.  
  250. -- Tertiary Branch
  251. beeTable["Fuchsia"] = 128
  252. beeTable["Ashen"] = 128
  253.  
  254. -- Hungry Branch
  255. beeTable["Hungry"] = 16
  256. beeTable["Starved"] = 32
  257. beeTable["Ravenous"] = 64
  258.  
  259. -- Confused Branch
  260. beeTable["Dazed"] = 64
  261. beeTable["Irrational"] = 128
  262. beeTable["Delirious"] = 256
  263.  
  264. -- Forestry Branch
  265. beeTable["Pulped"] = 32
  266. beeTable["Spoiled"] = 64
  267. beeTable["Decomposed"] = 128
  268.  
  269. -- Wooden Branch
  270. beeTable["Wooden"] = 16
  271. beeTable["Lumbered"] = 32
  272. beeTable["Timbered"] = 64
  273.  
  274. -- Beastly Branch
  275. beeTable["Jaded"] = 256
  276.  
  277. -- Thaumic Bees
  278.  
  279. -- Arcane Branch
  280. beeTable["Esoteric"] = 64
  281. beeTable["Mysterious"] = 128
  282. beeTable["Arcane"] = 256
  283.  
  284. -- Supernatural Branch
  285. beeTable["Charmed"] = 32
  286. beeTable["Enchanted"] = 64
  287. beeTable["Supernatural"] = 128
  288.  
  289. -- Scholarly Branch
  290. beeTable["Pupil"] = 512
  291. beeTable["Scholarly"] = 1024
  292. beeTable["Savant"] = 2048
  293.  
  294. -- Thaumic Branch
  295. beeTable["Stark"] = 512
  296. beeTable["Aura"] = 1024
  297. beeTable["Ignis"] = 1024
  298. beeTable["Aqua"] = 1024
  299. beeTable["Solum"] = 1024
  300. beeTable["Praecantatio"] = 1024
  301.  
  302. -- Skulking Branch
  303. beeTable["Skulking"] = 256
  304. beeTable["Brainy"] = 512
  305. beeTable["Gossamer"] = 512
  306. beeTable["Wispy"] = 1024
  307. beeTable["Batty"] = 512
  308. beeTable["Ghastly"] = 512
  309.  
  310. -- Aware Branch
  311. beeTable["Aware"] = 64
  312. beeTable["Vis"] = 128
  313. beeTable["Pure"] = 256
  314. beeTable["Flux"] = 256
  315. beeTable["Node"] = 512
  316. beeTable["Rejuvenating"] = 256
  317.  
  318. -- Time Branch
  319. beeTable["Timely"] = 128
  320. beeTable["Lordly"] = 256
  321. beeTable["Doctoral"] = 512
  322.  
  323. -- Soulful Branch
  324. beeTable["Spirit"] = 128
  325. beeTable["Soul"] = 256
  326.  
  327. -- Alchemical Branch
  328. beeTable["Minium"] = 256
  329.  
  330. -- Metallic Branch
  331. beeTable["Iron"] = 64
  332. beeTable["Copper"] = 64
  333. beeTable["Tin"] = 64
  334. beeTable["Silver"] = 64
  335. beeTable["Lead"] = 64
  336. beeTable["Gold"] = 128
  337.  
  338. -- Gem Branch
  339. beeTable["Diamond"] = 512
  340. beeTable["Emerald"] = 128
  341.  
  342. -- Fleshy Branch
  343. beeTable["Poultry"] = 512
  344. beeTable["Beefy"] = 512
  345. beeTable["Porcine"] = 512
  346.  
  347. -- Only scores species that you specify on the command line
  348. local targeting = false
  349. local targetFound = false
  350. if #targetSpecies > 0 then
  351.   for key, value in pairs(beeTable) do
  352.     targetFound = false
  353.     for i, target in ipairs(targetSpecies) do
  354.       if key == target then
  355.         print("Targeting "..key.." species.")
  356.         targeting = true
  357.         targetFound = true
  358.         break
  359.       end
  360.     end
  361.     if not targetFound then
  362.       beeTable[key] = 0
  363.     end
  364.   end
  365.   if not targeting then
  366.     print("Did not find target species")
  367.     return
  368.   end
  369. end
  370.  
  371. -- Fix for some versions returning bees.species.*
  372. function fixName(name)
  373.   return name:gsub("bees%.species%.",""):gsub("^.", string.upper)
  374. end
  375.  
  376. toleranceTable["NONE"] = 0
  377. toleranceTable["UP_1"] = 1
  378. toleranceTable["UP_2"] = 2
  379. toleranceTable["DOWN_1"] = 1
  380. toleranceTable["DOWN_2"] = 2
  381. toleranceTable["BOTH_1"] = 2
  382. toleranceTable["BOTH_2"] = 4
  383.  
  384. toleranceString["NONE"] = "    "
  385. toleranceString["UP_1"] = " +1 "
  386. toleranceString["UP_2"] = " +2 "
  387. toleranceString["DOWN_1"] = " -1 "
  388. toleranceString["DOWN_2"] = " -2 "
  389. toleranceString["BOTH_1"] = "+-1 "
  390. toleranceString["BOTH_2"] = "+-2 "
  391.  
  392.  
  393. function getBees()
  394.   io.write("waiting for bees.")
  395.   -- catalog bees in own inventory
  396.   local free = {}
  397.   for i = 1,16 do
  398.     turtle.select(i)
  399.     if turtle.getItemCount(i) > 0 then
  400.       countBees = countBees + 1
  401.       if #free > 0 then
  402.         j = table.remove(free, 1)
  403.         turtle.transferTo(j)
  404.         table.insert(free, i)
  405.       end
  406.     else
  407.       table.insert(free, i)
  408.     end
  409.   end
  410.   -- get any bees from apiary
  411.   if countBees < 2 or needPrincess then
  412.     turtle.select(1)
  413.     while not turtle.suck() do
  414.       sleep(10)
  415.       io.write(".")
  416.     end
  417.     countBees = countBees + 1
  418.   end
  419.   for i = 1,6 do
  420.     if turtle.suck() then countBees = countBees + 1 end
  421.   end
  422.   print()
  423. end
  424.  
  425. function returnBees()
  426.    turtle.select(princess)
  427.    s.dropSneaky(1,1)
  428.    turtle.select(bestDrone)
  429.    s.dropSneaky(0,1)
  430. end
  431.  
  432. function ditchCombs()  
  433.   turtle.turnLeft()
  434.   m = peripheral.wrap("front")
  435.   for i = 1,8 do
  436.     turtle.suck()
  437.     while (not m.isBee()) and (turtle.getItemCount(i) > 0) do
  438.       turtle.select(i)
  439.       turtle.drop()
  440.       if not m.isBee() then
  441.         turtle.suck()
  442.         turtle.dropDown()
  443.         turtle.select(countBees)
  444.         turtle.transferTo(i, 1)
  445.         countBees = countBees - 1
  446.       end
  447.     end
  448.   end
  449.   turtle.turnRight()
  450. end
  451.  
  452. function scanBees()
  453.    turtle.turnLeft()
  454.    turtle.turnLeft()
  455.    for i = 1, countBees do
  456.      turtle.select(i)
  457.      turtle.drop()
  458.    end
  459. end
  460.  
  461. function determineBest(slot)
  462.   local primScore = beeTable[data["speciesPrimary"]]
  463.   local secScore = beeTable[data["speciesSecondary"]]
  464.   if primScore == nil or secScore == nil then
  465.     needsUpdate = data["speciesPrimary"]..":"..data["speciesSecondary"]
  466.   end
  467.   primScore = (primScore ~= nil and primScore or 0)
  468.   secScore = (secScore ~= nil and secScore or 0)
  469.   local useNew = false
  470.   local score = 0
  471.   score = primScore + secScore
  472.   if(bestDrone == 0) then
  473.     useNew = true
  474.   else
  475.     if (score > currScore) then
  476.       useNew = true
  477.     elseif (score == currScore) then
  478.       if data["fertility"] > currData["fertility"] then
  479.         useNew = true
  480.       elseif data["fertility"] < currData["fertility"] then
  481.         useNew = false
  482.  
  483.       elseif data["speed"] > currData["speed"] then
  484.         useNew = true
  485.       elseif data["speed"] < currData["speed"] then
  486.         useNew = false
  487.  
  488.       elseif data["nocturnal"] and not currData["nocturnal"] then
  489.         useNew = true
  490.       elseif not data["nocturnal"] and currData["nocturnal"] then
  491.         useNew = false
  492.  
  493.       elseif data["tolerantFlyer"] and not currData["tolerantFlyer"] then
  494.         useNew = true
  495.       elseif not data["tolerantFlyer"] and currData["tolerantFlyer"] then
  496.         useNew = false
  497.  
  498.       elseif data["caveDwelling"] and not currData["caveDwelling"] then
  499.         useNew = true
  500.       elseif not data["caveDwelling"] and currData["caveDwelling"] then
  501.         useNew = false
  502.  
  503.       elseif toleranceTable[data["toleranceTemperature"]] > toleranceTable[currData["toleranceTemperature"]] then
  504.         useNew = true
  505.       elseif toleranceTable[data["toleranceTemperature"]] < toleranceTable[currData["toleranceTemperature"]] then
  506.         useNew = false
  507.  
  508.       elseif toleranceTable[data["toleranceHumidity"]] > toleranceTable[currData["toleranceHumidity"]] then
  509.         useNew = true
  510.       elseif toleranceTable[data["toleranceHumidity"]] < toleranceTable[currData["toleranceHumidity"]] then
  511.         useNew = false
  512.  
  513.       end
  514.     end
  515.   end
  516.   if useNew then
  517.     bestDrone = slot
  518.     currScore = score
  519.     currData = data
  520.   end
  521.   return score, useNew
  522. end
  523.  
  524. function log2(num)
  525.   return num == 0 and 0.0 or math.log(num)/math.log(2)
  526. end
  527.  
  528. function analyzeBees()
  529.   print("analyzing "..countBees.." bees...")
  530.   local score = 0
  531.   local useNew = false
  532.   print()
  533.   print("typ species f spd n f c tmp hmd score")
  534.   print("-|-|-------|-|---|-|-|-|---|---|-----")
  535.   for i = 1, countBees do
  536.     turtle.select(i)
  537.     while not s.suckSneaky(0,1) do
  538.       sleep(5)
  539.     end
  540.     turtle.turnRight()
  541.     turtle.drop()
  542.     m = peripheral.wrap("front")
  543.     data = m.analyze()
  544.     data["speciesPrimary"] = fixName(data["speciesPrimary"])
  545.     data["speciesSecondary"] = fixName(data["speciesSecondary"])
  546.     io.write(i.." ")
  547.     if (data["type"] == "princess") then
  548.       princess = i
  549.       princessData = data
  550.       io.write("P ")
  551.       useNew = false
  552.       score = 0
  553.     else
  554.       io.write("d ")
  555.       score, useNew = determineBest(i)
  556.     end
  557.     io.write(data["speciesPrimary"]:gsub("bees%.species%.",""):sub(1,3)..":"..data["speciesSecondary"]:gsub("bees%.species%.",""):sub(1,3).." ")
  558.     io.write(tostring(data["fertility"]).." ")
  559.     io.write(data["speed"] == 1 and "1.0 " or tostring(data["speed"]).." ")
  560.     if data["nocturnal"] then
  561.       io.write("n ")
  562.     else
  563.       io.write("  ")
  564.     end
  565.     if data["tolerantFlyer"] then
  566.       io.write("f ")
  567.     else
  568.       io.write("  ")
  569.     end
  570.     if data["caveDwelling"] then
  571.       io.write("c ")
  572.     else
  573.       io.write("  ")
  574.     end
  575.     io.write(toleranceString[data["toleranceTemperature"]])
  576.     io.write(toleranceString[data["toleranceHumidity"]])
  577.     io.write(string.format("%5.1d", log2(score)).." ")
  578.     if useNew then
  579.       io.write("*")
  580.       droneData = data
  581.     end
  582.     print()
  583.     turtle.suck()
  584.     turtle.turnLeft()
  585.   end
  586.   if princess ~= 0 then
  587.     print("breeding princess ("..princess..") with drone ("..bestDrone..")")
  588.   else
  589.     print("no princess")
  590.   end
  591.   print()
  592. end
  593.  
  594. function dropExcess()
  595.   for i = 1, 16 do
  596.     turtle.select(i)
  597.     turtle.dropDown()
  598.    end  
  599. end
  600.  
  601. -- Drop same drones so they won't interfere
  602. function dropDupe()
  603.   for i = 1, countBees do
  604.     turtle.select(i)
  605.     local count = turtle.getItemCount(i)
  606.     if count > 1 then
  607.       print("dropping "..tostring(turtle.getItemCount(i)-1).." excess drones...")
  608.       turtle.dropDown(count - 1)
  609.     end
  610.   end
  611.   turtle.select(1)
  612. end
  613.  
  614. function isPurebred()
  615.   if princessData["speciesPrimary"] ~= princessData["speciesSecondary"] then
  616.     return false
  617.   end
  618.   for key, value in pairs(princessData) do
  619.     if value ~= droneData[key] and key ~= "territory" and key ~= "type" then
  620.       return false
  621.     end
  622.   end
  623.   return true
  624. end
  625. ------=============================
  626.  
  627. -- clear out system
  628. while turtle.detect() do
  629.   turtle.turnRight()
  630. end
  631. local i = 1
  632. turtle.select(i)
  633. while turtle.getItemCount(i) > 0 do
  634.   i = i + 1
  635.   turtle.select(i)
  636. end
  637. turtle.turnRight()
  638. while s.suckSneaky(0,1) do
  639.   i = i + 1
  640.   turtle.select(i)
  641. end
  642. turtle.turnRight()
  643. turtle.suck()
  644. turtle.turnRight()
  645. while turtle.suck() do
  646. end
  647.  
  648. -- start breeding loop
  649. while true do
  650.   currslot = 1
  651.   princess = 0
  652.   bestDrone = 0
  653.   data = {}
  654.   currData = {}
  655.   princessData = {}
  656.   droneData = {}
  657.   countBees = 0
  658.   currScore = 0
  659.  
  660.   getBees()
  661.   ditchCombs()
  662.   if (turtle.getItemCount(2) > 0) then
  663.     dropDupe()
  664.     scanBees()
  665.     analyzeBees()
  666.     if countBees <= 2 and isPurebred() then
  667.       print("Bees are purebred")
  668.       turtle.turnLeft()
  669.       return
  670.     end
  671.     if needsUpdate == "" then
  672.       turtle.turnRight()
  673.       turtle.turnRight()
  674.       if princess ~= 0 then
  675.         returnBees()
  676.         dropExcess()
  677.       else
  678.         needPrincess = true
  679.       end
  680.     else
  681.       turtle.turnLeft()
  682.       print("Please add new species to bee table: "..needsUpdate)
  683.       return
  684.     end
  685.   end
  686.   sleep(5)
  687. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement