Advertisement
guitarplayer616

schem fixed 2 w/multiturtle

Jan 21st, 2017
379
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --made by me
  2. --setup() made by orwell
  3.  
  4. local tArgs = { ... }
  5. if #tArgs < 1 then
  6.   error("Usage: blueprint <gunzipped schematic file>")
  7. end
  8.  
  9. if not fs.exists("textutilsFIX") then
  10.     shell.run("pastebin get 3wguFBXn textutilsFIX")
  11. end
  12.  
  13. if not fs.exists("grid") then
  14.     shell.run("pastebin get EjYUEQqx grid")
  15. end
  16.  
  17. shell.run("grid")
  18. os.loadAPI("textutilsFIX")
  19.  
  20. local filename = tArgs[1]
  21.  
  22. if not fs.exists(filename) then
  23.   error("File does not exist.")
  24. end
  25.  
  26. function save(name,table)
  27.     local h = fs.open(name,"w")
  28.     table = textutils.serialize(table)
  29.     h.write(table)
  30.     h.close()
  31. end
  32.  
  33. function saveIns(name,table)
  34.     local h = fs.open(name,"w")
  35.     h.writeLine(name.." = {}")
  36.     for i,coord in pairs(table) do
  37.         h.writeLine(name.."["..i.."] = {"..table.concat(coord,",").."}")
  38.         h.flush()
  39.     end
  40.     h.close()
  41. end
  42.  
  43. function saveBlueprint(reference,slots,instructions,uniqueblocks,nTurtle)
  44.     local fname = filename:gsub("%.(.*)","")..".blueprint"
  45.     if nTurtle then
  46.         fname = fname.."["..tostring(nTurtle).."]"
  47.     end
  48.     local h = fs.open(fname,"w")
  49.     h.writeLine("reference ="..textutils.serialize(reference)..";")
  50.     h.writeLine("slots = "..textutils.serialize(slots)..";")
  51.     h.writeLine("uniqueblocks = "..textutils.serialize(uniqueblocks)..";")
  52.     h.writeLine("instructions = "..textutilsFIX.serialize(instructions)..";")
  53.     h.close()
  54.     return fname
  55. end
  56.  
  57. local block_id = {}
  58.  
  59. block_id[0] = "Air"
  60. block_id[1] = "Stone"
  61. block_id[2] = "Grass"
  62. block_id[3] = "Dirt"
  63. block_id[4] = "Cobblestone"
  64. block_id[5] = "Wood Planks"
  65. block_id[6] = "Sapling"
  66. block_id[7] = "Bedrock"
  67. block_id[8] = "Water"
  68. block_id[9] = "Stationary water"
  69. block_id[10] = "Lava"
  70. block_id[11] = "Stationary lava"
  71. block_id[12] = "Sand"
  72. block_id[13] = "Gravel"
  73. block_id[14] = "Gold Ore"
  74. block_id[15] = "Iron (Ore)"
  75. block_id[16] = "Coal Ore"
  76. block_id[17] = "Wood"
  77. block_id[18] = "Leaves"
  78. block_id[19] = "Sponge"
  79. block_id[20] = "Glass"
  80. block_id[21] = "Lapis Lazuli (Ore)"
  81. block_id[22] = "Lapis Lazuli (Block)"
  82. block_id[23] = "Dispenser"
  83. block_id[24] = "Sandstone"
  84. block_id[25] = "Note Block Tile entity"
  85. block_id[26] = "Bed"
  86. block_id[27] = "Powered Rail "
  87. block_id[28] = "Detector Rail "
  88. block_id[29] = "Sticky Piston"
  89. block_id[30] = "Cobweb"
  90. block_id[31] = "Tall Grass"
  91. block_id[32] = "Dead Bush"
  92. block_id[33] = "Piston"
  93. block_id[34] = "Piston Extension"
  94. block_id[35] = "Wool"
  95. block_id[36] = "Block moved by Piston"
  96. block_id[37] = "Dandelionandelion"
  97. block_id[38] = "Rose"
  98. block_id[39] = "Brown Mushroom"
  99. block_id[40] = "Red Mushroom"
  100. block_id[41] = "Block of Gold"
  101. block_id[42] = "Block of Iron"
  102. block_id[43] = "Double Slabs"
  103. block_id[44] = "Slabs"
  104. block_id[45] = "Brick Block"
  105. block_id[46] = "TNT"
  106. block_id[47] = "Bookshelf"
  107. block_id[48] = "Moss Stone"
  108. block_id[49] = "Obsidian"
  109. block_id[50] = "Torch"
  110. block_id[51] = "Fire"
  111. block_id[52] = "Monster Spawner"
  112. block_id[53] = "Wooden Stairs"
  113. block_id[54] = "Chest"
  114. block_id[55] = "Redstone (Wire)"
  115. block_id[56] = "Diamond (Ore)"
  116. block_id[57] = "Block of Diamond"
  117. block_id[58] = "Crafting Table"
  118. block_id[59] = "Seeds"
  119. block_id[60] = "Farland"
  120. block_id[61] = "Furnace"
  121. block_id[62] = "Burning Furnace"
  122. block_id[63] = "Sign Post"
  123. block_id[64] = "Wooden Door"
  124. block_id[65] = "Ladders"
  125. block_id[66] = "Rails"
  126. block_id[67] = "Cobblestone Stairs"
  127. block_id[68] = "Wall Sign"
  128. block_id[69] = "Lever"
  129. block_id[70] = "Stone Pressure Plate"
  130. block_id[71] = "Iron Door"
  131. block_id[72] = "Wooden Pressure Plates"
  132. block_id[73] = "Redstone Ore"
  133. block_id[74] = "Glowing Redstone Ore"
  134. block_id[75] = "Redstone Torch"
  135. block_id[76] = "Redstone Torch"
  136. block_id[77] = "Stone Button "
  137. block_id[78] = "Snow"
  138. block_id[79] = "Ice"
  139. block_id[80] = "Snow Block"
  140. block_id[81] = "Cactus"
  141. block_id[82] = "Clay (Block)"
  142. block_id[83] = "Sugar Cane"
  143. block_id[84] = "Jukebox"
  144. block_id[85] = "Fence"
  145. block_id[86] = "Pumpkin"
  146. block_id[87] = "Netherrack"
  147. block_id[88] = "Soul Sand"
  148. block_id[89] = "Glowstone"
  149. block_id[90] = "Portal"
  150. block_id[91] = "Jack-O-Lantern"
  151. block_id[92] = "Cake Block"
  152. block_id[93] = "Redstone Repeater"
  153. block_id[94] = "Redstone Repeater"
  154. block_id[95] = "Stained Glass"
  155. block_id[96] = "Trapdoors"
  156. block_id[97] = "Hidden Silverfish"
  157. block_id[98] = "Stone Bricks"
  158. block_id[99] = "Huge brown and red mushroom"
  159. block_id[100] = "Huge brown and red mushroom"
  160. block_id[101] = "Iron Bars"
  161. block_id[102] = "Glass Pane"
  162. block_id[103] = "Melon"
  163. block_id[104] = "Pumpkin Stem"
  164. block_id[105] = "Melon Stem"
  165. block_id[106] = "Vines"
  166. block_id[107] = "Fence Gate"
  167. block_id[108] = "Brick Stairs"
  168. block_id[109] = "Stone Brick Stairs"
  169. block_id[110] = "Mycelium"
  170. block_id[111] = "Lily Pad"
  171. block_id[112] = "Nether Brick"
  172. block_id[113] = "Nether Brick Fence"
  173. block_id[114] = "Nether Brick Stairs"
  174. block_id[115] = "Nether Wart"
  175. block_id[116] = "Enchantment Table"
  176. block_id[117] = "Brewing Stand"
  177. block_id[118] = "Cauldron"
  178. block_id[119] = "End Portal"
  179. block_id[120] = "End Portal Frame"
  180. block_id[121] = "End Stone "
  181. block_id[126] = "Wood Slabs"
  182. block_id[128] = "Sandstone Stairs"
  183. block_id[134] = "Spruce Wood Stairs"
  184. block_id[135] = "Birch Wood Stairs"
  185. block_id[136] = "Jungle Wood Stairs"
  186. block_id[156] = "Quartz Stairs"
  187. block_id[159] = "Stained Clay"
  188. block_id[160] = "Stained Glass Pane"
  189. block_id[163] = "Acacia Wood Stairs"
  190. block_id[164] = "Dark Oak Wood Stairs"
  191. block_id[171] = "Carpet"
  192. block_id[172] = "Hardened Clay"
  193. block_id[256] = "Iron Ingotron Shovel"
  194. block_id[257] = "Iron Pickaxe"
  195. block_id[258] = "Iron Axe"
  196. block_id[259] = "Flint and Steel"
  197. block_id[260] = "Red Apple"
  198. block_id[261] = "Bow"
  199. block_id[262] = "Arrow"
  200. block_id[263] = "Coal"
  201.  
  202. local woolColors = {}
  203. woolColors[0] = "White"
  204. woolColors[1] = "Orange"
  205. woolColors[2] = "Magenta"
  206. woolColors[3] = "Light Blue"
  207. woolColors[4] = "Yellow"
  208. woolColors[5] = "Lime"
  209. woolColors[6] = "Pink"
  210. woolColors[7] = "Gray"
  211. woolColors[8] = "Light Gray"
  212. woolColors[9] = "Cyan"
  213. woolColors[10] = "Purple"
  214. woolColors[11] = "Blue"
  215. woolColors[12] = "Brown"
  216. woolColors[13] = "Green"
  217. woolColors[14] = "Red"
  218. woolColors[15] = "Black"
  219.  
  220. local woodTypes = {}
  221. woodTypes[0] = "Oak"
  222. woodTypes[1] = "Spruce"
  223. woodTypes[2] = "Birch"
  224. woodTypes[3] = "Jungle"
  225. woodTypes[4] = "Acacia"
  226. woodTypes[5] = "Dark Oak"
  227.  
  228. local stairOrientation = {}
  229. stairOrientation[0] = "East"
  230. stairOrientation[1] = "West"
  231. stairOrientation[2] = "South"
  232. stairOrientation[3] = "North"
  233. stairOrientation[4] = "East Inverted"
  234. stairOrientation[5] = "West Inverted"
  235. stairOrientation[6] = "South Inverted"
  236. stairOrientation[7] = "North Inverted"
  237.  
  238. local nonWoodenSlabs = {       
  239.     [0] = "Stone",     
  240.     [1] = "Sandstone",     
  241.     [2] = "Wooden",    
  242.     [3] = "Cobblestone",       
  243.     [4] = "Bricks",    
  244.     [5] = "Stone Bricks",      
  245.     [6] = "Nether Brick",      
  246.     [7] = "Quartz",    
  247.     [8] = "Inverted Stone",    
  248.     [9] = "Inverted Sandstone",    
  249.     [10] = "Inverted Wooden",      
  250.     [11] = "Inverted Cobblestone",     
  251.     [12] = "Inverted Bricks",      
  252.     [13] = "Inverted Stone Bricks",    
  253.     [14] = "Inverted Nether Brick",    
  254.     [15] = "Inverted Quartz",      
  255. }
  256.  
  257. local length = 0
  258. local height = 0
  259. local width = 0
  260. local blocks = {}
  261. local data = {}
  262.  
  263. function getBlockName(id, blockData)
  264.     blockData = blockData or nil
  265.     local str = nil
  266.     if(block_id[id] == nil) then
  267.         return tostring(id)..", "..tostring(blockData)
  268.     else
  269.         if(blockData) then
  270.             if(id == 35) or (id == 159) or (id == 95) or (id == 160) or (id == 171) then
  271.                 str = tostring(woolColors[blockData]) .. " " .. tostring(block_id[id])
  272.                 return str
  273.             elseif id == 5 or id==17 or id==126 then
  274.                 str = tostring(woodTypes[blockData]).." "..tostring(block_id[id])
  275.                 return str
  276.             elseif id == 44 or id == 43 then       
  277.                 str = tostring(nonWoodenSlabs[blockData]).." "..tostring(block_id[id])     
  278.                 return str
  279.             end
  280.         return block_id[id]
  281.         end
  282.     end
  283. end
  284.  
  285. function getBlockId(x,y,z)
  286.   return blocks[y + z*width + x*length*width + 1]
  287. end
  288.  
  289. function getData(x,y,z)
  290.   return data[y + z*width + x*length*width + 1]
  291. end
  292.  
  293. function readbytes(h, n)
  294.   for i=1,n do
  295.     h.read()
  296.   end
  297. end
  298.  
  299. function readname(h)  
  300.   local n1 = h.read()
  301.   local n2 = h.read()
  302.  
  303.   if(n1 == nil or n2 == nil) then
  304.     return ""
  305.   end
  306.  
  307.   local n = n1*256 + n2
  308.  
  309.   local str = ""
  310.   for i=1,n do
  311.     local c = h.read()
  312.     if c == nil then
  313.       return
  314.     end  
  315.     str = str .. string.char(c)
  316.   end
  317.   return str
  318. end
  319.  
  320. function parse(a, h, containsName)
  321.   local containsName = containsName or true
  322.   local i,i1,i2,i3,i4
  323.   if a==0 then
  324.     return
  325.   end
  326.   if containsName then
  327.     name = readname(h)
  328.   end  
  329.  
  330.   if a==1 then
  331.     readbytes(h,1)  
  332.   elseif a==2 then
  333.     i1 = h.read()
  334.     i2 = h.read()
  335.     i = i1*256 + i2
  336.     if(name=="Height") then
  337.       height = i
  338.     elseif (name=="Length") then
  339.       length = i
  340.     elseif (name=="Width") then
  341.       width = i
  342.     end
  343.   elseif a==3 then
  344.     readbytes(h,4)
  345.   elseif a==4 then
  346.     readbytes(h,8)
  347.   elseif a==5 then
  348.     readbytes(h,4)
  349.   elseif a==6 then
  350.     readbytes(h,8)
  351.   elseif a==7 then
  352.     i1 = h.read()
  353.     i2 = h.read()
  354.     i3 = h.read()
  355.     i4 = h.read()
  356.     i = i1*256*256*256 + i2*256*256 + i3*256 + i4
  357.     if name == "Blocks" then
  358.       for i=1,i do
  359.         table.insert(blocks, h.read())
  360.       end
  361.     elseif name == "Data" then
  362.       for i=1,i do
  363.         table.insert(data, h.read())
  364.       end
  365.     else
  366.       readbytes(h,i)
  367.     end
  368.   elseif a==8 then
  369.     i1 = h.read()
  370.     i2 = h.read()
  371.     i = i1*256 + i2
  372.     readbytes(h,i)
  373.   elseif a==9 then
  374.     --readbytes(h,5)
  375.     local type = h.read()
  376.     i1 = h.read()
  377.     i2 = h.read()
  378.     i3 = h.read()
  379.     i4 = h.read()
  380.     i = i1*256*256*256 + i2*256*256 + i3*256 + i4
  381.     for j=1,i do
  382.       parse(h.read(), h, false)
  383.     end
  384.   end
  385. end
  386.  
  387. function forward()
  388.   while not turtle.forward() do
  389.     turtle.dig()
  390.   end
  391. end
  392.  
  393. function up()
  394.   while not turtle.up() do
  395.     turtle.digUp()
  396.   end
  397. end
  398.  
  399. function down()
  400.   while not turtle.down() do
  401.     turtle.digDown()
  402.   end
  403. end
  404.  
  405. function place()
  406.   while not turtle.placeDown() do
  407.     turtle.digDown()
  408.   end
  409. end
  410.  
  411. local function show_selected_slot(n)
  412.     local w,h = term.getCursorPos()
  413.     local itemData = turtle.getItemDetail(newSelect)
  414.     if itemData then
  415.         term.clearLine()
  416.         term.setCursorPos(1,h)
  417.         write("    "..itemData.name..", "..itemData.damage)
  418.     else
  419.         term.clearLine()
  420.         term.setCursorPos(1,h)
  421.         write("    ")
  422.     end
  423.     return itemData
  424. end
  425.  
  426. local function setColor(color)     
  427.     if term.isColor() then     
  428.         term.setTextColor(color)       
  429.     end    
  430. end
  431.    
  432. function setup(filename)
  433. --input file
  434. --returns blocks,data
  435. --requires parse, getBlockName
  436.  
  437.     if not fs.exists(filename) then
  438.         error("File "..tostring(filename).." does not exist.")
  439.     end
  440.     h = fs.open(filename, "rb")
  441.  
  442.     local a = 0
  443.     while (a ~= nil) do
  444.         a = h.read()
  445.         parse(a, h)
  446.     end
  447.  
  448.     write("length: " .. length)
  449.     write("   width: " .. width)
  450.     write("   height: " .. height .. "\n")
  451.    
  452.     uniqueblocks={}
  453.     for i,v in ipairs(blocks) do
  454.         found = false
  455.         for j,w in ipairs(uniqueblocks) do
  456.  
  457.             --[[if (w.blockID==v and (w.data==data[i] or w.blockID ~= 35)) then
  458.                 found = true
  459.                 w.amount = w.amount + 1
  460.                 break
  461.             end]]--
  462.  
  463.             --for now, data is only accounted for when the block is whool
  464.             if (w.blockID==v) and (w.data==data[i]) then
  465.                 found = true
  466.                 w.amount = w.amount + 1
  467.                 break
  468.             end
  469.         end
  470.  
  471.         if found==false then
  472.             uniqueblocks[#uniqueblocks+1] = {}
  473.             uniqueblocks[#uniqueblocks].blockID = v
  474.             uniqueblocks[#uniqueblocks].data = data[i]
  475.             uniqueblocks[#uniqueblocks].amount = 1
  476.         end
  477.     end
  478.  
  479.     if fs.exists("slots") then
  480.         print("slots file discovered...")
  481.         print("skipping setup")
  482.         h.close()
  483.         return
  484.     end
  485.  
  486.     print("number of block types: " .. #uniqueblocks)
  487.     for i,v in ipairs(uniqueblocks) do
  488.         if (i%9)==0 then
  489.             read()
  490.         end
  491.  
  492.         local stacks = math.ceil( (v.amount/64) )
  493.         setColor(colors.white)
  494.         write(" -" .. getBlockName(v.blockID, v.data))
  495.         setColor(colors.lightGray)
  496.         write("("..v.blockID..","..v.data..")")
  497.         setColor(colors.white)
  498.         write(": ")
  499.  
  500.         if v.amount > 64 then
  501.             setColor(colors.magenta)
  502.             print(stacks.." stacks")
  503.         else
  504.             setColor(colors.cyan)
  505.             print(v.amount)
  506.         end
  507.     end
  508.    
  509.     setColor(colors.white)
  510.  
  511.     read()
  512.    
  513.  
  514.     print("Use arrowKeys and enter to select slots containing block the turtle will use for the printed blockType")
  515.     setColor(colors.gray)
  516.     print("press x to skip(not use) the specified blockType")
  517.     setColor(colors.white)
  518.     slots={}
  519.     for i,block in ipairs(uniqueblocks) do
  520.         local n = nil
  521.         blockData = block.data
  522.        
  523.         setColor(colors.lightGray)
  524.         write(" -in which slots is ")
  525.         setColor(colors.lime)
  526.         write(getBlockName(block.blockID, blockData))
  527.         setColor(colors.lightGray)
  528.         print("("..block.blockID..","..blockData .. ") ?")
  529.         setColor(colors.white)
  530.         if not slots[block.blockID] then
  531.             slots[block.blockID] = {}
  532.         end
  533.         slots[block.blockID][blockData] = {}
  534.         show_selected_slot(turtle.getSelectedSlot())
  535.         --input none
  536.         --output(n)    
  537.  
  538.         --(oldWay)
  539.         if tArgs[2] == "sim" or tArgs[2] == "simulate" then
  540.             write("   ")
  541.             str = read()
  542.             n = tonumber(str)
  543.         else
  544.             n = numberSelector()
  545.         end
  546.  
  547.         local itemData = show_selected_slot(n)
  548.         if(n and itemData) then
  549.             print()
  550.             slots[block.blockID][blockData] = {itemData.name,itemData.damage}
  551.         else
  552.             local w,h = term.getCursorPos()
  553.             term.clearLine()
  554.             term.setCursorPos(1,h)
  555.             print("    SKIPPING")
  556.             slots[block.blockID][blockData] = {}
  557.         end
  558.     end
  559.    
  560.     h.close()
  561.     save("slots",slots)
  562. end
  563.  
  564. function numberSelector()
  565.  
  566.     local function selectNext(newSelect)
  567.         if newSelect >= 1 and newSelect <= 16 then
  568.             turtle.select(newSelect)
  569.             show_selected_slot(newSelect)
  570.         end
  571.     end
  572.  
  573.     local function ifKey(events,nKey,fn,...)
  574.         if events[1] == "key" and events[2] == tonumber(nKey) then
  575.             fn(...)
  576.         end
  577.     end
  578.  
  579.     local bRunning = true
  580.     local bNothing = false
  581.     while bRunning do
  582.         local events = { os.pullEvent("key") }
  583.         local newSelect
  584.         local selected = turtle.getSelectedSlot()
  585.    
  586.         ifKey(events,203,function() newSelect = selected - 1 ; selectNext(newSelect) ; end)
  587.         ifKey(events,205,function() newSelect = selected + 1 ; selectNext(newSelect) ; end)
  588.         ifKey(events,200,function() newSelect = selected - 4 ; selectNext(newSelect) ; end)
  589.         ifKey(events,208,function() newSelect = selected + 4 ; selectNext(newSelect) ; end)
  590.         ifKey(events,28,function() bRunning = false ; end)
  591.         ifKey(events,45,function() bNothing = true ; bRunning = false ; end)
  592.         ifKey(events,15,function() bNothing = true ; bRunning = false; end)
  593.  
  594.         for i = 2,13 do
  595.             ifKey(events,i,function() selectNext(i-1) end)
  596.         end
  597.         for i = 26,27 do
  598.             ifKey(events,i,function() selectNext(i-13) end)
  599.         end
  600.         for i = 39,40 do
  601.             ifKey(events,i,function() selectNext(i-24) end)
  602.         end
  603.     end
  604.     if bNothing then
  605.         return nil
  606.     else
  607.         return turtle.getSelectedSlot()
  608.     end
  609. end
  610.  
  611. -- [[ Iterators ]] --
  612.  
  613. function checkIfAir()
  614.     --finds the location to place the next block
  615.     while true do
  616.     x,y,z = iterate(x,y,z,startx,starty,startz,height-1,width-1,length-1)
  617.         --makes the turtle build faster by having to travel less
  618.         blockID2 = getBlockId(x,y,z)    -- temporary variable
  619.         blockData2 = getData(x,y,z)     -- temporary variable
  620.         if slots[blockID2] then
  621.             -- makes sure the next block to place at location is not air
  622.             slot_2nd = slots[blockID2][blockData2]
  623.             if slot_2nd then
  624.                 if #slot_2nd > 0 then
  625.                     recordObj(x,y,z)
  626.                     break
  627.                 end
  628.             end
  629.         end
  630.     end
  631. end
  632.  
  633. function check(x,y,z,startx,starty,startz)
  634.     if x%2==startx%2 then
  635.         oddx = true
  636.         if y%2==starty%2 then
  637.             oddy = true
  638.         else
  639.             oddy = false
  640.         end
  641.     else
  642.         oddx = false
  643.         if y%2==starty%2 then
  644.             oddy = false
  645.         else
  646.             oddy = true
  647.         end
  648.     end
  649.     return oddx,oddy
  650. end
  651.  
  652.  
  653. function Yiterate(x,y,z,startx,starty,startz,finalx,finaly,finalz)
  654.    
  655.     local height = finalx
  656.     local width = finaly
  657.     local length = finalz
  658.    
  659.     if oddx then
  660.         if y < width then
  661.             y = y + 1
  662.         elseif y == width then
  663.             if x < height then
  664.                 x = x + 1
  665.             --elseif x == height then
  666.                 --x,y,z = "max","max","max"
  667.             end
  668.         end
  669.     else
  670.         if y <= starty then
  671.             if x < height then
  672.                 x = x + 1
  673.             elseif x == height then
  674.                 x = "max"
  675.                 y = "max"
  676.                 z = "max"
  677.             end
  678.         else
  679.             y=y-1
  680.         end
  681.     end
  682.     return x,y,z
  683. end
  684.  
  685. function iterate(x,y,z,startx,starty,startz,finalx,finaly,finalz)
  686.    
  687.     local height = finalx
  688.     local width = finaly
  689.     local length = finalz
  690.    
  691.    
  692.     local oddx,oddy = check(x,y,z,startx,starty,startz)
  693.     if z == length and oddy then
  694.         x,y,z = Yiterate(x,y,z,startx,starty,startz,finalx,finaly,finalz)    
  695.     elseif z == startz and oddy then
  696.         z = z + 1
  697.     elseif z == startz and (not oddy) then
  698.         x,y,z = Yiterate(x,y,z,startx,starty,startz,finalx,finaly,finalz)
  699.     elseif z==length and (not oddy) then
  700.         z = z - 1
  701.  
  702.     elseif z < length then
  703.         if oddy then
  704.             z = z + 1
  705.         else
  706.             z = z - 1
  707.         end
  708.     end
  709.     return x,y,z
  710.  end
  711.  
  712. -- [[ TSP_algorithm API ]] --
  713.  
  714. local w,h = term.getSize()
  715.  
  716. local function calculateDistance(tNode1,tNode2)
  717.     local turnCost = 0
  718.     local deltaY,deltaZ
  719.     local y1 = tNode1[2]
  720.     local z1 = tNode1[3]
  721.     local y2 = tNode2[2]
  722.     local z2 = tNode2[3]
  723.    
  724.     deltaZ = z2-z1
  725.     deltaY = y2-y1
  726.    
  727.     if deltaZ == 0 or deltaY == 0 then
  728.         turnCost = 0
  729.     else
  730.         turnCost = 1
  731.     end
  732.    
  733.     return math.abs(deltaZ) + math.abs(deltaY) + turnCost
  734.     --return math.sqrt( (z2-z1)^2 + (y2-y1)^2 )
  735. end
  736.  
  737. local function twoOptSwap(route, i, k)
  738.     local new_route = {}
  739.     for c = 1,i-1 do
  740.         table.insert(new_route,route[c])
  741.     end
  742.     for c = k,i,-1 do
  743.         table.insert(new_route,route[c])
  744.     end
  745.     for c = k+1,#route do
  746.         table.insert(new_route,route[c])  
  747.     end
  748.     return new_route
  749. end
  750.  
  751. local function calculateTotalDistance(route)
  752.     local total = 0
  753.     for i = 1,#route-1 do
  754.         total = total + calculateDistance(route[i],route[i+1])
  755.     end
  756.     return total
  757. end
  758.  
  759. local function display(route,distance)
  760.     local l,h = term.getSize()
  761.     shell.run("clear")
  762.  
  763.     for i = 1,#route-1 do
  764.         paintutils.drawLine(route[i][2],route[i][3],route[i+1][2],route[i+1][3],colors.lime)
  765.     end
  766.     for i,coord in pairs(route) do
  767.         term.setBackgroundColor(colors.yellow)
  768.         term.setTextColor(colors.magenta)
  769.         if coord[2] < l and coord[2] >= 1 and coord[3] >= 1 and coord[3] < h then
  770.             term.setCursorPos(coord[2],coord[3])
  771.             local char = i + 64
  772.             if char > 190 then
  773.                 char = char - 190
  774.             end
  775.             if char > 380 then
  776.                 char = char - 380
  777.             end
  778.             term.write(string.char(char))
  779.         end
  780.     end
  781.     term.setBackgroundColor(colors.black)
  782.     term.setTextColor(colors.white)
  783.     term.setCursorPos(1,h)
  784.     term.write(distance)
  785. end
  786.  
  787. local route = {}
  788. route[1] = {1,28,3}
  789. route[2] = {1,36,13}
  790. route[3] = {1,20,8}
  791. route[4] = {1,8,8}
  792. route[5] = {1,44,5}
  793. route[6] = {1,32,13}
  794. route[7] = {1,20,17}
  795. --route[8] = {1,28,3}
  796.  
  797. function tsp_algorithm(existing_route)
  798.     local improve = 0
  799.     while improve < 3 do
  800.         local best_distance = calculateTotalDistance(existing_route)
  801.         for i = 2,#existing_route-1 do
  802.             for k = i + 1, #existing_route do
  803.                 new_route = twoOptSwap(existing_route, i, k)
  804.                 new_distance = calculateTotalDistance(new_route)
  805.                 if new_distance < best_distance then
  806.                     improve = 0
  807.                     existing_route = new_route
  808.                     best_distance = calculateTotalDistance(existing_route)
  809.                     display(existing_route,best_distance)
  810.                     sleep(0)
  811.                 end
  812.             end
  813.         end
  814.         improve = improve + 1
  815.     end
  816.     return existing_route, best_distance
  817. end
  818.  
  819. -- [[ schematic --> blueprint ]] --
  820.  
  821. --turtles[i].instructions[n] = {x,y,z,id,data}
  822. --i = multiturtle ie 1,2,3,4 ; n = step ie 1 - 256 (no air)
  823.  
  824. --fn splits 16x16 grid between 4 turtles returning startx,y,z and endx,y,z of 4 4x4 grids
  825. --fn takes each 4x4 grid and turns them into instructions[n] = {x,y,z,id,data}
  826. --fn for master turtle to setup all slave turtles with the instructions[n] table and goto/find/place functions
  827.  
  828. function blueprint(startx,starty,startz,finalx,finaly,finalz)
  829.     --uses iterator to make instructions[n] table
  830.     local x,y,z = startx,starty,startz
  831.     local instructions = {}
  832.     local nTimes = (finalx+1-startx)*(finaly+1-starty)*(finalz+1-startz)
  833.     for i=1,nTimes do
  834.         if x == "max" then
  835.             break
  836.         end
  837.         local id = getBlockId(x,y,z)
  838.         local data = getData(x,y,z)
  839.         if id > 0 then
  840.             table.insert(instructions,{x,y,z,id,data})
  841.         end
  842.         x,y,z = iterate(x,y,z,startx,starty,startz,finalx,finaly,finalz)
  843.     end
  844.     return instructions
  845. end
  846.  
  847. function improveBlueprint(instructions,startx,starty,startz,finalx,finaly,finalz)
  848.     local function instructions2layers(instructions)
  849.         local layers = {}
  850.         for x = startx,finalx do
  851.             layers[x] = {}
  852.             for n=1,#instructions do
  853.                 if instructions[n][1] == x then
  854.                     table.insert(layers[x],{unpack(instructions[n],1,3)})
  855.                 end
  856.             end
  857.         end
  858.         return layers
  859.     end
  860.     local function organize(layers)
  861.         local startingPosition = {startx,starty,startz}
  862.         for x = startx,finalx do
  863.             table.insert(layers[x],1,startingPosition)
  864.             layers[x] = tsp_algorithm(layers[x])
  865.             startingPosition = layers[x][#layers[x]]
  866.         end
  867.         return layers
  868.     end
  869.  
  870.     local function layers2instructions(layers)
  871.         local instructions = {}
  872.         --organizedlayers only
  873.         for x = startx,finalx do
  874.             for i = 2,#layers[x] do
  875.                 table.insert(instructions,layers[x][i])
  876.             end
  877.         end
  878.         return instructions
  879.     end
  880.  
  881.     local function add_id_and_data(instructions)
  882.         for n = 1,#instructions do
  883.             instructions[n][4] = getBlockId(unpack(instructions[n],1,3))
  884.             instructions[n][5] = getData(unpack(instructions[n],1,3))
  885.         end
  886.         return instructions
  887.     end
  888.  
  889.     local layers = instructions2layers(instructions)
  890.     layers = organize(layers)
  891.     local new_instructions = layers2instructions(layers)
  892.     new_instructions = add_id_and_data(new_instructions)
  893.     return new_instructions
  894. end
  895.  
  896. function simulateIns(instructions)
  897.     local w,h = term.getSize()
  898.     local lastx = 0
  899.     shell.run("clr")
  900.     for n = 1,#instructions do
  901.         if lastx~=instructions[n][1] then
  902.             term.setBackgroundColor(colors.black)
  903.             shell.run("clr")
  904.         end
  905.         if instructions[n][2]+1 >= 1 and instructions[n][3]+1 >= 1 and instructions[n][2]+1 < w and instructions[n][3]+1 <  h then
  906.             term.setCursorPos(instructions[n][2]+1,instructions[n][3]+1)
  907.             term.setBackgroundColor(2^instructions[n][5])
  908.             term.write(" ")
  909.         end
  910.         lastx = instructions[n][1]
  911.         sleep(0)
  912.     end
  913. end
  914.  
  915. function orientation_check(reference,slots)
  916.     for id,table in pairs(slots) do
  917.         for data,table2 in pairs(table) do
  918.             if table2 and table2[1] then
  919.                 if (table2[1]:find("stairs") or table2[1]:find("chest") or table2[1]:find("furnace")) then
  920.                     for n = 1,5 do
  921.                         term.scroll(1)
  922.                         sleep(0)
  923.                     end
  924.                     print("orientation required")
  925.                     print("what direction is the turtle facing?")
  926.                     local r
  927.                     while true do
  928.                         write("    ")
  929.                         if term.isColor() then
  930.                             term.setTextColor(colors.yellow)
  931.                         end
  932.                         r = read()
  933.                         r = tostring(r):lower()
  934.                         term.setTextColor(colors.white)
  935.                         if r ~= "south" and r~= "north" and r~= "west" and r~= "east" then
  936.                             print(r.. " not recognized, north/south/east/west?")
  937.                         else
  938.                             break
  939.                         end
  940.                     end
  941.                
  942.                     reference.relativeDirection = r
  943.                     print("don't forget to include wrench in turtle!")
  944.                     reference.wrench = true
  945.                     return reference
  946.                 end
  947.             end
  948.         end
  949.     end
  950.     return reference
  951. end
  952.  
  953. function multiturtle_check(reference)
  954.     write("How many Turtles?: ")
  955.     local n = read()
  956.     n = tonumber(n)
  957.     if n then
  958.         if n == 1 then
  959.             reference.multiturtle = false
  960.         else
  961.             reference.multiturtle = n
  962.         end
  963.     end
  964.     print()
  965.     return reference
  966. end
  967.  
  968. local function Main()
  969.     setup(filename)
  970.  
  971.     --save("blocks",blocks)
  972.     --save("data",data)
  973.     --save("uniqueblocks",uniqueblocks)
  974.  
  975.     reference = {
  976.         startx = 0,
  977.         starty = 0,
  978.         startz = 0,
  979.         finalx = height-1,
  980.         finaly = width-1,
  981.         finalz = length-1,
  982.         height = height,
  983.         width = width,
  984.         length = length,
  985.         wrench = false,
  986.         multiturtle = false, -- otherwise its a number (1,2,4,8,12,etc),
  987.         relativeDirection = "south",
  988.         numChests = false,
  989.         filename = false,
  990.         returnx = 0,
  991.         returny = 0,
  992.         returnz = -1,
  993.     }
  994.    
  995.     if not slots then
  996.         slots = textutils.unserialize( fs.open("slots","r").readAll() )
  997.     end
  998.  
  999.     reference = orientation_check(reference,slots)
  1000.     reference = multiturtle_check(reference)
  1001.    
  1002.     local instructions = blueprint(reference.startx,reference.starty,reference.startz,reference.finalx,reference.finaly,reference.finalz)
  1003.     if reference.multiturtle then
  1004.         local A1 = Class_Grid(instructions,reference.starty,reference.startz,reference.finaly,reference.finalz)
  1005.         local startLocations = {nTurtleSplit(reference.multiturtle,A1)}
  1006.         for i,v in pairs(startLocations) do
  1007.             local nTurtle = i
  1008.             local ref = reference
  1009.             ref.starty = v.starty
  1010.             ref.startz = v.startz
  1011.             ref.finaly = v.finaly
  1012.             ref.finalz = v.finalz
  1013.             local ins = blueprint(ref.startx,v.starty,v.startz,ref.finalx,v.finaly,v.finalz)
  1014.             if tArgs[2] == "tsp" then
  1015.                 ins = improveBlueprint(ins,ref.startx,ref.starty,ref.startz,ref.finalx,ref.finaly,ref.finalz)
  1016.             end
  1017.            
  1018.             local fname = saveBlueprint(ref,slots,ins,uniqueblocks,nTurtle)
  1019.             print(ref.starty," ",ref.startz," ",ref.finaly," ",ref.finalz)
  1020.             print(fname," saved")
  1021.         end
  1022.     else
  1023.        
  1024.         if tArgs[2] == "tsp" then
  1025.             instructions = improveBlueprint(instructions,reference.startx,reference.starty,reference.startz,reference.finalx,reference.finaly,reference.finalz)
  1026.         end
  1027.     --textutils.pagedPrint(textutils.serialize(ins))
  1028.     --saveIns("instructions",ins)
  1029.         local fname = saveBlueprint(reference,slots,instructions,uniqueblocks)
  1030.         print(fname," saved")
  1031.     --delete slots,reference,ins,uniqueblocks files
  1032.     end
  1033. end
  1034.  
  1035. Main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement