Advertisement
guitarplayer616

SchemFixed2

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