View difference between Paste ID: EuaYMxCx and dEdTNP64
SHOW: | | - or go back to the newest paste.
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