SHOW:
|
|
- or go back to the newest paste.
| 1 | -- *-* <- Absolutely needed, do not delete. | |
| 2 | ||
| 3 | -- BeeAlverizer 1.1 fork of BeeAnalyzer 4 | |
| 4 | -- Original code by Direwolf20 | |
| 5 | -- Hotfixes by Mandydax, Mikeyhun and MaaadMike | |
| 6 | ||
| 7 | -- Major overhaul and rewrite to make work without turtle by Damaged | |
| 8 | ||
| 9 | ||
| 10 | -- JSON lib located at http://pastebin.com/jy3QenZn save as JSON.lua | |
| 11 | - | -- Be careful of case |
| 11 | + | -- Be careful of case |
| 12 | ||
| 13 | if not fs.exists("JSON.lua") then
| |
| 14 | shell.run("pastebin", "get", "jy3QenZn", "JSON.lua")
| |
| 15 | end | |
| 16 | ||
| 17 | local JSON = (loadfile "JSON.lua")() | |
| 18 | JSON.strictTypes = true | |
| 19 | ||
| 20 | -- Build: http://users.on.net/~damageinc/Alveary%20placement.jpg | |
| 21 | ||
| 22 | -- Make sure you name this program "bee" (careful of case) | |
| 23 | ||
| 24 | -- Direction definitions. | |
| 25 | ||
| 26 | -- When looking at computer, what direction is it? | |
| 27 | -- Or simply put the direction in the label EG: bee1.west | |
| 28 | ||
| 29 | local alvearyDirection = "west" | |
| 30 | ||
| 31 | for i,case in pairs({ ".west", ".east", ".north", ".south" }) do
| |
| 32 | if string.find(os.getComputerLabel(),case) then | |
| 33 | alvearyDirection = string.sub(case, 2) | |
| 34 | break | |
| 35 | end | |
| 36 | end | |
| 37 | print("I appear to be facing: "..alvearyDirection)
| |
| 38 | local analyzerDirection | |
| 39 | local junkDirection | |
| 40 | ||
| 41 | if alvearyDirection == "west" then | |
| 42 | analyzerDirection = "south" | |
| 43 | junkDirection = "north" | |
| 44 | end | |
| 45 | if alvearyDirection == "north" then | |
| 46 | analyzerDirection = "west" | |
| 47 | junkDirection = "east" | |
| 48 | end | |
| 49 | if alvearyDirection == "east" then | |
| 50 | analyzerDirection = "north" | |
| 51 | junkDirection = "south" | |
| 52 | end | |
| 53 | if alvearyDirection == "south" then | |
| 54 | analyzerDirection = "east" | |
| 55 | junkDirection = "west" | |
| 56 | end | |
| 57 | ||
| 58 | ||
| 59 | ||
| 60 | ||
| 61 | ||
| 62 | ||
| 63 | ||
| 64 | -- attribute scoring for same species tie-breaking ----------------------------- | |
| 65 | local droneTarget | |
| 66 | local princessSlot = 0 | |
| 67 | alveary = peripheral.wrap("back")
| |
| 68 | memoryChest = peripheral.wrap("top")
| |
| 69 | local maxMem = memoryChest.getInventorySize() | |
| 70 | -- Fix for some versions returning bees.species.* | |
| 71 | function fixName(name) | |
| 72 | return name:gsub("bees%.species%.",""):gsub("^.", string.upper)
| |
| 73 | end | |
| 74 | ||
| 75 | function getBeeData(i) | |
| 76 | return memoryChest.getStackInSlot(i)["beeInfo"] | |
| 77 | end | |
| 78 | ||
| 79 | function getPrimarySpecies(i) | |
| 80 | local thisBee = getBeeData(i) | |
| 81 | if thisBee["speciesPrimary"] ~= nil then | |
| 82 | return fixName(thisBee["speciesPrimary"]) | |
| 83 | else | |
| 84 | return fixName(thisBee["active"]["species"]) | |
| 85 | end | |
| 86 | end | |
| 87 | ||
| 88 | function getSecondarySpecies(i) | |
| 89 | if getBeeData(i)["speciesSecondary"] ~= nil then | |
| 90 | return fixName(getBeeData(i)["speciesSecondary"]) | |
| 91 | else | |
| 92 | return fixName(getBeeData(i)["inactive"]["species"]) | |
| 93 | end | |
| 94 | end | |
| 95 | ||
| 96 | scoresFertility = {
| |
| 97 | [1] = 0.1, | |
| 98 | [2] = 0.2, | |
| 99 | [3] = 0.3, | |
| 100 | [4] = 0.4 | |
| 101 | } | |
| 102 | scoresSpeed = {
| |
| 103 | ["0.3"] = 0.01, -- Slowest | |
| 104 | ["0.6"] = 0.02, -- Slower | |
| 105 | ["0.8"] = 0.03, -- Slow | |
| 106 | ["1"] = 0.04, -- Normal | |
| 107 | ["1.2"] = 0.05, -- Fast | |
| 108 | ["1.4"] = 0.06, -- Faster | |
| 109 | ["1.7"] = 0.07 -- Fastest | |
| 110 | } | |
| 111 | scoresAttrib = {
| |
| 112 | diurnal = 0.004, | |
| 113 | nocturnal = 0.003, | |
| 114 | tolerantFlyer = 0.002, | |
| 115 | caveDwelling = 0.0001 | |
| 116 | } | |
| 117 | scoresTolerance = {
| |
| 118 | ["NONE"] = 0.00000, | |
| 119 | ["UP 1"] = 0.00001, | |
| 120 | ["UP 2"] = 0.00002, | |
| 121 | ["UP 3"] = 0.00003, | |
| 122 | ["UP 4"] = 0.00004, | |
| 123 | ["UP 5"] = 0.00005, | |
| 124 | ["DOWN 1"] = 0.00001, | |
| 125 | ["DOWN 2"] = 0.00002, | |
| 126 | ["DOWN 3"] = 0.00003, | |
| 127 | ["DOWN 4"] = 0.00004, | |
| 128 | ["DOWN 5"] = 0.00005, | |
| 129 | ["BOTH 1"] = 0.00002, | |
| 130 | ["BOTH 2"] = 0.00004, | |
| 131 | ["BOTH 3"] = 0.00006, | |
| 132 | ["BOTH 4"] = 0.00008, | |
| 133 | ["BOTH 5"] = 0.00010 | |
| 134 | } | |
| 135 | ||
| 136 | -- the bee graph --------------------------------------------------------------- | |
| 137 | ||
| 138 | bees = {}
| |
| 139 | ||
| 140 | function addParent(parent, offspring) | |
| 141 | if bees[parent] then | |
| 142 | bees[parent].mutateTo[offspring] = true | |
| 143 | else | |
| 144 | bees[parent] = {
| |
| 145 | --name = parent, | |
| 146 | score = nil, | |
| 147 | mutateTo = {[offspring]=true},
| |
| 148 | mutateFrom = {}
| |
| 149 | } | |
| 150 | end | |
| 151 | end | |
| 152 | ||
| 153 | function addOffspring(offspring, parentss) | |
| 154 | if bees[offspring] then | |
| 155 | for i, parents in ipairs(parentss) do | |
| 156 | table.insert(bees[offspring].mutateFrom, parents) | |
| 157 | end | |
| 158 | else | |
| 159 | bees[offspring] = {
| |
| 160 | score = nil, | |
| 161 | mutateTo = {},
| |
| 162 | mutateFrom = parentss | |
| 163 | } | |
| 164 | end | |
| 165 | for i, parents in ipairs(parentss) do | |
| 166 | for i, parent in ipairs(parents) do | |
| 167 | addParent(parent, offspring) | |
| 168 | end | |
| 169 | end | |
| 170 | end | |
| 171 | ||
| 172 | -- score bees that have no parent combinations as 1 | |
| 173 | -- iteratively find the next bee up the line and increase the score | |
| 174 | function scoreBees() | |
| 175 | -- find all bees with no mutateFrom data | |
| 176 | local beeCount = 0 | |
| 177 | local beeScore = 1 | |
| 178 | for name, beeData in pairs(bees) do | |
| 179 | if #beeData.mutateFrom == 0 then | |
| 180 | beeData.score = beeScore | |
| 181 | else | |
| 182 | beeCount = beeCount + 1 | |
| 183 | end | |
| 184 | end | |
| 185 | while beeCount > 0 do | |
| 186 | beeScore = beeScore * 2 | |
| 187 | -- find all bees where all parent combos are scored | |
| 188 | for name, beeData in pairs(bees) do | |
| 189 | if not beeData.score then | |
| 190 | local scoreBee = true | |
| 191 | for i, beeParents in ipairs(beeData.mutateFrom) do | |
| 192 | local parent1 = bees[beeParents[1]] | |
| 193 | local parent2 = bees[beeParents[2]] | |
| 194 | ||
| 195 | if not parent1.score | |
| 196 | or parent1.score == beeScore | |
| 197 | or not parent2.score | |
| 198 | or parent2.score == beeScore then | |
| 199 | scoreBee = false | |
| 200 | break | |
| 201 | end | |
| 202 | end | |
| 203 | if scoreBee then | |
| 204 | beeData.score = beeScore | |
| 205 | beeCount = beeCount - 1 | |
| 206 | end | |
| 207 | end | |
| 208 | end | |
| 209 | end | |
| 210 | end | |
| 211 | ||
| 212 | -- produce combinations from 1 or 2 lists | |
| 213 | function choose(list, list2) | |
| 214 | local newList = {}
| |
| 215 | if list2 then | |
| 216 | for i = 1, #list2 do | |
| 217 | for j = 1, #list do | |
| 218 | if list[j] ~= list[i] then | |
| 219 | table.insert(newList, {list[j], list2[i]})
| |
| 220 | end | |
| 221 | end | |
| 222 | end | |
| 223 | else | |
| 224 | for i = 1, #list do | |
| 225 | for j = i, #list do | |
| 226 | if list[i] ~= list[j] then | |
| 227 | table.insert(newList, {list[i], list[j]})
| |
| 228 | end | |
| 229 | end | |
| 230 | end | |
| 231 | end | |
| 232 | return newList | |
| 233 | end | |
| 234 | ||
| 235 | ||
| 236 | for key, value in pairs (alveary.getBeeBreedingData()) do | |
| 237 | addOffspring( fixName(value.result), {{ fixName(value.allele1), fixName(value.allele2) }} )
| |
| 238 | end | |
| 239 | scoreBees() | |
| 240 | ||
| 241 | -- logging --------------------------------------------------------------------- | |
| 242 | ||
| 243 | local logFile = fs.open("bee.log", "w")
| |
| 244 | function log(msg) | |
| 245 | msg = msg or "" | |
| 246 | logFile.write(tostring(msg)) | |
| 247 | logFile.flush() | |
| 248 | io.write(msg) | |
| 249 | end | |
| 250 | function logLine(msg) | |
| 251 | msg = msg or "" | |
| 252 | logFile.write(msg.."\n") | |
| 253 | logFile.flush() | |
| 254 | io.write(msg.."\n") | |
| 255 | end | |
| 256 | ||
| 257 | function logTable(table) | |
| 258 | for key, value in pairs (table) do | |
| 259 | logLine(key .. " = " .. tostring(value)) | |
| 260 | end | |
| 261 | end | |
| 262 | ||
| 263 | ||
| 264 | -- analyzing functions --------------------------------------------------------- | |
| 265 | ||
| 266 | function clearSystem() | |
| 267 | -- clear out alveary | |
| 268 | for i = 2,9 do | |
| 269 | memoryChest.pullItem(alvearyDirection,i) | |
| 270 | end | |
| 271 | -- clear out analyzer | |
| 272 | for i = 1, 12 do | |
| 273 | memoryChest.pullItem(analyzerDirection,i) | |
| 274 | end | |
| 275 | end | |
| 276 | ||
| 277 | function analyzeBees() | |
| 278 | princessSlot = 0 | |
| 279 | logLine("analyzing bees...")
| |
| 280 | memoryChest.condenseItems() | |
| 281 | local highestScore | |
| 282 | local highestScoreDrone | |
| 283 | for i,data in pairs(memoryChest.getAllStacks()) do | |
| 284 | data = memoryChest.getStackInSlot(i) | |
| 285 | - | sleep(10) |
| 285 | + | |
| 286 | memoryChest.pushItem(junkDirection,i) | |
| 287 | print("P")
| |
| 288 | else | |
| 289 | print("B")
| |
| 290 | --print(JSON:encode(data["beeInfo"])) | |
| 291 | --print(data["beeInfo"]["isAnalyzed"]) | |
| 292 | if data["beeInfo"]["isAnalyzed"] == false then | |
| 293 | memoryChest.pushItemIntoSlot(analyzerDirection,i,64,3) | |
| 294 | while memoryChest.pullItemIntoSlot(analyzerDirection,9,61,i) == 0 do sleep(1) end | |
| 295 | end | |
| 296 | if string.find(data["rawName"], "princess") then | |
| 297 | princessSlot = i | |
| 298 | end | |
| 299 | end | |
| 300 | end | |
| 301 | end | |
| 302 | ||
| 303 | local droneData | |
| 304 | droneData = { }
| |
| 305 | ||
| 306 | function sortBees() | |
| 307 | droneData = { }
| |
| 308 | if princessSlot ~= 0 then | |
| 309 | logLine("scoring drones...")
| |
| 310 | for i,data in pairs(memoryChest.getAllStacks()) do | |
| 311 | if i ~= princessSlot then | |
| 312 | -- check for untargeted species | |
| 313 | if memoryChest.getStackInSlot(i) ~= nil and (not bees[getPrimarySpecies(i)].targeted or not bees[getSecondarySpecies(i)].targeted) then | |
| 314 | - | -- check for untargeted species |
| 314 | + | |
| 315 | - | if memoryChest.getStackInSlot(i) ~= nil and (not bees[getPrimarySpecies(i)].targeted or not bees[getSecondarySpecies(i)].targeted) then |
| 315 | + | else |
| 316 | - | memoryChest.pushItem(junkDirection,i) |
| 316 | + | droneData[i] = scoreBee(i) |
| 317 | if droneData[i] == 0 then | |
| 318 | - | if string.find(data["rawName"], "princess") then |
| 318 | + | memoryChest.pushItem(junkDirection,i) |
| 319 | - | princessSlot = i |
| 319 | + | droneData[i] = nil |
| 320 | end | |
| 321 | end | |
| 322 | end | |
| 323 | end | |
| 324 | -- find the best drone | |
| 325 | logLine("sorting drones...")
| |
| 326 | highestScore = 0 | |
| 327 | - | droneData[i] = scoreBee(i) |
| 327 | + | |
| 328 | - | if droneData[i] == 0 then |
| 328 | + | |
| 329 | highestScore = beeScore | |
| 330 | highestScoreDrone = i | |
| 331 | end | |
| 332 | end | |
| 333 | printHeader() | |
| 334 | for i = 1, maxMem do | |
| 335 | if memoryChest.getStackInSlot(i) ~= nil then | |
| 336 | printBee(i) | |
| 337 | end | |
| 338 | end | |
| 339 | end | |
| 340 | logLine() | |
| 341 | return highestScoreDrone | |
| 342 | end | |
| 343 | ||
| 344 | function getBees() | |
| 345 | -- get bees from apiary | |
| 346 | log("waiting for bees.")
| |
| 347 | local firstPass = true | |
| 348 | local highScore | |
| 349 | while true do | |
| 350 | local gotStuff = false | |
| 351 | for i = 3,9 do | |
| 352 | if memoryChest.pullItem(alvearyDirection,i) ~= 0 then | |
| 353 | gotStuff = true | |
| 354 | end | |
| 355 | end | |
| 356 | if gotStuff == true then | |
| 357 | break | |
| 358 | end | |
| 359 | if firstPass then | |
| 360 | firstPass = false | |
| 361 | logLine() | |
| 362 | logLine("First time waiting:")
| |
| 363 | logLine("-compacting bees")
| |
| 364 | for i = 1,maxMem do | |
| 365 | if droneData[i] ~= nil then | |
| 366 | if i ~= 1 then | |
| 367 | for j = 1,i-1 do | |
| 368 | if memoryChest.getStackInSlot(j) == nil then | |
| 369 | memoryChest.swapStacks(i, j) | |
| 370 | droneData[j] = droneData[i] | |
| 371 | droneData[i] = nil | |
| 372 | break | |
| 373 | end | |
| 374 | end | |
| 375 | end | |
| 376 | end | |
| 377 | end | |
| 378 | logLine("-resorting bees in chest")
| |
| 379 | for i = 1,maxMem do | |
| 380 | if droneData[i] ~= nil then | |
| 381 | if memoryChest.getStackInSlot(i) ~= nil then | |
| 382 | highScore = i | |
| 383 | for j = i + 1, maxMem do | |
| 384 | if memoryChest.getStackInSlot(j) ~= nil then | |
| 385 | if droneData[j] > droneData[highScore] then | |
| 386 | highScore = j | |
| 387 | end | |
| 388 | end | |
| 389 | end | |
| 390 | -- swap bees | |
| 391 | if highScore ~= i then | |
| 392 | memoryChest.swapStacks(i, highScore) | |
| 393 | droneData[i], droneData[highScore] = droneData[highScore], droneData[i] | |
| 394 | end | |
| 395 | end | |
| 396 | end | |
| 397 | end | |
| 398 | logLine("-discarding excess")
| |
| 399 | for i = maxMem, maxMem - (maxMem / 10) do | |
| 400 | if droneData[i] ~= nil then | |
| 401 | memoryChest.pushItem(junkDirection,i) | |
| 402 | droneData[i] = nil | |
| 403 | end | |
| 404 | end | |
| 405 | else | |
| 406 | sleep(10) | |
| 407 | end | |
| 408 | log(".")
| |
| 409 | end | |
| 410 | log("*")
| |
| 411 | logLine() | |
| 412 | end | |
| 413 | ||
| 414 | function scoreBee(droneID) | |
| 415 | local beeDataDrone = getBeeData(droneID) | |
| 416 | local beeDataPrincess = getBeeData(princessSlot) | |
| 417 | local droneSpecies = {getPrimarySpecies(droneID), getSecondarySpecies(droneID)}
| |
| 418 | -- check for untargeted species | |
| 419 | if not bees[droneSpecies[1]].targeted or not bees[droneSpecies[2]].targeted then | |
| 420 | return 0 | |
| 421 | end | |
| 422 | local princessSpecies = {getPrimarySpecies(princessSlot), getSecondarySpecies(princessSlot)}
| |
| 423 | local score | |
| 424 | local maxScore = 0 | |
| 425 | for _, combo in ipairs({{princessSpecies[1], droneSpecies[1]}
| |
| 426 | ,{princessSpecies[1], droneSpecies[2]}
| |
| 427 | ,{princessSpecies[2], droneSpecies[1]}
| |
| 428 | ,{princessSpecies[2], droneSpecies[2]}}) do
| |
| 429 | -- find maximum score for each combo | |
| 430 | score = (bees[combo[1]].score + bees[combo[2]].score) / 2 | |
| 431 | for name, beeData in pairs(bees) do | |
| 432 | if beeData.targeted then | |
| 433 | for i, parents in ipairs(beeData.mutateFrom) do | |
| 434 | if combo[1] == parents[1] and combo[2] == parents[2] | |
| 435 | or combo[2] == parents[1] and combo[1] == parents[2] then | |
| 436 | score = (score + beeData.score) / 2 | |
| 437 | end | |
| 438 | end | |
| 439 | end | |
| 440 | end | |
| 441 | maxScore = maxScore + score | |
| 442 | end | |
| 443 | -- add one for each combination that results in the maximum score | |
| 444 | score = maxScore | |
| 445 | -- score attributes | |
| 446 | score = score + math.max(scoresFertility[beeDataDrone["active"]["fertility"]], scoresFertility[beeDataPrincess["active"]["fertility"]]) | |
| 447 | score = score + math.min(scoresSpeed[tostring(beeDataDrone["active"]["speed"])], scoresSpeed[tostring(beeDataPrincess["active"]["speed"])]) | |
| 448 | if beeDataDrone["active"]["nocturnal"] or beeDataPrincess["active"]["nocturnal"] then score = score + scoresAttrib["nocturnal"] end | |
| 449 | if beeDataDrone["active"]["tolerantFlyer"] or beeDataPrincess["active"]["tolerantFlyer"] then score = score + scoresAttrib["tolerantFlyer"] end | |
| 450 | if beeDataDrone["active"]["caveDwelling"] or beeDataPrincess["active"]["caveDwelling"] then score = score + scoresAttrib["caveDwelling"] end | |
| 451 | score = score + math.max(scoresTolerance[string.upper(beeDataDrone["active"]["temperatureTolerance"])], scoresTolerance[string.upper(beeDataPrincess["active"]["temperatureTolerance"])]) | |
| 452 | score = score + math.max(scoresTolerance[string.upper(beeDataDrone["active"]["humidityTolerance"])], scoresTolerance[string.upper(beeDataPrincess["active"]["humidityTolerance"])]) | |
| 453 | return score | |
| 454 | end | |
| 455 | ||
| 456 | function printHeader() | |
| 457 | logLine() | |
| 458 | logLine("sl t species f spd n f c tmp hmd score ")
| |
| 459 | logLine("--|-|-------|-|---|-|-|-|---|---|------")
| |
| 460 | end | |
| 461 | ||
| 462 | -- string constants for console output | |
| 463 | toleranceString = {
| |
| 464 | ["NONE"] = " - ", | |
| 465 | ["UP 1"] = " +1 ", | |
| 466 | ["UP 2"] = " +2 ", | |
| 467 | ["UP 3"] = " +3 ", | |
| 468 | ["UP 4"] = " +4 ", | |
| 469 | ["UP 5"] = " +5 ", | |
| 470 | ["DOWN 1"] = " -1 ", | |
| 471 | ["DOWN 2"] = " -2 ", | |
| 472 | ["DOWN 3"] = " -3 ", | |
| 473 | ["DOWN 4"] = " -4 ", | |
| 474 | ["DOWN 5"] = " -5 ", | |
| 475 | ["BOTH 1"] = "+-1 ", | |
| 476 | ["BOTH 2"] = "+-2 ", | |
| 477 | ["BOTH 3"] = "+-3 ", | |
| 478 | ["BOTH 4"] = "+-4 ", | |
| 479 | ["BOTH 5"] = "+-5 " | |
| 480 | } | |
| 481 | ||
| 482 | speedString = {
| |
| 483 | ["0.3"] = "0.3", -- Slowest | |
| 484 | ["0.6"] = "0.6", -- Slower | |
| 485 | ["0.8"] = "0.8", -- Slow | |
| 486 | ["1"] = "1.0", -- Normal | |
| 487 | ["1.2"] = "1.2", -- Fast | |
| 488 | ["1.4"] = "1.4", -- Faster | |
| 489 | ["1.7"] = "1.7" -- Fastest | |
| 490 | } | |
| 491 | ||
| 492 | function printBee(i) | |
| 493 | local beeData = getBeeData(i) | |
| 494 | log(i < 10 and " "..i.." " or i.." ") | |
| 495 | -- type | |
| 496 | log(string.find(memoryChest.getStackInSlot(i)["rawName"], "princess") and "P " or "D ") | |
| 497 | -- species | |
| 498 | log(getPrimarySpecies(i):gsub("bees%.species%.",""):sub(1,3)..":"..getSecondarySpecies(i):gsub("bees%.species%.",""):sub(1,3).." ")
| |
| 499 | -- fertility | |
| 500 | log(tostring(beeData["active"]["fertility"]).." ") | |
| 501 | -- speed | |
| 502 | log(speedString[tostring(beeData["active"]["speed"])].." ") | |
| 503 | -- nocturnal | |
| 504 | log(beeData["active"]["nocturnal"] and "X " or "- ") | |
| 505 | -- flyer | |
| 506 | log(beeData["active"]["tolerantFlyer"] and "X " or "- ") | |
| 507 | -- cave dwelling | |
| 508 | log(beeData["active"]["caveDwelling"] and "X " or "- ") | |
| 509 | -- temperature tolerance | |
| 510 | log(toleranceString[string.upper(beeData["active"]["temperatureTolerance"])]) | |
| 511 | -- humidity tolerance | |
| 512 | log(toleranceString[string.upper(beeData["active"]["humidityTolerance"])]) | |
| 513 | -- score | |
| 514 | log(droneData[i] and string.format("%5.1d", droneData[i]).." " or " ")
| |
| 515 | logLine() | |
| 516 | end | |
| 517 | ||
| 518 | function dropExcess() | |
| 519 | logLine("dropping excess...")
| |
| 520 | for i = ( maxMem - 9 ), maxMem do | |
| 521 | -- drop drones over ( max inv - 9 ) to clear space for newly bred bees and product | |
| 522 | memoryChest.pushItem(junkDirection,i) | |
| 523 | end | |
| 524 | end | |
| 525 | ||
| 526 | function isPurebred(droneID) | |
| 527 | -- check if princess and drone are exactly the same and no chance for mutation | |
| 528 | local princessPrimary = getPrimarySpecies(princessSlot) | |
| 529 | if princessPrimary ~= getSecondarySpecies(princessSlot) then | |
| 530 | return false | |
| 531 | end | |
| 532 | if getPrimarySpecies(droneID) ~= princessPrimary then | |
| 533 | return false | |
| 534 | end | |
| 535 | if getSecondarySpecies(droneID) ~= princessPrimary then | |
| 536 | return false | |
| 537 | end | |
| 538 | local droneBeeData = getBeeData(droneID) | |
| 539 | local princessBeeData = getBeeData(princessSlot) | |
| 540 | for i,key in pairs({ "fertility", "speed", "nocturnal", "tolerantFlyer", "caveDwelling", "temperatureTolerance", "humidityTolerance" }) do
| |
| 541 | if | |
| 542 | droneBeeData["active"][key] ~= princessBeeData["active"][key] or | |
| 543 | droneBeeData["inactive"][key] ~= princessBeeData["inactive"][key] | |
| 544 | then | |
| 545 | return false | |
| 546 | end | |
| 547 | end | |
| 548 | - | for i, target in ipairs(tArgs) do |
| 548 | + | |
| 549 | - | targetBee(target) |
| 549 | + | |
| 550 | - | for name, data in pairs(bees) do |
| 550 | + | |
| 551 | - | if data.targeted and data.score > 1 then |
| 551 | + | |
| 552 | - | logLine(name .. string.rep(" ", 20-#name), data.score)
|
| 552 | + | |
| 553 | -- set species and all parents to targeted | |
| 554 | function targetBee(name) | |
| 555 | local bee = bees[name] | |
| 556 | if bee and not bee.targeted then | |
| 557 | bee.targeted = true | |
| 558 | for i, parents in ipairs(bee.mutateFrom) do | |
| 559 | for j, parent in ipairs(parents) do | |
| 560 | targetBee(parent) | |
| 561 | end | |
| 562 | end | |
| 563 | end | |
| 564 | end | |
| 565 | ||
| 566 | tArgs = { ... }
| |
| 567 | ||
| 568 | if fs.exists("bee.data") and #tArgs == 0 then
| |
| 569 | local recoveredData = fs.open("bee.data", "r")
| |
| 570 | local historyData = recoveredData.readLine() | |
| 571 | if historyData then | |
| 572 | historyData = JSON:decode(historyData) | |
| 573 | tArgs[1] = historyData["target"] | |
| 574 | if historyData["count"] ~= nil then | |
| 575 | tArgs[2] = historyData["count"] | |
| 576 | end | |
| 577 | logLine("Recovered old data.")
| |
| 578 | end | |
| 579 | recoveredData.close() | |
| 580 | end | |
| 581 | ||
| 582 | ||
| 583 | - | droneTarget = analyzeBees() |
| 583 | + | |
| 584 | local myProgramName | |
| 585 | - | if isPurebred(droneTarget) then |
| 585 | + | |
| 586 | if type(fileName) == "string" then | |
| 587 | if fileName ~= "" then | |
| 588 | local tempFile = fs.open(fileName,"r") | |
| 589 | if string.sub(tempFile.readLine(),4,6) == "*-*" then | |
| 590 | myProgramName = fileName | |
| 591 | break | |
| 592 | end | |
| 593 | end | |
| 594 | end | |
| 595 | end | |
| 596 | return myProgramName | |
| 597 | end | |
| 598 | ||
| 599 | ||
| 600 | -- set bee graph entry to targeted if species was specified on the command line | |
| 601 | -- otherwise set all entries to targeted | |
| 602 | ||
| 603 | local totalDrones | |
| 604 | local alwaysBreed | |
| 605 | ||
| 606 | if #tArgs > 0 then | |
| 607 | logLine("targeting bee species:")
| |
| 608 | fs.delete("bee.data")
| |
| 609 | recoveredData = fs.open("bee.data", "w")
| |
| 610 | local tempArray = {}
| |
| 611 | tempArray["target"] = tArgs[1] | |
| 612 | if tArgs[2] ~= nil then | |
| 613 | tempArray["count"] = math.min(math.max(tonumber(tArgs[2]),1),64) | |
| 614 | totalDrones = math.max(tonumber(tArgs[2]),1) | |
| 615 | end | |
| 616 | recoveredData.write( JSON:encode( tempArray ) ) | |
| 617 | recoveredData.close() | |
| 618 | if type(tArgs[1]) == "string" then | |
| 619 | print(string.lower(tArgs[1])) | |
| 620 | while true do | |
| 621 | if tArgs[1]:gsub("^.", string.upper) == "Breedprincess" then
| |
| 622 | analyzeBees() | |
| 623 | targetBee(getPrimarySpecies(princessSlot)) | |
| 624 | break | |
| 625 | end | |
| 626 | if tArgs[1]:gsub("^.", string.upper) == "Breeddrone" then
| |
| 627 | analyzeBees() | |
| 628 | targetBee(getPrimarySpecies(1)) | |
| 629 | break | |
| 630 | end | |
| 631 | if true then | |
| 632 | targetBee(tArgs[1]:gsub("^.", string.upper))
| |
| 633 | break | |
| 634 | end | |
| 635 | break | |
| 636 | end | |
| 637 | else | |
| 638 | print("You must enter a valid target mutation")
| |
| 639 | end | |
| 640 | for name, data in pairs(bees) do | |
| 641 | if data.targeted and data.score > 1 then | |
| 642 | logLine(name .. string.rep(" ", 20-#name), data.score)
| |
| 643 | end | |
| 644 | end | |
| 645 | local myProgramName = findMe() | |
| 646 | logLine("Found program:"..myProgramName)
| |
| 647 | if myProgramName ~= nil then | |
| 648 | fs.delete("startup")
| |
| 649 | local startupFile = fs.open("startup","w")
| |
| 650 | startupFile.write("shell.run(\""..myProgramName.."\")")
| |
| 651 | startupFile.close() | |
| 652 | else | |
| 653 | logLine("Cannot find program name, you edited the first line of the program didn't you!")
| |
| 654 | end | |
| 655 | else | |
| 656 | for _, beeData in pairs(bees) do | |
| 657 | beeData.targeted = true | |
| 658 | end | |
| 659 | end | |
| 660 | ||
| 661 | -- breeding loop --------------------------------------------------------------- | |
| 662 | ||
| 663 | ||
| 664 | ||
| 665 | logLine("Clearing system...")
| |
| 666 | clearSystem() | |
| 667 | if not memoryChest.getAllStacks() then | |
| 668 | print("No bees to work on, add bees and restart")
| |
| 669 | else | |
| 670 | redstone.setOutput("bottom", true)
| |
| 671 | while true do | |
| 672 | analyzeBees() | |
| 673 | droneTarget = sortBees() | |
| 674 | if princessSlot ~= 0 then | |
| 675 | if isPurebred(droneTarget) and memoryChest.getStackInSlot(droneTarget)["qty"] == totalDrone then | |
| 676 | logLine("Bees are purebred.")
| |
| 677 | logLine("Princess: "..princessSlot)
| |
| 678 | logLine("Drone: "..droneTarget)
| |
| 679 | redstone.setOutput("bottom", false)
| |
| 680 | fs.delete("bee.data")
| |
| 681 | fs.delete("startup")
| |
| 682 | break | |
| 683 | end | |
| 684 | memoryChest.pushItemIntoSlot(alvearyDirection,princessSlot,1,1) | |
| 685 | memoryChest.pushItemIntoSlot(alvearyDirection,droneTarget,1,2) | |
| 686 | dropExcess() | |
| 687 | end | |
| 688 | getBees() | |
| 689 | end | |
| 690 | end | |
| 691 | logFile.close() |