View difference between Paste ID: X3ZT6F33 and 7n9cyzSn
SHOW: | | - or go back to the newest paste.
1
	
2
3
    -- BeeAnalyzer x     
4
	-- maybe i replace the output with simple breeding bee-bee... though it has score and is sorted now
5
6
7
    invmod = peripheral.wrap("right")
8
	targetedSpecies = ""
9
	     
10
    -- the bee graph ---------------------------------------------------------------
11
     
12
    bees = {}
13
     
14
    function addParent(parent, offspring)
15
      if not bees[parent] then
16
        bees[parent] = {
17
          --name = parent,
18-
          score = nil,
18+
          score = 0,
19
          mutateFrom = {}
20
        }
21
      end
22
    end
23
     
24
    function addOffspring(offspring, parentss)
25
      if bees[offspring] then
26
        for i, parents in ipairs(parentss) do
27
          table.insert(bees[offspring].mutateFrom, parents)
28
        end
29
      else
30
        bees[offspring] = {
31-
          score = nil,
31+
          score = 0,
32
          mutateFrom = parentss
33
        }
34
      end
35
      for i, parents in ipairs(parentss) do
36
        for i, parent in ipairs(parents) do
37
          addParent(parent, offspring)
38
        end
39
      end
40
    end
41
     
42
	 
43
44
     
45
    -- produce combinations from 1 or 2 lists
46
    function choose(list, list2)
47
      local newList = {}
48
      if list2 then
49
        for i = 1, #list2 do
50
          for j = 1, #list do
51
            if list[j] ~= list[i] then
52
              table.insert(newList, {list[j], list2[i]})
53
            end
54
          end
55
        end
56
      else
57
        for i = 1, #list do
58
          for j = i, #list do
59
            if list[i] ~= list[j] then
60
              table.insert(newList, {list[i], list[j]})
61
            end
62
          end
63
        end
64
      end
65
      return newList
66
    end
67
     
68
    -- Forestry Bees ---------------------------------------------------------------
69
     
70
    -- Apis Branch
71
    addOffspring("Common", choose({"Forest", "Meadows", "Modest", "Marbled", "Tropical", "Wintry", "Marshy", "Water", "Rocky", "Embittered", "Unusual", "Mystical", "Sorcerous", "Attuned"}))
72
    addOffspring("Cultivated", choose({"Common"}, {"Forest", "Meadows", "Modest", "Marbled", "Tropical", "Wintry", "Marshy", "Water", "Rocky", "Embittered", "Unusual", "Mystical", "Sorcerous", "Attuned"}))
73
    -- Noble Branch
74
    addOffspring("Noble", {{"Cultivated", "Common"}})
75
    addOffspring("Majestic", {{"Noble", "Cultivated"}})
76
    addOffspring("Imperial", {{"Majestic", "Noble"}})
77
    -- Industrious Branch
78
    addOffspring("Diligent", {{"Cultivated", "Common"}})
79
    addOffspring("Unweary", {{"Diligent", "Cultivated"}})
80
    addOffspring("Industrious", {{"Unweary", "Diligent"}})
81
    -- Heroic Branch
82
    addOffspring("Heroic", {{"Steadfast", "Valiant"}})
83
    -- Infernal Branch
84
    addOffspring("Sinister", {{"Cultivated", "Modest"}, {"Cultivated", "Tropical"}})
85
    addOffspring("Fiendish", {{"Sinister", "Cultivated"}, {"Sinister", "Modest"}, {"Sinister", "Tropical"}})
86
    addOffspring("Demonic", {{"Fiendish", "Sinister"}})
87
    -- Austere Branch
88
    addOffspring("Frugal", {{"Sinister", "Modest"}, {"Fiendish", "Modest"}})
89
    addOffspring("Austere", {{"Frugal", "Modest"}})
90
	
91
    -- Tropical Branch
92
    addOffspring("Exotic", {{"Austere", "Tropical"}})
93
    addOffspring("Edenic", {{"Exotic", "Tropical"}})
94
	
95
    -- Frozen Branch
96
    addOffspring("Icy", {{"Industrious", "Wintry"}})
97
    addOffspring("Glacial", {{"Icy", "Wintry"}})
98
    addOffspring("Frigid", {{"Diligent", "Wintry"}})
99
    addOffspring("Absolute", {{"Frigid", "Ocean"}})
100
    -- Festive Branch
101
    addOffspring("Celebratory", {{"Austere", "Excited"}})
102
    addOffspring("Leporine", {{"Meadows", "Forest"}})
103
    addOffspring("Merry", {{"Wintry", "Forest"}})
104
    addOffspring("Tipsy", {{"Wintry", "Meadows"}})
105
106
    -- Agrarian Branch
107
    addOffspring("Rural", {{"Diligent", "Meadows"}})
108
    addOffspring("Farmed", {{"Rural", "Cultivated"}})
109
	
110
    -- Boggy Branch
111
    addOffspring("Swamp", {{"Common", "Marshy"}})
112
    addOffspring("Boggy", {{"Swamp", "Marshy"}})
113
    addOffspring("Fungal", {{"Boggy", "Swamp"}})
114
		
115
    -- Agricultural Branch
116
    addOffspring("Fermented", {{"Rural", "Fruity"}})
117
    addOffspring("Bovine", {{"Rural", "Water"}})
118
    addOffspring("Caffeine", {{"Rural", "Tropical"}})
119
    addOffspring("Citrus", {{"Farmed", "Modest"}})
120
    addOffspring("Minty", {{"Farmed", "Tropical"}})
121
	
122
    -- Barren Branch
123
    addOffspring("Arid", {{"Meadows", "Modest"}})
124
    addOffspring("Barren", {{"Arid", "Common"}})
125
    addOffspring("Desolate", {{"Barren", "Arid"}})
126
127
	
128
    -- Hostile Branch
129
    addOffspring("Skeletal", {{"Desolate", "Frugal"}})
130
    addOffspring("Decaying", {{"Desolate", "Modest"}})
131
    addOffspring("Creepy", {{"Desolate", "Austere"}})
132
    -- Rocky Branch
133
    addOffspring("Tolerant", {{"Diligent", "Rocky"}})
134
    addOffspring("Hardy", {{"Tolerant", "Rocky"}})
135
    addOffspring("Resilient", {{"Hardy", "Tolerant"}})
136
	
137
    -- Rusty Branch
138
    addOffspring("Rusty", {{"Resilient", "Diligent"}})
139
    addOffspring("Corroded", {{"Resilient", "Diligent"}})
140
    addOffspring("Tarnished", {{"Resilient", "Diligent"}})
141
    addOffspring("Leaden", {{"Resilient", "Unweary"}})
142
143
	
144
    -- Metallic Branch
145
    addOffspring("Lustered", {{"Resilient", "Unweary"}})
146
    addOffspring("Galvanized", {{"Tarnished", "Cultivated"}})
147
    addOffspring("Invincible", {{"Resilient", "Ender"}})
148
	
149
    -- Alloyed Branch
150
    addOffspring("Impregnable", {{"Resilient", "Noble"}})
151
    addOffspring("Resolute", {{"Corroded", "Tarnished"}})
152
    addOffspring("Brazen", {{"Corroded", "Galvanized"}})
153
    addOffspring("Fortified", {{"Rusty", "Fossiled"}})
154
    addOffspring("Lustrous", {{"Resilient", "Imperial"}})
155
156
    -- Precious Branch
157
    addOffspring("Shining", {{"Rusty", "Noble"}})
158
    addOffspring("Glittering", {{"Resolute", "Noble"}})
159
    addOffspring("Precious", {{"Glittering", "Shining"}})
160
    addOffspring("Valuable", {{"Glittering", "Ender"}})
161
162
	-- Mineral Branch
163
    addOffspring("Lapis", {{"Resilient", "Water"}})
164
    addOffspring("Sodalite", {{"Lapis", "Diligent"}})
165
    addOffspring("Pyrite", {{"Rusty", "Sinister"}})
166
    addOffspring("Bauxite", {{"Resilient", "Diligent"}})
167
    addOffspring("Cinnabar", {{"Resilient", "Sinister"}})
168
    addOffspring("Sphalerite", {{"Tarnished", "Sinister"}})
169
170
    -- Gemstone Branch
171
    addOffspring("Emerald", {{"Lapis", "Noble"}})
172
    addOffspring("Ruby", {{"Emerald", "Austere"}})
173
    addOffspring("Sapphire", {{"Emerald", "Ocean"}})
174
    addOffspring("Olivine", {{"Emerald", "Ender"}})
175
    addOffspring("Diamond", {{"Sapphire", "Imperial"}})
176
	
177
    -- Nuclear Branch
178
    addOffspring("Unstable", {{"Austere", "Rocky"}})
179
    addOffspring("Nuclear", {{"Unstable", "Rusty"}})
180
    addOffspring("Radioactive", {{"Nuclear", "Glittering"}})
181
    -- Historic Branch
182
    addOffspring("Ancient", {{"Noble", "Diligent"}})
183
    addOffspring("Primeval", {{"Ancient", "Noble"}})
184
    addOffspring("Prehistoric", {{"Primeval", "Majestic"}})
185
    addOffspring("Relic", {{"Prehistoric", "Imperial"}})
186
	
187
    -- Fossilized
188
    addOffspring("Fossiled", {{"Primeval", "Forest"}})
189
    addOffspring("Oily", {{"Primeval", "Modest"}})
190
    addOffspring("Preserved", {{"Primeval", "Boggy"}})
191
    addOffspring("Resinous", {{"Primeval", "Marshy"}})
192
193
    -- Refined Branch
194
    addOffspring("Distilled", {{"Oily", "Industrious"}})
195
    addOffspring("Refined", {{"Distilled", "Oily"}})
196
    addOffspring("Elastic", {{"Refined", "Resinous"}})
197
    addOffspring("Tarry", {{"Refined", "Fossiled"}})
198
199
	
200
    -- Aquatic Branch
201
    addOffspring("River", {{"Common", "Water"}})
202
    addOffspring("Ocean", {{"Common", "Water"}})
203
    addOffspring("Stained", {{"Ocean", "Water"}})
204
205
	
206
    -- Saccharine Branch
207
    addOffspring("Sweetened", {{"Diligent", "Tropical"}})
208
    addOffspring("Sugary", {{"Sweetened", "Diligent"}})
209
    addOffspring("Fruity", {{"Sugary", "Forest"}})
210
	
211
	
212
    -- Volcanic Branch
213
    addOffspring("Angry", {{"Sinister", "Embittered"}})
214
    addOffspring("Furious", {{"Angry", "Embittered"}})
215
    addOffspring("Volcanic", {{"Furious", "Angry"}})
216
    addOffspring("Glowering", {{"Excited", "Angry"}})
217
218
	
219
    -- Viscous Branch
220
    addOffspring("Viscous", {{"Exotic", "Water"}})
221
    addOffspring("Glutinous", {{"Viscous", "Exotic"}})
222
    addOffspring("Sticky", {{"Glutinous", "Viscous"}})
223
	
224
    -- Virulent Branch
225
    addOffspring("Malicious", {{"Sinister", "Tropical"}})
226
    addOffspring("Infectious", {{"Malicious", "Tropical"}})
227
    addOffspring("Virulent", {{"Infectious", "Malicious"}})
228
	
229
    -- Caustic Branch
230
    addOffspring("Corrosive", {{"Virulent", "Sticky"}})
231
    addOffspring("Caustic", {{"Corrosive", "Fiendish"}})
232
    addOffspring("Acidic", {{"Caustic", "Corrosive"}})
233
234
	
235
    -- Energetic Branch
236
    addOffspring("Excited", {{"Cultivated", "Valiant"}})
237
    addOffspring("Energetic", {{"Excited", "Valiant"}})
238
    addOffspring("Ecstatic", {{"Energetic", "Excited"}})
239
240
241
    -- Shadow Branch
242
    addOffspring("Shadowed", {{"Rocky", "Furious"}})
243
    addOffspring("Darkened", {{"Shadowed", "Embittered"}})
244
    addOffspring("Abyssmal", {{"Darkened", "Shadowed"}})
245
     
246
    -- Primary Branch
247
    addOffspring("Bleached", {{"Wintry", "Valiant"}})
248
    addOffspring("Ebony", {{"Rocky", "Valiant"}})
249
    addOffspring("Maroon", {{"Forest", "Valiant"}})
250
    addOffspring("Natural", {{"Tropical", "Valiant"}})
251
    addOffspring("Prussian", {{"Water", "Valiant"}})
252
    addOffspring("Saffron", {{"Meadows", "Valiant"}})
253
    addOffspring("Sepia", {{"Marshy", "Valiant"}})
254
    -- Secondary Branch
255
    addOffspring("Amber", {{"Maroon", "Saffron"}})
256
    addOffspring("Azure", {{"Prussian", "Bleached"}})
257
    addOffspring("Indigo", {{"Maroon", "Prussian"}})
258
    addOffspring("Lavender", {{"Maroon", "Bleached"}})
259
    addOffspring("Lime", {{"Natural", "Bleached"}})
260
    addOffspring("Slate", {{"Ebony", "Bleached"}})
261
    addOffspring("Turquoise", {{"Natural", "Prussian"}})
262
    -- Tertiary Branch
263
    addOffspring("Ashen", {{"Slate", "Bleached"}})
264
    addOffspring("Fuchsia", {{"Indigo", "Lavender"}})
265
     
266
267
	 -- hungry,confused,forestry,wooden branch
268
269
    addOffspring("Hungry", {{"Arid", "Rural"}})
270
    addOffspring("Starved", {{"Barren", "Hungry"}})
271
    addOffspring("Ravenous", {{"Hungry", "Starved"}})
272
    addOffspring("Dazed", {{"Arid", "Edenic"}})
273
    addOffspring("Irrational", {{"Barren", "Dazed"}})
274
    addOffspring("Delirious", {{"Dazed", "Irrational"}})
275
    addOffspring("Pulped", {{"Unweary", "Forest"}})
276
    addOffspring("Spoiled", {{"Pulped", "Decaying"}})
277
    addOffspring("Decomposed", {{"Pulped", "Decaying"}})
278
    addOffspring("Wooden", {{"Diligent", "Forest"}})
279
    addOffspring("Lumbered", {{"Diligent", "Wooden"}})
280
    addOffspring("Timbered", {{"Wooden", "Lumbered"}})
281
	
282
    -- Beastly Branch
283
    addOffspring("Jaded", {{"Ender", "Relic"}})
284
285
     
286
    -- Magic Bees ------------------------------------------------------------------
287
     
288
    -- Arcane Branch
289
    addOffspring("Esoteric", {{"Imperial", "Demonic"}, {"Heroic", "Demonic"}})	
290
    addOffspring("Mysterious", {{"Ender", "Esoteric"}})
291
    addOffspring("Arcane", {{"Mysterious", "Esoteric"}})
292
	
293
    -- Supernatural Branch
294
    addOffspring("Charmed", {{"Diligent", "Valiant"}})
295
    addOffspring("Enchanted", {{"Valiant", "Charmed"}})
296
    addOffspring("Supernatural", {{"Enchanted", "Charmed"}})
297
    -- Scholarly Branch
298
    addOffspring("Pupil", {{"Arcane", "Enchanted"}})
299
    addOffspring("Scholarly", {{"Arcane", "Pupil"}})
300
    addOffspring("Savant", {{"Scholarly", "Pupil"}})
301
302
	
303
    -- Thaumic Branch
304
    addOffspring("Stark", {{"Arcane", "Supernatural"}})
305
306
307
    -- Skulking Branch
308
    addOffspring("Skulking", {{"Mysterious", "Modest"}, {"Mysterious", "Desolate"}})	
309
    addOffspring("Brainy", {{"Skulking", "Sinister"}})		
310
    addOffspring("Gossamer", {{"Skulking", "Supernatural"}, {"Skulking", "Ancient"}})	
311
    addOffspring("Wispy", {{"Gossamer", "Cultivated"}})	
312
    addOffspring("Batty", {{"Skulking", "Frugal"}, {"Skulking", "Rocky"}})	
313
    addOffspring("Ghastly", {{"Skulking", "Austere"}, {"Skulking", "Creepy"}})	
314
315
		
316
    addOffspring("Aware", {{"Demonic", "Edenic"}})			
317
    addOffspring("Vis", {{"Aware", "Arcane"}, {"Aware", "Stark"}})		
318
    addOffspring("Pure", {{"Vis", "Edenic"}})			
319
    addOffspring("Flux", {{"Vis", "Edenic"}})			
320
    addOffspring("Node", {{"Pure", "Flux"}})			
321
    addOffspring("Rejuvenating", {{"Vis", "Energetic"}})			
322
    addOffspring("Timely", {{"Industrious", "Enchanted"}})			
323
    addOffspring("Lordly", {{"Timely", "Imperial"}})			
324
    addOffspring("Doctoral", {{"Timely", "Lordly"}})			
325
    addOffspring("Spirit", {{"Fiendish", "Enchanted"}, {"Fiendish", "Ender"}})		
326
    addOffspring("Soul", {{"Fiendish", "Spirit"}})			
327
    addOffspring("Minium", {{"Sinister", "Mysterious"}, {"Frugal", "Pupil"}})			
328
    addOffspring("Iron", {{"Industrious", "Diligent"}})			
329
    addOffspring("Gold", {{"Minium", "Lead"}})		
330
331
			
332
    addOffspring("Copper", {{"Industrious", "Meadows"}})				
333
    addOffspring("Tin", {{"Industrious", "Forest"}})				
334
    addOffspring("Silver", {{"Imperial", "Modest"}})				
335
    addOffspring("Lead", {{"Industrious", "Copper"}, {"Industrious", "Tin"}, {"Industrious", "Common"}})			
336
    addOffspring("Diamond", {{"Austere", "Gold"}})				
337
    addOffspring("Emerald", {{"Austere", "Silver"}})				
338
    addOffspring("Poultry", {{"Common", "Skulking"}})				
339
    addOffspring("Beefy", {{"Common", "Skulking"}})				
340
    addOffspring("Porcine", {{"Common", "Skulking"}})	
341
342
343
     
344
    -- logging ---------------------------------------------------------------------
345
     
346
    local logFile = fs.open("bee.log", "w")
347
    function log(msg)
348
      msg = msg or ""
349
      logFile.write(tostring(msg))
350
      logFile.flush()
351
      io.write(msg)
352
    end
353
    function logLine(msg)
354
      msg = msg or ""
355
      logFile.write(msg.."\n")
356
      logFile.flush()
357
      io.write(msg.."\n")
358
    end
359
     
360
    -- analyzing functions ---------------------------------------------------------
361
     
362
    -- Fix for some versions returning bees.species.*
363
    function fixName(name)
364
      return name:gsub("bees%.species%.",""):gsub("^.", string.upper)
365
    end
366
     
367
    function clearSystem()
368
      -- orient turtle
369
      while true do
370
        local p = peripheral.wrap("front")
371
        if p and p.isBee then
372
          break
373
        end
374
        turtle.turnRight()
375
      end
376
      -- clear out analyzer
377
      turtle.turnLeft()
378
      while turtle.suckUp() do end
379
      -- clear out beealyzer
380
      turtle.turnRight()
381
      turtle.suck()
382
      -- clear out apiary
383
      turtle.turnRight()
384
      while turtle.suck() do end
385
    end
386
     
387
    function getBees()
388
      -- get bees from apiary
389
      log("waiting for bees.")
390
      turtle.select(1)
391
      while not turtle.suck() do
392
        sleep(10)
393
        log(".")
394
      end
395
      log("*")
396
      while turtle.suck() do
397
        log("*")
398
      end
399
      logLine()
400
    end
401
     
402
    function countBees()
403
      -- spread dups and fill gaps
404
      local count = 0
405
      for i = 1, 16 do
406
        local slotCount = turtle.getItemCount(i)
407
        if slotCount == 1 then
408
          for j = 1, i-1 do
409
            if turtle.getItemCount(j) == 0 then
410
              turtle.select(i)
411
              turtle.transferTo(j)
412
              break
413
            end
414
          end
415
          count = count + 1
416
        elseif slotCount > 1 then
417
          for j = 2, slotCount do
418
            turtle.select(i)
419
            for k = 1, 16 do
420
              if turtle.getItemCount(k) == 0 then
421
                turtle.transferTo(k, 1)
422
              end
423
            end
424
          end
425
          if turtle.getItemCount(i) > 1 then
426
            turtle.dropDown(turtle.getItemCount(i)-1)
427
          end
428
        end
429
      end
430
      return count
431
    end
432
     
433
    function breedBees(princessSlot, droneSlot)
434
       turtle.select(princessSlot)
435
       invmod.dropSneaky(1)
436
       turtle.select(droneSlot)
437
       invmod.dropSneaky(0)
438
    end
439
     
440
    function ditchProduct()  
441
      print("ditching product...")
442
      turtle.turnLeft()
443
      m = peripheral.wrap("front")
444
      for i = 1, 16 do
445
        if turtle.getItemCount(i) > 0 then
446
          turtle.select(i)
447
          turtle.drop()
448
          if not m.isBee() then
449
            turtle.suck()
450
            turtle.dropDown()
451
          else
452
            turtle.suck()
453
          end
454
        end
455
      end
456
      turtle.turnRight()
457
    end
458
     
459
    function scanBees()
460
      log("scanning bees")
461
      turtle.turnLeft()
462
      turtle.turnLeft()
463
      for i = 1, 16 do
464
        if turtle.getItemCount(i) > 0 then
465
          log(".")
466
          turtle.select(i)
467
          invmod.dropSneakyUp(2)
468
          while not turtle.suckUp() do
469
            sleep(1)
470
          end
471
        end
472
      end
473
      logLine()
474
      turtle.turnRight()
475
      turtle.turnRight()
476
    end
477
     
478
    function swapBee(slot1, slot2, freeSlot)
479
      turtle.select(slot1)
480
      turtle.transferTo(freeSlot)
481
      turtle.select(slot2)
482
      turtle.transferTo(slot1)
483
      turtle.select(freeSlot)
484
      turtle.transferTo(slot2)
485
    end  
486
     
487
--if princess has no scored offspring (mutated) ... maybewe want to breed with the highest scored drone (droneScore)
488
--find the highest drone bee we have, find what we need to breed with it
489
--if we have that drone, breed princess with that drone
490
--else find the highest we have in that tree, and repeat
491
--if we dont have any then exit with needbee: bee (tree)
492
493
494
--returns which drone is highest parent for species, or species if available
495
function findAvailableParent(species, droneData)
496
	local droneIndex = 0
497
	local droneScore = 99999
498
499
	for i = 2, 16 do
500
		if droneData[i] then
501
			if droneData[i]["speciesPrimary"] == species or droneData[i]["speciesSecondary"] == species then
502
				droneIndex = i
503-
				droneScore = bee[species].score
503+
				droneScore = bees[species].score
504
				return droneIndex, droneScore
505
			end
506
		end
507
	end
508
	
509-
	for i, parents in ipairs(bee[species].mutateFrom) do
509+
	for i, parents in ipairs(bees[species].mutateFrom) do
510
		index, score = findAvailableParent(parents[1], droneData)
511
		if score < droneScore then
512
			droneIndex = index
513
			droneScore = score
514
		end
515
		index, score = findAvailableParent(parents[2], droneData)
516
		if score < droneScore then
517
			droneIndex = index
518
			droneScore = score
519
		end
520
	end
521
	if droneScore == 99999 then
522
		logLine("Missing bee species: " .. species)
523
	end
524
	return droneIndex, droneScore
525
end
526
527
function analyzeBees()
528
529
	logLine("analyzing bees...")
530
	local freeSlot
531
	local princessSlot
532
	local princessData
533
	local droneData = {}
534
	turtle.turnLeft()
535
	local beealyzer = peripheral.wrap("front")
536
537
	for i = 1, 16 do
538
		if turtle.getItemCount(i) > 0 then
539
			turtle.select(i)
540
			turtle.drop()
541
			local beeData = beealyzer.analyze()        
542
			turtle.suck()
543
			if not beeData["speciesPrimary"] then
544
				print("Bee "..i.." not correctly analyzed")
545
			else
546
				beeData["speciesPrimary"] = fixName(beeData["speciesPrimary"])
547
				beeData["speciesSecondary"] = fixName(beeData["speciesSecondary"])
548
				if beeData["type"] == "princess" then
549
					princessData = beeData
550
					princessSlot = i
551
				else
552
					droneData[i] = beeData
553
				end
554
			end
555
		else
556
			freeSlot = i
557
		end
558
	end
559
560
	if princessData then
561
		if princessSlot ~= 1 then
562
			swapBee(1, princessSlot, freeSlot)
563
			droneData[princessSlot] = droneData[1]
564
			droneData[1] = nil
565
			princessSlot = 1
566
		end
567
568
		-- bubble sort drones
569
		print("sorting drones...")
570
		for i = 2, 16 do
571
			if turtle.getItemCount(i) > 0 and droneData[i] then
572
				droneData[i].score = scoreBee(princessData, droneData[i])
573
				for j = i - 1, 2, -1 do
574
					if droneData[j+1].score > droneData[j].score then
575
						swapBee(j+1, j, freeSlot)
576
						droneData[j+1], droneData[j] = droneData[j], droneData[j+1]
577
					end
578
				end
579
			end
580
		end
581
582
		if droneData[2] and droneData[2].score < 1 then
583
			--no breeding combos found for this princess
584
			i, j = findAvailableParent(targetedSpecies, droneData)
585
586
			if j == 99999 then
587
				droneData[2].score = 0
588
			else
589
				swapBee(2, i, freeSlot)
590
				droneData[2], droneData[i] = droneData[i], droneData[2]
591
			end
592
		end
593
594
		printHeader()
595
		princessData.slot = 1
596
		printBee(princessData)
597
		for i = 2, 16 do
598
			if droneData[i] then
599
				droneData[i].slot = i
600
				printBee(droneData[i])
601
			end
602
		end
603
	end
604
	logLine()
605
	turtle.turnRight()
606
	return princessData, droneData
607
end
608
     
609
610
611
--if drone score is 9999 return 9999 or 10k for pure
612
--find offspring for this combo, return highest scoring offspring ... for each bee, if its cerated from these get its score
613
614
615
function scoreBee(princessData, droneData)
616
617
	local droneSpecies = {droneData["speciesPrimary"], droneData["speciesSecondary"]}
618
	local princessSpecies = {princessData["speciesPrimary"], princessData["speciesSecondary"]}
619
620
	  
621-
	if bee[droneSpecies[1]].score == 9999 and bee[droneSpecies[2]].score == 9999 then
621+
	if bees[droneSpecies[1]].score == 9999 and bees[droneSpecies[2]].score == 9999 then
622
		return 10000
623-
	if bee[droneSpecies[1]].score == 9999 or bee[droneSpecies[2]].score == 9999 then
623+
624
	if bees[droneSpecies[1]].score == 9999 or bees[droneSpecies[2]].score == 9999 then
625
		return 9999
626
	end
627
628
	local droneScore = 0
629
	
630
	for name, beeData in pairs(bees) do
631
		if beeData.score > droneScore then
632
			for i, parents in ipairs(beeData.mutateFrom) do
633
				if princessSpecies[1] == parents[1] or princessSpecies[2] == parents[1] then
634
					if droneSpecies[1] == parents[2] and droneSpecies[2] == parents[2] then
635
						droneScore = beeData.score + 1
636
						break
637
					end
638
					if droneSpecies[1] == parents[2] or droneSpecies[2] == parents[2] then
639
						droneScore = beeData.score
640
						break
641
					end
642
				end
643
				if princessSpecies[1] == parents[2] or princessSpecies[2] == parents[2] then
644
					if droneSpecies[1] == parents[1] and droneSpecies[2] == parents[1] then
645
						droneScore = beeData.score + 1
646
						break
647
					end
648
					if droneSpecies[1] == parents[1] or droneSpecies[2] == parents[1] then
649
						droneScore = beeData.score
650
						break
651
					end
652
				end
653
			end
654
		end
655
	end
656
657
	return droneScore
658
end
659
     
660
    function printHeader()
661
      logLine()
662
      logLine("typ species f spd d n f c tmp hmd score")
663
      logLine("-|-|-------|-|---|-|-|-|-|---|---|-----")
664
    end
665
     
666
    toleranceString = {
667
      ["NONE"] = "    ",
668
      ["UP_1"] = " +1 ",
669
      ["UP_2"] = " +2 ",
670
      ["UP_3"] = " +3 ",
671
      ["DOWN_1"] = " -1 ",
672
      ["DOWN_2"] = " -2 ",
673
      ["DOWN_3"] = " -3 ",
674
      ["BOTH_1"] = "+-1 ",
675
      ["BOTH_2"] = "+-2 ",
676
      ["BOTH_3"] = "+-3 "
677
    }
678
    function printBee(beeData)
679
      log(beeData["slot"] < 10 and beeData["slot"].." " or beeData["slot"])
680
      if (beeData["type"] == "princess") then
681
        log("P ")
682
      else
683
        log("d ")
684
      end
685
      log(beeData["speciesPrimary"]:gsub("bees%.species%.",""):sub(1,3)..":"..beeData["speciesSecondary"]:gsub("bees%.species%.",""):sub(1,3).." ")
686
      log(tostring(beeData["fertility"]).." ")
687
      log(beeData["speed"] == 1 and "1.0 " or tostring(beeData["speed"]).." ")
688
      if beeData["diurnal"] then
689
        log("d ")
690
      else
691
        log("  ")
692
      end
693
      if beeData["nocturnal"] then
694
        log("n ")
695
      else
696
        log("  ")
697
      end
698
      if beeData["tolerantFlyer"] then
699
        log("f ")
700
      else
701
        log("  ")
702
      end
703
      if beeData["caveDwelling"] then
704
        log("c ")
705
      else
706
        log("  ")
707
      end
708
      log(toleranceString[beeData["toleranceTemperature"]])
709
      log(toleranceString[beeData["toleranceHumidity"]])
710
      if beeData.score then
711
        logLine(string.format("%5.1d", beeData.score).." ")
712
      else
713
        logLine()
714
      end
715
    end
716
     
717
    function dropExcess(droneData)
718
      print("dropping excess...")
719
      local count = 0
720
      for i = 1, 16 do
721
        if turtle.getItemCount(i) > 0 then
722
          count = count + 1
723
          
724
          -- drop drones over 9 to clear space for newly bred bees and product
725
          if count > 9 then
726
            turtle.select(i)
727
            turtle.dropDown()
728
            count = count - 1
729
          end
730
        end
731
      end  
732
    end
733
     
734
    function isPurebred(princessData, droneData)
735
      -- check if princess and drone are exactly the same and no chance for mutation
736
      if princessData["speciesPrimary"] ~= princessData["speciesSecondary"] then
737
        return false
738
      end
739
      for key, value in pairs(princessData) do
740
        if value ~= droneData[key] and key ~= "territory" and key ~= "type" and key ~= "slot" then
741
          return false
742
        end
743
      end
744
      return true
745
    end
746
     
747
    function getUnknown(princessData, droneData)
748
      -- lists species that are not in the bee graph
749
      local unknownSpecies = {}
750
      if not bees[princessData["speciesPrimary"]] then
751
        table.insert(unknownSpecies, princessData["speciesPrimary"])
752
      end
753
      if not bees[princessData["speciesSecondary"]] then
754
        table.insert(unknownSpecies, princessData["speciesSecondary"])
755
      end
756
      for _, beeData in pairs(droneData) do
757
        if not bees[beeData["speciesPrimary"]] then
758
          table.insert(unknownSpecies, beeData["speciesPrimary"])
759
        end
760
        if not bees[beeData["speciesSecondary"]] then
761
          table.insert(unknownSpecies, beeData["speciesSecondary"])
762
        end
763
      end
764
      return unknownSpecies
765
    end
766
     
767
768
function scoreBeesIterate(name)
769
	
770
	for i, parents in ipairs(bees[name].mutateFrom) do
771
		if bees[parents[1]].score < bees[name].score - 2 then
772
			bees[parents[1]].score = bees[name].score - 2
773
			scoreBeesIterate(parents[1])
774
		end
775
		if bees[parents[2]].score < bees[name].score - 2 then
776
			bees[parents[2]].score = bees[name].score - 2
777
			scoreBeesIterate(parents[2])
778
		end
779
	end
780
end
781
782
-- program begins, read input---------------------------------------------------
783
784
tArgs = { ... }
785
if #tArgs > 0 then
786
787
	logLine("targeting bee species:")
788
	for i, target in ipairs(tArgs) do
789
		targetedSpecies = target
790
		bees[target].score = 9999
791
		for name, data in pairs(bees) do
792
			if data.score > 1 then
793
				logLine(name .. string.rep(" ", 20-#name), data.score)
794
			end
795
		end
796
	end
797
	  
798
	for name, beeData in pairs(bees) do
799
		if beeData.score == 9999 then
800
			scoreBeesIterate(name)			
801
		end
802
	end
803
else
804
	logLine("Usage Bee [species]")
805
	logFile.close()
806
	return false
807
end
808
     
809
-- breeding loop ---------------------------------------------------------------
810
     
811
logLine("Clearing system...")
812
clearSystem()
813
while true do
814
815
	ditchProduct()
816
	countBees()
817
	scanBees()
818
	princessData, droneData = analyzeBees()
819
820
	if droneData[2].score == 0 then --analyze failed to find a breeding pair
821
		break
822
	end
823
824
	if princessData then
825
826
		if isPurebred(princessData, droneData[2]) then
827
			logLine("Bees are purebred")
828
			turtle.turnRight()
829
			break
830
		end
831
832
		local unknownSpecies = getUnknown(princessData, droneData)
833
		if #unknownSpecies > 0 then
834
			logLine("Please add new species to bee graph:")
835
			for _, species in ipairs(unknownSpecies) do
836
				logLine("  "..species)
837
			end
838
			turtle.turnRight()
839
			break
840
		end
841
842
		breedBees(1, 2)
843
		dropExcess(droneData)
844
	end
845
846
	getBees()
847
	if redstone.getInput("right") then logLine("Execution ended by user.") break end
848
end
849
logFile.close()