Advertisement
ondrej008

Untitled

Nov 15th, 2019
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.66 KB | None | 0 0
  1. local startingPosition = { x = 0, y = 0, z = 0}
  2.  
  3. local blocksExplored = {}
  4. local blocksExploredTravellable = {}
  5. local blockQueue = {}
  6. local logMessages = {}
  7.  
  8. local dirWorld = "north"
  9.  
  10. term.write("Enable debug output mode?: ")
  11. local debugOn = true
  12. if(io.read("*l") == "false") then
  13. debugOn = false
  14. end
  15. term.write("Enable block logging mode?: ")
  16. local blockLog = true
  17. if(io.read("*l") == "false") then
  18. blockLog = false
  19. end
  20. term.write("Enable distance logging mode?: ")
  21. local distanceLog = true
  22. if(io.read("*l") == "false") then
  23. distanceLog = false
  24. end
  25. term.write("Enter turtle's x coordinate: ")
  26. startingPosition.x = io.read("*l")
  27. term.write("Enter turtle's y coordinate: ")
  28. startingPosition.y = io.read("*l")
  29. term.write("Enter turtle's z coordinate: ")
  30. startingPosition.z = io.read("*l")
  31. local currentPosition = startingPosition
  32.  
  33. local function tableString(tbl)
  34. local str = "{"
  35. for k,v in pairs(tbl) do
  36. str = str .. k .. "=" .. v
  37. end
  38. str = str .. "}"
  39. return str
  40. end
  41.  
  42. local function consumeFuel()
  43. for i = 1, 16, 1 do
  44. local fuelDifference = turtle.getFuelLimit() - turtle.getFuelLevel()
  45. if(fuelDifference < (80 * 64)) then
  46. turtle.refuel()
  47. end
  48. end
  49. term.write("[CaveEX]: New fuel amount is " .. turtle.getFuelLevel() .. " actions/moves.")
  50. end
  51.  
  52. local function compactPosition()
  53. return "x: " .. currentPosition.x .. ", y: " .. currentPosition.y .. ", z: " .. currentPosition.z
  54. end
  55.  
  56. local function logMessage(msg)
  57. logMessages[#logMessages + 1] = tostring(msg)
  58. if(debugOn) then print(msg) end
  59. end
  60.  
  61. local function updatePosition()
  62. if(dirWorld == "north") then
  63. startingPosition.z = startingPosition.z + 1
  64. elseif(dirWorld == "south") then
  65. startingPosition.z = startingPosition.z - 1
  66. elseif(dirWorld == "west") then
  67. startingPosition.x = startingPosition.x - 1
  68. elseif(dirWorld == "east") then
  69. startingPosition.x = startingPosition.x + 1
  70. end
  71. end
  72.  
  73. local function forward(n)
  74. for i = 1, n, 1 do
  75. turtle.forward()
  76. updatePosition()
  77. end
  78. end
  79.  
  80. local function noDuplicate(newEntry)
  81. for i, v in pairs(blocksExplored) do
  82. if(v == newEntry) then
  83. logMessage("[CaveEX]: Found duplicate in blocksExplored " .. tableString(newEntry))
  84. return false
  85. end
  86. end
  87.  
  88. for i, v in pairs(blockQueue) do
  89. if(v == newEntry) then
  90. logMessage("[CaveEX]: Found duplicate in blockQueue " .. tableString(newEntry))
  91. return false
  92. end
  93. end
  94.  
  95. return true
  96. end
  97.  
  98. local function dirToOffset()
  99. if(dirWorld == "north") then
  100. return 0, 1
  101. elseif(dirWorld == "south") then
  102. return 0, -1
  103. elseif(dirWorld == "west") then
  104. return -1, 0
  105. elseif(dirWorld == "east") then
  106. return 1, 0
  107. end
  108. end
  109.  
  110. local function leftTurn()
  111. if(dirWorld == "north") then
  112. dirWorld = "west"
  113. elseif(dirWorld == "west") then
  114. dirWorld = "south"
  115. elseif(dirWorld == "south") then
  116. dirWorld = "east"
  117. elseif(dirWorld == "east") then
  118. dirWorld = "north"
  119. end
  120. end
  121.  
  122. local function addIfAirFront()
  123. consumeFuel()
  124. if(not turtle.detect()) then
  125. local x0, z0 = dirToOffset()
  126. local newEntry = { x = currentPosition.x + x0, y = currentPosition.y, z = currentPosition.z + z0 }
  127. if(noDuplicate(newEntry)) then
  128. blockQueue[#blockQueue + 1] = newEntry
  129. if(blockLog) then logMessage("[CaveEX]: blockQueue += " .. tableString(blockQueue[#blockQueue])) end
  130. end
  131. else
  132. local x0, z0 = dirToOffset()
  133. local success, data = turtle.inspect()
  134. local newEntry = { x = currentPosition.x + x0, y = currentPosition.y, z = currentPosition.z + z0, name = data.name, meta = data.metadata }
  135. if(noDuplicate(newEntry)) then
  136. blocksExplored[#blocksExplored + 1] = newEntry
  137. if(blockLog) then logMessage("[CaveEX]: blocksExplored += " .. tableString(blocksExplored[#blocksExplored])) end
  138. end
  139. end
  140. turtle.turnLeft()
  141. leftTurn()
  142. end
  143.  
  144. local function addIfAir()
  145. if(not turtle.detectDown()) then
  146. local newEntry = { x = currentPosition.x, y = currentPosition.y - 1, z = currentPosition.z }
  147. if(noDuplicate(newEntry)) then
  148. blockQueue[#blockQueue + 1] = newEntry
  149. if(blockLog) then logMessage("[CaveEX]: blockQueue += " .. tableString(blockQueue[#blockQueue])) end
  150. end
  151. else
  152. local success, data = turtle.inspectDown()
  153. local newEntry = { x = currentPosition.x, y = currentPosition.y - 1, z = currentPosition.z, name = data.name, meta = data.metadata }
  154. if(noDuplicate(newEntry)) then
  155. blocksExplored[#blocksExplored + 1] = newEntry
  156. if(blockLog) then logMessage("[CaveEX]: blocksExplored += " .. tableString(blocksExplored[#blocksExplored])) end
  157. end
  158. end
  159.  
  160. if(not turtle.detectUp()) then
  161. local newEntry = { x = currentPosition.x, y = currentPosition.y + 1, z = currentPosition.z }
  162. if(noDuplicate(newEntry)) then
  163. blockQueue[#blockQueue + 1] = newEntry
  164. if(blockLog) then logMessage("[CaveEX]: blockQueue += " .. tableString(blockQueue[#blockQueue])) end
  165. end
  166. else
  167. local success, data = turtle.inspectUp()
  168. local newEntry = { x = currentPosition.x, y = currentPosition.y + 1, z = currentPosition.z, name = data.name, meta = data.metadata }
  169. if(noDuplicate(newEntry)) then
  170. blocksExplored[#blocksExplored + 1] = newEntry
  171. if(blockLog) then logMessage("[CaveEX]: blocksExplored += " .. tableString(blocksExplored[#blocksExplored])) end
  172. end
  173. end
  174.  
  175. addIfAirFront()
  176. addIfAirFront()
  177. addIfAirFront()
  178. addIfAirFront()
  179.  
  180. blocksExplored[#blocksExplored + 1] = { x = currentPosition.x, y = currentPosition.y, z = currentPosition.z, name = "air", meta = "nil" }
  181. blocksExploredTravellable[#blocksExploredTravellable + 1] = { x = currentPosition.x, y = currentPosition.y, z = currentPosition.z }
  182. end
  183.  
  184. term.write("CaveEX starting from " .. compactPosition())
  185.  
  186. local timeStart = os.clock()
  187.  
  188. consumeFuel()
  189.  
  190. -- Populate blockQueue with the blocks around us.
  191.  
  192. addIfAir()
  193.  
  194. local function lowestTable(tbl)
  195. local lowestValue = 999999
  196. local lowest = nil
  197. for key, value in pairs(tbl) do
  198. if(value < lowestValue) then
  199. lowestValue = value
  200. lowest = key
  201. end
  202. end
  203. return lowest
  204. end
  205.  
  206. local function indexTable(tbl, ele)
  207. for key, value in pairs(tbl) do
  208. if(value.x == ele.x and value.y == ele.y and value.z == ele.z) then
  209. return key
  210. end
  211. end
  212. end
  213.  
  214. local function getNeighbours(current)
  215. local returnable = {}
  216. for key, value in pairs(blocksExploredTravellable) do
  217. if(value.x == current.x and value.y == current.y and (value.z == current.z + 1 or value.z == current.z - 1)) then
  218. returnable[#returnable + 1] = value
  219. elseif((value.x == current.x + 1 or value.x == current.x - 1) and value.y == current.y and value.z == current.z) then
  220. returnable[#returnable + 1] = value
  221. elseif(value.x == current.x and (value.y == current.y + 1 or value.y == current.y - 1) and value.z == current.z) then
  222. returnable[#returnable + 1] = value
  223. end
  224. end
  225. end
  226.  
  227. local function h(value, goal)
  228. local xD = goal.x - value.x
  229. local yD = (goal.y - value.y) * 10
  230. local zD = goal.z - value.z
  231. return math.sqrt(xD^2 + yD^2 + zD^2)
  232. end
  233.  
  234. local function tableIn(tbl, ele)
  235. for key, value in pairs(tbl) do
  236. if(ele.x == key.x and ele.y == key.y and ele.z == key.z) then
  237. return true
  238. end
  239. end
  240.  
  241. return false
  242. end
  243.  
  244. local function tablePrepend(tbl, ele)
  245. local returnable = { ele }
  246.  
  247. for key, value in pairs(tbl) do
  248. returnable[key] = value
  249. end
  250.  
  251. return returnable
  252. end
  253.  
  254. local function reconstructPath(cameFrom, current)
  255. totalPath = { current }
  256. while(tableIn(cameFrom, current)) do
  257. current = cameFrom[current]
  258. totalPath = tablePrepend(totalPath, current)
  259. end
  260. return totalPath
  261. end
  262.  
  263. local function aSTAR(start, goal)
  264. local openSet = { start } -- number indexed
  265. local cameFrom = {} -- value indexed
  266.  
  267. local gScore = {} -- value indexed
  268. gScore[start] = 0
  269.  
  270. local fScore = {} -- value indexed
  271. fScore[start] = h(start, goal)
  272.  
  273. while(#openSet > 0) do
  274. local current = lowestTable(fScore) -- check
  275. if(current == goal) then
  276. --term.write("I FRIKKIN GOT IT BOY!")
  277. return reconstructPath(cameFrom, current)
  278. end
  279.  
  280. openSet[indexTable(openSet, current)] = nil -- check
  281. if(getNeighbours(current)) then
  282. for key, value in pairs(getNeighbours(current)) do
  283. local tentative_gScore = gScore[current] + 1
  284. if(tentative_gScore < gScore[value]) then
  285. cameFrom[value] = current
  286. gScore[value] = tentative_gScore
  287. fScore[value] = gScore[value] + h(value, goal)
  288. if(openSet[indexTable(openSet, value)] == nil) then
  289. openSet[#openSet + 1] = value
  290. end
  291. end
  292. end
  293. else
  294. --term.write("No neighbors...")
  295. return { goal }
  296. end
  297. end
  298.  
  299. --term.write("didn't find it, sad!")
  300. end
  301.  
  302. local function moveTo(goal)
  303. print("From: " .. tableString(currentPosition) .. ", To: " .. tableString(goal))
  304. end
  305.  
  306. local function pathfind()
  307. -- Pathfind our way to the nearest block.
  308. local nearestBlock = { x = 0, y = 0, z = 0 }
  309. local nearestBlockValue = 999999
  310. for _,v in pairs(blockQueue) do
  311. local xD = currentPosition.x - v.x
  312. local yD = (currentPosition.y - v.y) * 10 -- height difference mega important
  313. local zD = currentPosition.z - v.z
  314. local distance = math.sqrt(xD^2 + yD^2 + zD^2)
  315. if(distanceLog) then logMessage("[CaveEX]: New distance " .. distance) end
  316. if(distance < nearestBlockValue) then
  317. nearestBlockValue = distance
  318. nearestBlock = { x = v.x, y = v.y, z = v.z }
  319. end
  320. end
  321. if(distanceLog) then logMessage("[CaveEX]: Closest block " .. tableString(nearestBlock)) end
  322. local path = aSTAR(currentPosition, nearestBlock)
  323.  
  324. for key, value in pairs(path) do
  325. print("Moving to: " .. key .. " = " .. tableString(value))
  326. moveTo(value)
  327. end
  328. end
  329.  
  330. --[[while(#blockQueue > 0) do
  331. pathfind()
  332. addIfAir()
  333. end]]
  334.  
  335. pathfind()
  336.  
  337. local timeEnd = os.clock() - timeStart
  338.  
  339. term.write("CaveEX finished in " .. timeEnd .. " seconds.")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement