Advertisement
naxishere

Untitled

Aug 3rd, 2024 (edited)
247
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.02 KB | None | 0 0
  1. is_test = false
  2. Coord = {}
  3.  
  4. function Coord:new(x, y, z)
  5.   local o = {x = x, y = y, z = z}
  6.   self.__index = self
  7.   return setmetatable(o, self)
  8. end
  9.  
  10. Box = {}
  11.  
  12. function Box:new(coord1, coord2)
  13.   local o = {coord1 = coord1, coord2 = coord2}
  14.   o = setmetatable(o, self)
  15.   self.__index = self
  16.   return o
  17. end
  18.  
  19. function Box:contains(coord)
  20.   local max_x, min_x = math.max(self.coord1.x, self.coord2.x), math.min(self.coord1.x, self.coord2.x)
  21.   local max_y, min_y = math.max(self.coord1.y, self.coord2.y), math.min(self.coord1.y, self.coord2.y)
  22.   local max_z, min_z = math.max(self.coord1.z, self.coord2.z), math.min(self.coord1.z, self.coord2.z)
  23.    return coord.x <= max_x and coord.x >= min_x and coord.y <= max_y and coord.y >= min_y and coord.z <= max_z and coord.z >= min_z
  24. end
  25.  
  26. Set = {}
  27.  
  28. function Set:new()
  29.   local o = {}
  30.   self.__index = self
  31.   return setmetatable(o, self)
  32. end
  33.  
  34. function Set:of_list(list)
  35.   local o = Set:new()
  36.   for _, val in ipairs(list) do
  37.     o:add(val)
  38.   end
  39.   return o
  40. end
  41.  
  42. function Set:add(val)
  43.   self[val] = true
  44. end
  45.  
  46. function Set:mem(val)
  47.   return self[val] ~= nil
  48. end
  49.  
  50. function Set:remove(val)
  51.   self[val] = nil
  52. end
  53.  
  54. function Set:union(other)
  55.   local new_set = Set:new()
  56.   for k, _ in pairs(self) do
  57.     new_set:add(k)
  58.   end
  59.   for k, _ in pairs(other) do
  60.     new_set:add(k)
  61.   end
  62.   return new_set
  63. end
  64.  
  65.  
  66. base_box = Box:new(Coord:new(34, 62, -1617), Coord:new(45, 70, -1623))
  67.  
  68. non_veins = Set:of_list{"minecraft:stone", "minecraft:cobblestone", "minecraft:diorite", "minecraft:gravel", "minecraft:dirt", "minecraft:andesite", "minecraft:granite", "minecraft:lava", "minecraft:obsidian", "minecraft:water", "minecraft:chest", "minecraft:base_stone_nether", "minecraft:basalt", "minecraft:netherrack", "minecraft:blackstone", "minecraft:nether_quartz_ore"}
  69.  
  70.  
  71. function should_mine(block)
  72.   return non_veins[block] ~= nil
  73. end
  74.  
  75. function test()
  76.   local first = Coord:new(1, 2, 3)
  77.   local second = Coord:new(6, 7, 8)
  78.   local box = Box:new(first, second)
  79.   print(box:contains(second)) -- true
  80.   print(box:contains(Coord:new(8, 9, 10))) -- false
  81.   print(box:contains(Coord:new(4, 5, 6))) -- true
  82. end
  83.  
  84. Movement = {
  85.   Forward = {},
  86.   Backward = {},
  87.   Up = {},
  88.   Down = {},
  89.   Left = {},
  90.   Right = {}
  91. }
  92.  
  93. function Movement:opposite(movement)
  94.   if movement == self.Forward then
  95.     return self.Backward
  96.   elseif movement == self.Backward then
  97.     return self.Forward
  98.   elseif movement == self.Up then
  99.     return self.Down
  100.   elseif movement == self.Down then
  101.     return self.Up
  102.   elseif movement == self.Left then
  103.     return self.Right
  104.   elseif movement == self.Right then
  105.     return self.Left
  106.   end
  107. end
  108.  
  109. function Movement:execute(movement)
  110.   if is_test then
  111.     return true
  112.   end
  113.   if movement == self.Forward then
  114.     return turtle.forward()
  115.   elseif movement == self.Backward then
  116.     return turtle.back()
  117.   elseif movement == self.Up then
  118.     return turtle.up()
  119.   elseif movement == self.Down then
  120.     return turtle.down()
  121.   elseif movement == self.Left then
  122.     turtle.turnLeft()
  123.     return true
  124.   elseif movement == self.Right then
  125.     turtle.turnRight()
  126.     return true
  127.   end
  128. end
  129.  
  130. Cardinal = {
  131.   North = {},
  132.   East = {},
  133.   South = {},
  134.   West = {}
  135. }
  136.  
  137. function Cardinal:read()
  138.   local cardinal = io.read()
  139.   if cardinal == "north" then
  140.     return Cardinal.North
  141.   elseif cardinal == "east" then
  142.     return Cardinal.East
  143.   elseif cardinal == "south" then
  144.     return Cardinal.South
  145.   elseif cardinal == "west" then
  146.     return Cardinal.West
  147.   else
  148.       error("Invalid cardinal direction")
  149.   end
  150. end
  151.  
  152. function Cardinal:right(cardinal)
  153.   if cardinal == self.North then
  154.     return self.East
  155.   elseif cardinal == self.East then
  156.     return self.South
  157.   elseif cardinal == self.South then
  158.     return self.West
  159.   elseif cardinal == self.West then
  160.     return self.North
  161.   end
  162. end
  163.  
  164. function Cardinal:left(cardinal)
  165.   if cardinal == self.North then
  166.     return self.West
  167.   elseif cardinal == self.West then
  168.     return self.South
  169.   elseif cardinal == self.South then
  170.     return self.East
  171.   elseif cardinal == self.East then
  172.     return self.North
  173.   end
  174. end
  175.  
  176. function Cardinal:update_forward(coord)
  177.   if self.facing == self.North then
  178.     coord.z = coord.z - 1
  179.   elseif self.facing == self.East then
  180.     coord.x = coord.x + 1
  181.   elseif self.facing == self.South then
  182.     coord.z = coord.z + 1
  183.   elseif self.facing == self.West then
  184.     coord.x = coord.x - 1
  185.   end
  186. end
  187.  
  188. function Cardinal:update_backward(coord)
  189.   if self.facing == self.North then
  190.     coord.z = coord.z + 1
  191.   elseif self.facing == self.East then
  192.     coord.x = coord.x - 1
  193.   elseif self.facing == self.South then
  194.     coord.z = coord.z - 1
  195.   elseif self.facing == self.West then
  196.     coord.x = coord.x + 1
  197.   end
  198. end
  199.  
  200.  
  201. Robot = {}
  202.  
  203. function Robot:new(start, facing)
  204.   local o = { log = {}, start = start, current_coord = start, facing = facing }
  205.   self.__index = self
  206.   return setmetatable(o, self)
  207. end
  208.  
  209. function Robot:execute(movement)
  210.   if not Movement:execute(movement) then
  211.     return false
  212.   end
  213.  
  214.   if movement == Movement.Forward then
  215.     Cardinal:update_forward(self.current_coord)
  216.   elseif movement == Movement.Backward then
  217.     Cardinal:update_backward(self.current_coord)
  218.   elseif movement == Movement.Left then
  219.     self.facing = Cardinal:left(self.facing)
  220.   elseif movement == Movement.Right then
  221.     self.facing = Cardinal:right(self.facing)
  222.   elseif movement == Movement.Up then
  223.     self.current_coord.y = self.current_coord.y + 1
  224.   elseif movement == Movement.Down then
  225.     self.current_coord.y = self.current_coord.y - 1
  226.   end
  227.   return true
  228. end
  229.  
  230. function Robot:execute_and_log(movement)
  231.   if not self:execute(movement) then
  232.     return false
  233.   end
  234.   table.insert(self.log, movement)
  235.   return true
  236. end
  237.  
  238. function Robot:backtrack_once()
  239.   local last_movement = self.log[#self.log]
  240.   if not self:execute(Movement:opposite(last_movement)) then
  241.     return false
  242.   end
  243.   table.remove(self.log)
  244.   return true
  245. end
  246.  
  247. function Robot:move_x(x_diff)
  248.   if x_diff == 0 then
  249.     return 0
  250.   end
  251.  
  252.   if self.facing == Cardinal.East then
  253.     if x_diff > 0 then
  254.       if not self:execute_and_log(Movement.Forward) then return x_diff end
  255.       return self:move_x(x_diff - 1)
  256.     else
  257.       if not self:execute_and_log(Movement.Backward) then return x_diff end
  258.       return self:move_x(x_diff + 1)
  259.     end
  260.   elseif self.facing == Cardinal.West then
  261.     if x_diff > 0 then
  262.       if not self:execute_and_log(Movement.Backward) then return x_diff end
  263.       return self:move_x(x_diff - 1)
  264.     else
  265.       if not self:execute_and_log(Movement.Forward) then return x_diff end
  266.       return self:move_x(x_diff + 1)
  267.     end
  268.   elseif self.facing == Cardinal.North or self.facing == Cardinal.South then
  269.     self:execute_and_log(Movement.Right)
  270.     return self:move_x(x_diff)
  271.   end
  272. end
  273.  
  274. function Robot:move_z(z_diff)
  275.   if z_diff == 0 then
  276.     return 0
  277.   end
  278.  
  279.   if self.facing == Cardinal.South then
  280.     if z_diff > 0 then
  281.       if not self:execute_and_log(Movement.Forward) then return z_diff end
  282.       return self:move_z(z_diff - 1)
  283.     else
  284.       if not self:execute_and_log(Movement.Backward) then return z_diff end
  285.       return self:move_z(z_diff + 1)
  286.     end
  287.   elseif self.facing == Cardinal.North then
  288.     if z_diff > 0 then
  289.       if not self:execute_and_log(Movement.Backward) then return z_diff end
  290.       return self:move_z(z_diff - 1)
  291.     else
  292.       if not self:execute_and_log(Movement.Forward) then return z_diff end
  293.       return self:move_z(z_diff + 1)
  294.     end
  295.   elseif self.facing == Cardinal.East or self.facing == Cardinal.West then
  296.     self:execute_and_log(Movement.Right)
  297.     return self:move_z(z_diff)
  298.   end
  299. end
  300.  
  301. function Robot:move_to_coord(coord)
  302.   local x_diff = coord.x - self.current_coord.x
  303.   local y_diff = coord.y - self.current_coord.y
  304.   local z_diff = coord.z - self.current_coord.z
  305.  
  306.   while y_diff ~= 0 do
  307.     if y_diff > 0 then
  308.       if not self:execute_and_log(Movement.Up) then break end
  309.       y_diff = y_diff - 1
  310.     elseif y_diff < 0 then
  311.       if not self:execute_and_log(Movement.Down) then break end
  312.       y_diff = y_diff + 1
  313.     end
  314.   end
  315.  
  316.   if y_diff ~= 0 then
  317.     return false
  318.   end
  319.  
  320.   if self:move_x(x_diff) ~= 0 then return false end
  321.   if self:move_z(z_diff) ~= 0 then return false end
  322.   return true
  323. end
  324.  
  325. function Robot:backtrack_all()
  326.   while #self.log > 0 do
  327.     if not self:backtrack_once() then return false end
  328.   end
  329.   return true
  330. end
  331.  
  332. function Robot:move_test()
  333.  
  334.   write("Enter the ending x coordinate: ")
  335.   local x = tonumber(io.read())
  336.   write("Enter the ending y coordinate: ")
  337.   local y = tonumber(io.read())
  338.   write("Enter the ending z coordinate: ")
  339.   local z = tonumber(io.read())
  340.  
  341.   local end_ = Coord:new(x, y, z)
  342.  
  343.   self:move_to_coord(end_)
  344.   self:backtrack_all()
  345. end
  346.  
  347. function main()
  348.   os.loadAPI("spec.lua")
  349.  
  350.   local start = Coord:new(spec.start_x, spec.start_y, spec.start_z)
  351.   local robot = Robot:new(start, spec.start_facing)
  352.   robot:move_test()
  353. end
  354.  
  355. if is_test then test() else main() end
  356.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement