SomeoneNew666

voxel

Feb 28th, 2025 (edited)
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 56.89 KB | None | 0 0
  1. -- Hybrid Optimal Mining Algorithm for ComputerCraft
  2. -- Combines minimal rotations with optimal layer transitions
  3. -- Dynamically selects the best pattern based on room dimensions
  4.  
  5. -- Define the directions (ComputerCraft orientation)
  6. local DIRECTIONS = {
  7. NORTH = 0, -- -Z (toward starting edge)
  8. EAST = 1, -- +X
  9. SOUTH = 2, -- +Z (deeper into the room)
  10. WEST = 3 -- -X
  11. }
  12.  
  13. -- Direction names for debugging
  14. local DIRECTION_NAMES = {
  15. [0] = "NORTH",
  16. [1] = "EAST",
  17. [2] = "SOUTH",
  18. [3] = "WEST"
  19. }
  20.  
  21. -- Define the costs
  22. local MOVEMENT_COST = 1
  23. local ROTATION_COST = 8
  24.  
  25. -- Initialize tracking variables
  26. local currentDir = DIRECTIONS.SOUTH -- Default turtle starts facing into the room (SOUTH)
  27. local totalCost = 0
  28. local movements = 0
  29. local rotations = 0
  30. local blocksDigged = 0
  31.  
  32. -- Function to calculate the relative rotation to reach the target direction
  33. local function getRotation(currentDir, targetDir)
  34. local diff = (targetDir - currentDir) % 4
  35. if diff == 0 then
  36. return 0 -- No rotation needed
  37. elseif diff == 1 then
  38. return 1 -- Turn right once
  39. elseif diff == 2 then
  40. return 2 -- Turn either way twice (we'll choose right twice)
  41. else -- diff == 3
  42. return -1 -- Turn left once (quicker than three rights)
  43. end
  44. end
  45.  
  46. -- Function to rotate the turtle to face a specific direction
  47. local function rotateTo(targetDir, simulate)
  48. if currentDir == targetDir then
  49. return true -- Already facing the correct direction
  50. end
  51.  
  52. local rotation = getRotation(currentDir, targetDir)
  53.  
  54. if not simulate then
  55. if rotation == 1 then
  56. -- Turn right once
  57. if not turtle.turnRight() then
  58. print("Failed to turn right")
  59. return false
  60. end
  61. elseif rotation == 2 then
  62. -- Turn right twice
  63. if not turtle.turnRight() then
  64. print("Failed to turn right (1/2)")
  65. return false
  66. end
  67. if not turtle.turnRight() then
  68. print("Failed to turn right (2/2)")
  69. return false
  70. end
  71. elseif rotation == -1 then
  72. -- Turn left once
  73. if not turtle.turnLeft() then
  74. print("Failed to turn left")
  75. return false
  76. end
  77. end
  78. end
  79.  
  80. -- Update tracking variables
  81. rotations = rotations + math.abs(rotation)
  82. totalCost = totalCost + ROTATION_COST * math.abs(rotation)
  83.  
  84. -- Update current direction
  85. currentDir = targetDir
  86. return true
  87. end
  88.  
  89. -- Function to dig and move in the current direction
  90. local function digAndMoveForward(simulate)
  91. if not simulate then
  92. -- Always try to dig first
  93. if turtle.detect() then
  94. if not turtle.dig() then
  95. print("Failed to dig block in front")
  96. return false
  97. end
  98. blocksDigged = blocksDigged + 1
  99. end
  100.  
  101. -- Then try to move
  102. if not turtle.forward() then
  103. print("Failed to move forward even after digging")
  104. return false
  105. end
  106. end
  107.  
  108. -- Update tracking variables
  109. movements = movements + 1
  110. totalCost = totalCost + MOVEMENT_COST
  111. return true
  112. end
  113.  
  114. -- Function to dig and move up
  115. local function digAndMoveUp(simulate)
  116. if not simulate then
  117. -- Always try to dig first
  118. if turtle.detectUp() then
  119. if not turtle.digUp() then
  120. print("Failed to dig block above")
  121. return false
  122. end
  123. blocksDigged = blocksDigged + 1
  124. end
  125.  
  126. -- Then try to move
  127. if not turtle.up() then
  128. print("Failed to move up even after digging")
  129. return false
  130. end
  131. end
  132.  
  133. -- Update tracking variables
  134. movements = movements + 1
  135. totalCost = totalCost + MOVEMENT_COST
  136. return true
  137. end
  138.  
  139. -- Function to dig and move down
  140. local function digAndMoveDown(simulate)
  141. if not simulate then
  142. -- Always try to dig first
  143. if turtle.detectDown() then
  144. if not turtle.digDown() then
  145. print("Failed to dig block below")
  146. return false
  147. end
  148. blocksDigged = blocksDigged + 1
  149. end
  150.  
  151. -- Then try to move
  152. if not turtle.down() then
  153. print("Failed to move down even after digging")
  154. return false
  155. end
  156. end
  157.  
  158. -- Update tracking variables
  159. movements = movements + 1
  160. totalCost = totalCost + MOVEMENT_COST
  161. return true
  162. end
  163.  
  164. -- Function to deposit items in chest
  165. local function depositItems(simulate)
  166. if simulate then
  167. return true
  168. end
  169.  
  170. print("Depositing items in chest...")
  171.  
  172. -- Turn around to face the chest (which is behind the starting position)
  173. rotateTo(DIRECTIONS.NORTH, simulate)
  174.  
  175. -- Move out of the room to the chest
  176. if not turtle.forward() then
  177. print("Failed to move to chest")
  178. -- Just continue, we'll try to deposit next time
  179. rotateTo(DIRECTIONS.SOUTH, simulate) -- Turn back to face into the room
  180. return false
  181. end
  182.  
  183. -- Deposit all items except fuel in slot 1
  184. for i = 2, 16 do
  185. if turtle.getItemCount(i) > 0 then
  186. turtle.select(i)
  187. turtle.drop()
  188. end
  189. end
  190. turtle.select(1) -- Return to slot 1
  191.  
  192. -- Return to the room
  193. rotateTo(DIRECTIONS.SOUTH, simulate)
  194. if not turtle.forward() then
  195. print("Failed to return to room!")
  196. return false
  197. end
  198.  
  199. return true
  200. end
  201.  
  202. -- Check if inventory is getting full
  203. local function isInventoryNearlyfull()
  204. local emptySlots = 0
  205. for i = 1, 16 do
  206. if turtle.getItemCount(i) == 0 then
  207. emptySlots = emptySlots + 1
  208. end
  209. end
  210. return (16 - emptySlots) >= 14 -- If only 2 or fewer slots are empty
  211. end
  212.  
  213. -- Function to determine the best pattern for a given room size
  214. local function getBestPattern(width, depth)
  215. -- Special cases for tiny rooms
  216. if width == 1 or depth == 1 then
  217. return "line"
  218. elseif width <= 2 and depth <= 2 then
  219. return "tiny"
  220. elseif width <= 3 and depth <= 3 then
  221. return "small_spiral"
  222. end
  223.  
  224. -- Check if width and depth are odd or even
  225. local isWidthOdd = width % 2 == 1
  226. local isDepthOdd = depth % 2 == 1
  227.  
  228. -- For larger rooms, always use serpentine patterns
  229. -- as they're more predictable and efficient
  230. if isWidthOdd and isDepthOdd then
  231. return "serpentine_odd_odd"
  232. elseif not isWidthOdd and not isDepthOdd then
  233. return "serpentine_even_even"
  234. else
  235. return "serpentine_mixed"
  236. end
  237. end
  238.  
  239. -- Generate a path that minimizes rotations but ends near the start
  240. function generateOptimizedPath(width, depth, reverse)
  241. local pattern = getBestPattern(width, depth)
  242. local path = {}
  243. reverse = reverse or false
  244.  
  245. print("Using pattern: " .. pattern .. (reverse and " (reversed)" or ""))
  246.  
  247. -- LINE pattern (1xN or Nx1 room)
  248. if pattern == "line" then
  249. if width == 1 then
  250. -- Single column
  251. if not reverse then
  252. -- Forward: top to bottom
  253. for z = 1, depth do
  254. table.insert(path, {x = 1, z = z, dir = DIRECTIONS.SOUTH})
  255. end
  256. else
  257. -- Reverse: bottom to top
  258. for z = depth, 1, -1 do
  259. table.insert(path, {x = 1, z = z, dir = DIRECTIONS.NORTH})
  260. end
  261. end
  262. else
  263. -- Single row
  264. if not reverse then
  265. -- Forward: left to right
  266. for x = 1, width do
  267. table.insert(path, {x = x, z = 1, dir = DIRECTIONS.EAST})
  268. end
  269. else
  270. -- Reverse: right to left
  271. for x = width, 1, -1 do
  272. table.insert(path, {x = x, z = 1, dir = DIRECTIONS.WEST})
  273. end
  274. end
  275. end
  276. return path
  277. end
  278.  
  279. -- TINY pattern (2x2 or smaller)
  280. if pattern == "tiny" then
  281. if not reverse then
  282. -- Forward: clockwise loop
  283. return {
  284. {x = 1, z = 1, dir = DIRECTIONS.EAST},
  285. {x = 2, z = 1, dir = DIRECTIONS.SOUTH},
  286. {x = 2, z = 2, dir = DIRECTIONS.WEST},
  287. {x = 1, z = 2, dir = DIRECTIONS.NORTH}
  288. }
  289. else
  290. -- Reverse: counter-clockwise loop
  291. return {
  292. {x = 1, z = 2, dir = DIRECTIONS.EAST},
  293. {x = 2, z = 2, dir = DIRECTIONS.NORTH},
  294. {x = 2, z = 1, dir = DIRECTIONS.WEST},
  295. {x = 1, z = 1, dir = DIRECTIONS.SOUTH}
  296. }
  297. end
  298. end
  299.  
  300. -- SMALL SPIRAL pattern (3x3 or smaller)
  301. if pattern == "small_spiral" then
  302. if not reverse then
  303. -- Build clockwise spiral path
  304. local spiral = {}
  305.  
  306. -- First row
  307. for x = 1, width do
  308. table.insert(spiral, {x = x, z = 1, dir = DIRECTIONS.EAST})
  309. end
  310.  
  311. -- Right edge down
  312. for z = 2, depth do
  313. table.insert(spiral, {x = width, z = z, dir = DIRECTIONS.SOUTH})
  314. end
  315.  
  316. -- Bottom row backwards
  317. for x = width-1, 1, -1 do
  318. table.insert(spiral, {x = x, z = depth, dir = DIRECTIONS.WEST})
  319. end
  320.  
  321. -- Left edge up (if room is at least 3 deep)
  322. if depth >= 3 then
  323. for z = depth-1, 2, -1 do
  324. table.insert(spiral, {x = 1, z = z, dir = DIRECTIONS.NORTH})
  325. end
  326. end
  327.  
  328. -- Fill in the center if needed (for 3x3 or larger)
  329. if width >= 3 and depth >= 3 then
  330. table.insert(spiral, {x = 2, z = 2, dir = DIRECTIONS.EAST})
  331. if width >= 4 then
  332. for x = 3, width-1 do
  333. table.insert(spiral, {x = x, z = 2, dir = DIRECTIONS.EAST})
  334. end
  335.  
  336. if depth >= 4 then
  337. -- Continue filling in larger rooms
  338. -- (Pattern continues but rarely needed for ComputerCraft mining)
  339. end
  340. end
  341. end
  342.  
  343. return spiral
  344. else
  345. -- Reverse spiral (counter-clockwise)
  346. local spiral = {}
  347.  
  348. -- First column down
  349. for z = 1, depth do
  350. table.insert(spiral, {x = 1, z = z, dir = DIRECTIONS.SOUTH})
  351. end
  352.  
  353. -- Bottom row right
  354. for x = 2, width do
  355. table.insert(spiral, {x = x, z = depth, dir = DIRECTIONS.EAST})
  356. end
  357.  
  358. -- Right edge up
  359. for z = depth-1, 1, -1 do
  360. table.insert(spiral, {x = width, z = z, dir = DIRECTIONS.NORTH})
  361. end
  362.  
  363. -- Top row backwards (if room is at least 3 wide)
  364. if width >= 3 then
  365. for x = width-1, 2, -1 do
  366. table.insert(spiral, {x = x, z = 1, dir = DIRECTIONS.WEST})
  367. end
  368. end
  369.  
  370. -- Fill in the center if needed
  371. if width >= 3 and depth >= 3 then
  372. table.insert(spiral, {x = 2, z = 2, dir = DIRECTIONS.SOUTH})
  373. if depth >= 4 then
  374. for z = 3, depth-1 do
  375. table.insert(spiral, {x = 2, z = z, dir = DIRECTIONS.SOUTH})
  376. end
  377.  
  378. if width >= 4 then
  379. -- Continue filling in larger rooms as needed
  380. end
  381. end
  382. end
  383.  
  384. return spiral
  385. end
  386. end
  387.  
  388. -- SERPENTINE patterns for all room types
  389. if pattern == "serpentine_odd_odd" or pattern == "serpentine_even_even" or pattern == "serpentine_mixed" then
  390. local serpentine = {}
  391.  
  392. if not reverse then
  393. -- Forward pattern
  394.  
  395. -- For odd×odd rooms, we need to handle the last column differently
  396. -- to ensure we end up near the starting position
  397. local normalColCount = width
  398. if pattern == "serpentine_odd_odd" then
  399. normalColCount = width - 1 -- We'll handle the last column separately
  400. end
  401.  
  402. -- Process the main part of the room using standard serpentine pattern
  403. for x = 1, normalColCount do
  404. if x % 2 == 1 then
  405. -- Odd columns go south
  406. for z = 1, depth do
  407. -- When at the end of an odd column, we need to decide if we turn east or go up
  408. if z == depth and x < normalColCount then
  409. -- Turn east at the end of the column (if not the last column)
  410. table.insert(serpentine, {x = x, z = z, dir = DIRECTIONS.EAST})
  411. else
  412. -- Otherwise, continue south
  413. table.insert(serpentine, {x = x, z = z, dir = DIRECTIONS.SOUTH})
  414. end
  415. end
  416. else
  417. -- Even columns go north
  418. for z = depth, 1, -1 do
  419. -- At the end of an even column, turn east if not the last column
  420. if z == 1 and x < normalColCount then
  421. table.insert(serpentine, {x = x, z = z, dir = DIRECTIONS.EAST})
  422. else
  423. table.insert(serpentine, {x = x, z = z, dir = DIRECTIONS.NORTH})
  424. end
  425. end
  426. end
  427. end
  428.  
  429. -- For odd×odd rooms, handle the last column to end near start
  430. if pattern == "serpentine_odd_odd" and width % 2 == 1 and normalColCount < width then
  431. local lastCol = width
  432. -- We're now at the top of the second-to-last column
  433. -- Turn east to enter the last column
  434. table.insert(serpentine, {x = normalColCount, z = 1, dir = DIRECTIONS.EAST})
  435.  
  436. -- Now we're at the top of the last column, and need to go down
  437. for z = 1, depth do
  438. -- Use SOUTH direction for all positions in this column
  439. table.insert(serpentine, {x = lastCol, z = z, dir = DIRECTIONS.SOUTH})
  440. end
  441. end
  442. else
  443. -- Reverse pattern
  444.  
  445. -- For odd×odd rooms in reverse, we start from the bottom of the last column
  446. local startingCol = 1
  447. if pattern == "serpentine_odd_odd" and width % 2 == 1 then
  448. startingCol = width -- Start at the last column
  449.  
  450. -- Process the last column from bottom to top
  451. for z = depth, 1, -1 do
  452. table.insert(serpentine, {x = startingCol, z = z, dir = DIRECTIONS.NORTH})
  453. end
  454.  
  455. -- Move west to second-to-last column
  456. table.insert(serpentine, {x = startingCol, z = 1, dir = DIRECTIONS.WEST})
  457.  
  458. -- Continue with the rest of the serpentine pattern
  459. startingCol = width - 1
  460. end
  461.  
  462. -- Process the main part of the room
  463. for x = startingCol, 1, -1 do
  464. if (width - x) % 2 == 0 then
  465. -- Process in the south direction
  466. for z = 1, depth do
  467. if z == depth and x > 1 then
  468. -- Turn west at the end of the column
  469. table.insert(serpentine, {x = x, z = z, dir = DIRECTIONS.WEST})
  470. else
  471. table.insert(serpentine, {x = x, z = z, dir = DIRECTIONS.SOUTH})
  472. end
  473. end
  474. else
  475. -- Process in the north direction
  476. for z = depth, 1, -1 do
  477. if z == 1 and x > 1 then
  478. -- Turn west at the end of the column
  479. table.insert(serpentine, {x = x, z = z, dir = DIRECTIONS.WEST})
  480. else
  481. table.insert(serpentine, {x = x, z = z, dir = DIRECTIONS.NORTH})
  482. end
  483. end
  484. end
  485. end
  486. end
  487.  
  488. return serpentine
  489. end
  490.  
  491. -- OPTIMIZED ZIGZAG pattern (even×even rooms)
  492. if pattern == "optimized_zigzag" then
  493. local zigzag = {}
  494.  
  495. if not reverse then
  496. -- Forward pattern: start at top-left, end at bottom-left
  497. -- This minimizes rotations while ensuring we end near the start
  498.  
  499. -- Process each row
  500. for z = 1, depth do
  501. if z % 2 == 1 then
  502. -- Odd rows go east
  503. for x = 1, width do
  504. if x == width and z < depth then
  505. -- Last position in row (except for last row)
  506. table.insert(zigzag, {x = x, z = z, dir = DIRECTIONS.SOUTH})
  507. else
  508. table.insert(zigzag, {x = x, z = z, dir = DIRECTIONS.EAST})
  509. end
  510. end
  511. else
  512. -- Even rows go west
  513. for x = width, 1, -1 do
  514. if x == 1 and z < depth then
  515. -- Last position in row (except for last row)
  516. table.insert(zigzag, {x = x, z = z, dir = DIRECTIONS.SOUTH})
  517. else
  518. table.insert(zigzag, {x = x, z = z, dir = DIRECTIONS.WEST})
  519. end
  520. end
  521. end
  522. end
  523. else
  524. -- Reverse pattern: start at bottom-left, end at top-left
  525.  
  526. for z = depth, 1, -1 do
  527. if z % 2 == 0 then
  528. -- Even rows (from bottom) go east
  529. for x = 1, width do
  530. if x == width and z > 1 then
  531. -- Last position in row (except for first/top row)
  532. table.insert(zigzag, {x = x, z = z, dir = DIRECTIONS.NORTH})
  533. else
  534. table.insert(zigzag, {x = x, z = z, dir = DIRECTIONS.EAST})
  535. end
  536. end
  537. else
  538. -- Odd rows (from bottom) go west
  539. for x = width, 1, -1 do
  540. if x == 1 and z > 1 then
  541. -- Last position in row (except for first/top row)
  542. table.insert(zigzag, {x = x, z = z, dir = DIRECTIONS.NORTH})
  543. else
  544. table.insert(zigzag, {x = x, z = z, dir = DIRECTIONS.WEST})
  545. end
  546. end
  547. end
  548. end
  549. end
  550.  
  551. return zigzag
  552. end
  553.  
  554. -- OPTIMIZED STRIPES pattern (for odd×even or even×odd rooms)
  555. if pattern == "optimized_stripes" then
  556. local stripes = {}
  557.  
  558. -- Choose horizontal or vertical stripes based on which minimizes rotations
  559. local horizontal = width >= depth
  560.  
  561. if horizontal then
  562. -- Horizontal stripes (minimize rotations by doing longer runs)
  563. if not reverse then
  564. -- Forward pattern
  565. for z = 1, depth do
  566. if z % 2 == 1 then
  567. -- Odd rows go east
  568. for x = 1, width do
  569. if x == width and z < depth then
  570. -- Turn at the end of row
  571. table.insert(stripes, {x = x, z = z, dir = DIRECTIONS.SOUTH})
  572. else
  573. table.insert(stripes, {x = x, z = z, dir = DIRECTIONS.EAST})
  574. end
  575. end
  576. else
  577. -- Even rows go west
  578. for x = width, 1, -1 do
  579. if x == 1 and z < depth then
  580. -- Turn at the end of row
  581. table.insert(stripes, {x = x, z = z, dir = DIRECTIONS.SOUTH})
  582. else
  583. table.insert(stripes, {x = x, z = z, dir = DIRECTIONS.WEST})
  584. end
  585. end
  586. end
  587. end
  588. else
  589. -- Reverse pattern
  590. for z = depth, 1, -1 do
  591. if (depth - z + 1) % 2 == 1 then
  592. -- Odd rows from bottom go east
  593. for x = 1, width do
  594. if x == width and z > 1 then
  595. -- Turn at the end of row
  596. table.insert(stripes, {x = x, z = z, dir = DIRECTIONS.NORTH})
  597. else
  598. table.insert(stripes, {x = x, z = z, dir = DIRECTIONS.EAST})
  599. end
  600. end
  601. else
  602. -- Even rows from bottom go west
  603. for x = width, 1, -1 do
  604. if x == 1 and z > 1 then
  605. -- Turn at the end of row
  606. table.insert(stripes, {x = x, z = z, dir = DIRECTIONS.NORTH})
  607. else
  608. table.insert(stripes, {x = x, z = z, dir = DIRECTIONS.WEST})
  609. end
  610. end
  611. end
  612. end
  613. end
  614. else
  615. -- Vertical stripes
  616. if not reverse then
  617. -- Forward pattern
  618. for x = 1, width do
  619. if x % 2 == 1 then
  620. -- Odd columns go south
  621. for z = 1, depth do
  622. if z == depth and x < width then
  623. -- Turn at the end of column
  624. table.insert(stripes, {x = x, z = z, dir = DIRECTIONS.EAST})
  625. else
  626. table.insert(stripes, {x = x, z = z, dir = DIRECTIONS.SOUTH})
  627. end
  628. end
  629. else
  630. -- Even columns go north
  631. for z = depth, 1, -1 do
  632. if z == 1 and x < width then
  633. -- Turn at the end of column
  634. table.insert(stripes, {x = x, z = z, dir = DIRECTIONS.EAST})
  635. else
  636. table.insert(stripes, {x = x, z = z, dir = DIRECTIONS.NORTH})
  637. end
  638. end
  639. end
  640. end
  641. else
  642. -- Reverse pattern
  643. for x = width, 1, -1 do
  644. if (width - x + 1) % 2 == 1 then
  645. -- Odd columns from right go south
  646. for z = 1, depth do
  647. if z == depth and x > 1 then
  648. -- Turn at the end of column
  649. table.insert(stripes, {x = x, z = z, dir = DIRECTIONS.WEST})
  650. else
  651. table.insert(stripes, {x = x, z = z, dir = DIRECTIONS.SOUTH})
  652. end
  653. end
  654. else
  655. -- Even columns from right go north
  656. for z = depth, 1, -1 do
  657. if z == 1 and x > 1 then
  658. -- Turn at the end of column
  659. table.insert(stripes, {x = x, z = z, dir = DIRECTIONS.WEST})
  660. else
  661. table.insert(stripes, {x = x, z = z, dir = DIRECTIONS.NORTH})
  662. end
  663. end
  664. end
  665. end
  666. end
  667. end
  668.  
  669. return stripes
  670. end
  671.  
  672. -- H_STRIPS_OPTIMIZED and V_STRIPS_OPTIMIZED patterns
  673. -- These are optimized versions of horizontal and vertical strips for larger rooms
  674. if pattern == "h_strips_optimized" or pattern == "v_strips_optimized" then
  675. local horizontal = (pattern == "h_strips_optimized")
  676. local strips = {}
  677.  
  678. if horizontal then
  679. -- Horizontal strips with special handling to end near start
  680. if not reverse then
  681. -- Calculate if we need to do special handling for the last row
  682. local normalRows = depth
  683. local endsNearStart = true
  684.  
  685. if depth % 2 == 0 then
  686. -- For even depths, we're already good - ends at bottom left
  687. endsNearStart = true
  688. else
  689. -- For odd depths, we need to modify the last row pattern
  690. -- to ensure we end near the start
  691. normalRows = depth - 1
  692. endsNearStart = false
  693. end
  694.  
  695. -- Process normal rows with standard zigzag
  696. for z = 1, normalRows do
  697. if z % 2 == 1 then
  698. -- Odd rows go east
  699. for x = 1, width do
  700. if x == width and z < normalRows then
  701. -- Turn at the end of row
  702. table.insert(strips, {x = x, z = z, dir = DIRECTIONS.SOUTH})
  703. else
  704. table.insert(strips, {x = x, z = z, dir = DIRECTIONS.EAST})
  705. end
  706. end
  707. else
  708. -- Even rows go west
  709. for x = width, 1, -1 do
  710. if x == 1 and z < normalRows then
  711. -- Turn at the end of row
  712. table.insert(strips, {x = x, z = z, dir = DIRECTIONS.SOUTH})
  713. else
  714. table.insert(strips, {x = x, z = z, dir = DIRECTIONS.WEST})
  715. end
  716. end
  717. end
  718. end
  719.  
  720. -- Handle the special last row for odd depths
  721. if not endsNearStart then
  722. -- Last row needs to end near start (left side)
  723. -- For odd depths, the last row starts at top right
  724. local lastZ = depth
  725.  
  726. -- Two options:
  727. -- 1. Zigzag from right to left (if width > 4)
  728. -- 2. Straight line from right to left (if width <= 4)
  729.  
  730. if width > 4 then
  731. -- Zigzag approach - minimizes rotation cost
  732. -- This creates a zigzag within the last row to end at the left
  733. -- Exact pattern will depend on width
  734.  
  735. -- This is a simplified version - a real implementation would
  736. -- optimize this path further
  737.  
  738. -- Process the last row in segments
  739. local segments = math.ceil(width / 3)
  740. for seg = 1, segments do
  741. local startX = width - ((seg-1) * 3)
  742. local endX = math.max(1, startX - 2)
  743.  
  744. -- Go left within this segment
  745. for x = startX, endX, -1 do
  746. if x == endX and endX > 1 then
  747. -- At the end of segment, turn south briefly
  748. table.insert(strips, {x = x, z = lastZ, dir = DIRECTIONS.SOUTH})
  749. -- Then back north
  750. table.insert(strips, {x = x, z = lastZ + 1, dir = DIRECTIONS.NORTH})
  751. -- Then continue west
  752. table.insert(strips, {x = x, z = lastZ, dir = DIRECTIONS.WEST})
  753. else
  754. table.insert(strips, {x = x, z = lastZ, dir = DIRECTIONS.WEST})
  755. end
  756. end
  757. end
  758. else
  759. -- For narrow rooms, just go straight from right to left
  760. for x = width, 1, -1 do
  761. table.insert(strips, {x = x, z = lastZ, dir = DIRECTIONS.WEST})
  762. end
  763. end
  764. end
  765. else
  766. -- Reverse pattern
  767. -- Similar logic but reversed direction
  768.  
  769. -- Calculate if we need to do special handling for the first row
  770. local normalRows = depth
  771. local startsNearEnd = true
  772.  
  773. if depth % 2 == 0 then
  774. -- For even depths, we start at bottom left
  775. startsNearEnd = true
  776. else
  777. -- For odd depths, we need a special first row
  778. normalRows = depth - 1
  779. startsNearEnd = false
  780. end
  781.  
  782. -- Handle the special first row for odd depths
  783. if not startsNearEnd then
  784. -- First row (from reverse perspective) needs to start near the end of normal pattern
  785. local firstZ = depth
  786.  
  787. -- Similar options as in forward pattern
  788. if width > 4 then
  789. -- Reverse of the zigzag approach
  790. local segments = math.ceil(width / 3)
  791. for seg = segments, 1, -1 do
  792. local startX = width - ((seg-1) * 3)
  793. local endX = math.max(1, startX - 2)
  794.  
  795. -- Go right within this segment (reversed from forward)
  796. for x = endX, startX do
  797. if x == endX and endX > 1 and seg > 1 then
  798. -- Reverse of the special turns
  799. table.insert(strips, {x = x, z = firstZ, dir = DIRECTIONS.EAST})
  800. -- Then down and up
  801. table.insert(strips, {x = x, z = firstZ + 1, dir = DIRECTIONS.SOUTH})
  802. table.insert(strips, {x = x, z = firstZ, dir = DIRECTIONS.NORTH})
  803. else
  804. table.insert(strips, {x = x, z = firstZ, dir = DIRECTIONS.EAST})
  805. end
  806. end
  807. end
  808. else
  809. -- For narrow rooms, just go straight from left to right
  810. for x = 1, width do
  811. table.insert(strips, {x = x, z = firstZ, dir = DIRECTIONS.EAST})
  812. end
  813. end
  814. end
  815.  
  816. -- Process normal rows with standard zigzag (reversed)
  817. for z = normalRows, 1, -1 do
  818. if z % 2 == 0 then
  819. -- Even rows go east (reversed from forward pattern)
  820. for x = 1, width do
  821. if x == width and z > 1 then
  822. -- Turn at the end of row
  823. table.insert(strips, {x = x, z = z, dir = DIRECTIONS.NORTH})
  824. else
  825. table.insert(strips, {x = x, z = z, dir = DIRECTIONS.EAST})
  826. end
  827. end
  828. else
  829. -- Odd rows go west (reversed from forward pattern)
  830. for x = width, 1, -1 do
  831. if x == 1 and z > 1 then
  832. -- Turn at the end of row
  833. table.insert(strips, {x = x, z = z, dir = DIRECTIONS.NORTH})
  834. else
  835. table.insert(strips, {x = x, z = z, dir = DIRECTIONS.WEST})
  836. end
  837. end
  838. end
  839. end
  840. end
  841. else
  842. -- Vertical strips with special handling to end near start
  843. -- Similar logic as horizontal strips but with x and z swapped
  844. if not reverse then
  845. -- Calculate if we need to do special handling for the last column
  846. local normalCols = width
  847. local endsNearStart = true
  848.  
  849. if width % 2 == 0 then
  850. -- For even widths, we're good - ends at bottom left
  851. endsNearStart = true
  852. else
  853. -- For odd widths, need to modify the last column
  854. normalCols = width - 1
  855. endsNearStart = false
  856. end
  857.  
  858. -- Process normal columns with standard zigzag
  859. for x = 1, normalCols do
  860. if x % 2 == 1 then
  861. -- Odd columns go south
  862. for z = 1, depth do
  863. if z == depth and x < normalCols then
  864. -- Turn at the end of column
  865. table.insert(strips, {x = x, z = z, dir = DIRECTIONS.EAST})
  866. else
  867. table.insert(strips, {x = x, z = z, dir = DIRECTIONS.SOUTH})
  868. end
  869. end
  870. else
  871. -- Even columns go north
  872. for z = depth, 1, -1 do
  873. if z == 1 and x < normalCols then
  874. -- Turn at the end of column
  875. table.insert(strips, {x = x, z = z, dir = DIRECTIONS.EAST})
  876. else
  877. table.insert(strips, {x = x, z = z, dir = DIRECTIONS.NORTH})
  878. end
  879. end
  880. end
  881. end
  882.  
  883. -- Handle the special last column for odd widths
  884. if not endsNearStart then
  885. -- Last column needs to end near start (top position)
  886. local lastX = width
  887.  
  888. -- For odd widths, the last column starts at bottom
  889. if depth > 4 then
  890. -- Zigzag approach for tall rooms
  891. local segments = math.ceil(depth / 3)
  892. for seg = 1, segments do
  893. local startZ = depth - ((seg-1) * 3)
  894. local endZ = math.max(1, startZ - 2)
  895.  
  896. -- Go up within this segment
  897. for z = startZ, endZ, -1 do
  898. if z == endZ and endZ > 1 then
  899. -- At the end of segment, turn east briefly
  900. table.insert(strips, {x = lastX, z = z, dir = DIRECTIONS.EAST})
  901. -- Then back west
  902. table.insert(strips, {x = lastX + 1, z = z, dir = DIRECTIONS.WEST})
  903. -- Then continue north
  904. table.insert(strips, {x = lastX, z = z, dir = DIRECTIONS.NORTH})
  905. else
  906. table.insert(strips, {x = lastX, z = z, dir = DIRECTIONS.NORTH})
  907. end
  908. end
  909. end
  910. else
  911. -- For short rooms, just go straight from bottom to top
  912. for z = depth, 1, -1 do
  913. table.insert(strips, {x = lastX, z = z, dir = DIRECTIONS.NORTH})
  914. end
  915. end
  916. end
  917. else
  918. -- Reverse pattern
  919. -- Similar logic but reversed direction
  920.  
  921. -- Calculate if we need to do special handling for the first column
  922. local normalCols = width
  923. local startsNearEnd = true
  924.  
  925. if width % 2 == 0 then
  926. -- For even widths, we start at top right
  927. startsNearEnd = true
  928. else
  929. -- For odd widths, we need a special first column
  930. normalCols = width - 1
  931. startsNearEnd = false
  932. end
  933.  
  934. -- Handle the special first column for odd widths
  935. if not startsNearEnd then
  936. -- First column (from reverse perspective) needs to start near the end
  937. local firstX = width
  938.  
  939. -- Similar options as in forward pattern
  940. if depth > 4 then
  941. -- Reverse of the zigzag approach
  942. local segments = math.ceil(depth / 3)
  943. for seg = segments, 1, -1 do
  944. local startZ = depth - ((seg-1) * 3)
  945. local endZ = math.max(1, startZ - 2)
  946.  
  947. -- Go down within this segment (reversed from forward)
  948. for z = endZ, startZ do
  949. if z == endZ and endZ > 1 and seg > 1 then
  950. -- Reverse of the special turns
  951. table.insert(strips, {x = firstX, z = z, dir = DIRECTIONS.SOUTH})
  952. -- Then east and west
  953. table.insert(strips, {x = firstX + 1, z = z, dir = DIRECTIONS.EAST})
  954. table.insert(strips, {x = firstX, z = z, dir = DIRECTIONS.WEST})
  955. else
  956. table.insert(strips, {x = firstX, z = z, dir = DIRECTIONS.SOUTH})
  957. end
  958. end
  959. end
  960. else
  961. -- For short rooms, just go straight from top to bottom
  962. for z = 1, depth do
  963. table.insert(strips, {x = firstX, z = z, dir = DIRECTIONS.SOUTH})
  964. end
  965. end
  966. end
  967.  
  968. -- Process normal columns with standard zigzag (reversed)
  969. for x = normalCols, 1, -1 do
  970. if x % 2 == 0 then
  971. -- Even columns go south (reversed from forward pattern)
  972. for z = 1, depth do
  973. if z == depth and x > 1 then
  974. -- Turn at the end of column
  975. table.insert(strips, {x = x, z = z, dir = DIRECTIONS.WEST})
  976. else
  977. table.insert(strips, {x = x, z = z, dir = DIRECTIONS.SOUTH})
  978. end
  979. end
  980. else
  981. -- Odd columns go north (reversed from forward pattern)
  982. for z = depth, 1, -1 do
  983. if z == 1 and x > 1 then
  984. -- Turn at the end of column
  985. table.insert(strips, {x = x, z = z, dir = DIRECTIONS.WEST})
  986. else
  987. table.insert(strips, {x = x, z = z, dir = DIRECTIONS.NORTH})
  988. end
  989. end
  990. end
  991. end
  992. end
  993. end
  994.  
  995. return strips
  996. end
  997.  
  998. -- Fallback to simple horizontal stripes pattern
  999. local fallback = {}
  1000.  
  1001. for z = 1, depth do
  1002. if z % 2 == 1 then
  1003. -- Odd rows go east
  1004. for x = 1, width do
  1005. if x == width and z < depth then
  1006. table.insert(fallback, {x = x, z = z, dir = DIRECTIONS.SOUTH})
  1007. else
  1008. table.insert(fallback, {x = x, z = z, dir = DIRECTIONS.EAST})
  1009. end
  1010. end
  1011. else
  1012. -- Even rows go west
  1013. for x = width, 1, -1 do
  1014. if x == 1 and z < depth then
  1015. table.insert(fallback, {x = x, z = z, dir = DIRECTIONS.SOUTH})
  1016. else
  1017. table.insert(fallback, {x = x, z = z, dir = DIRECTIONS.WEST})
  1018. end
  1019. end
  1020. end
  1021. end
  1022.  
  1023. return fallback
  1024. end
  1025.  
  1026. -- Function to excavate a room with optimal pathing
  1027. function excavateRoom(width, height, depth, simulate)
  1028. simulate = simulate or false -- Default to actual mining, not simulation
  1029.  
  1030. -- Validate dimensions
  1031. if width < 1 or width > 200 or height < 1 or height > 200 or depth < 1 or depth > 200 then
  1032. error("Dimensions must be between 1 and 200")
  1033. end
  1034.  
  1035. -- Reset counters for a new excavation
  1036. totalCost = 0
  1037. movements = 0
  1038. rotations = 0
  1039. blocksDigged = 0
  1040.  
  1041. -- Print starting information
  1042. print("Starting excavation of " .. width .. "x" .. height .. "x" .. depth .. " room")
  1043. print("Mode: " .. (simulate and "Simulation" or "Actual mining"))
  1044. print("Starting position: 1,1,1 (front-left corner of the room)")
  1045.  
  1046. -- Calculate total blocks to mine
  1047. local totalBlocks = width * height * depth
  1048. local minedBlocks = 0
  1049.  
  1050. -- Select appropriate pattern and indicate to user
  1051. local patternName = getBestPattern(width, depth)
  1052. print("Using optimal pattern: " .. patternName)
  1053.  
  1054. -- Execute the excavation layer by layer
  1055. for y = 1, height do
  1056. print("--- Mining layer " .. y .. " of " .. height .. " ---")
  1057.  
  1058. -- Determine if we should use forward or reverse pattern for this layer
  1059. local useReverse = (y % 2 == 0) -- Even layers use reverse pattern
  1060.  
  1061. -- Get the optimized path for this layer
  1062. local layerPath = generateOptimizedPath(width, depth, useReverse)
  1063.  
  1064. -- Current position starts at appropriate corner based on pattern
  1065. local currentPos
  1066. if not useReverse then
  1067. -- Forward pattern starts at front-left
  1068. currentPos = {x = 1, y = y, z = 1}
  1069. else
  1070. -- Reverse pattern starts at the end of the forward pattern
  1071. local lastPos = layerPath[1]
  1072. currentPos = {x = lastPos.x, y = y, z = lastPos.z}
  1073. end
  1074.  
  1075. -- First block is already visited
  1076. minedBlocks = minedBlocks + 1
  1077.  
  1078. -- For each position in the path (skipping the first as we're already there)
  1079. for i = 2, #layerPath do
  1080. local targetPos = layerPath[i]
  1081. local targetDir = targetPos.dir
  1082.  
  1083. -- First rotate if needed
  1084. if currentDir ~= targetDir then
  1085. rotateTo(targetDir, simulate)
  1086. end
  1087.  
  1088. -- Then move forward
  1089. if not digAndMoveForward(simulate) then
  1090. print("Failed to move to next position")
  1091. return false
  1092. end
  1093.  
  1094. -- Update current position
  1095. if targetDir == DIRECTIONS.NORTH then
  1096. currentPos.z = currentPos.z - 1
  1097. elseif targetDir == DIRECTIONS.EAST then
  1098. currentPos.x = currentPos.x + 1
  1099. elseif targetDir == DIRECTIONS.SOUTH then
  1100. currentPos.z = currentPos.z + 1
  1101. elseif targetDir == DIRECTIONS.WEST then
  1102. currentPos.x = currentPos.x - 1
  1103. end
  1104.  
  1105. -- Update progress
  1106. minedBlocks = minedBlocks + 1
  1107. if minedBlocks % 10 == 0 or minedBlocks == totalBlocks then
  1108. print("Mined " .. minedBlocks .. "/" .. totalBlocks .. " blocks")
  1109. end
  1110.  
  1111. -- Check if inventory is getting full
  1112. if not simulate and isInventoryNearlyfull() then
  1113. depositItems(simulate)
  1114. end
  1115. end
  1116.  
  1117. -- After completing a layer, move up if not at the top
  1118. if y < height then
  1119. if not digAndMoveUp(simulate) then
  1120. print("Failed to move to next layer")
  1121. return false
  1122. end
  1123.  
  1124. -- Reset current direction based on the next layer's pattern
  1125. local nextLayerReverse = ((y+1) % 2 == 0)
  1126. local nextLayerPath = generateOptimizedPath(width, depth, nextLayerReverse)
  1127. local nextStartDir = nextLayerPath[1].dir
  1128.  
  1129. -- Rotate to the starting direction for the next layer
  1130. rotateTo(nextStartDir, simulate)
  1131. end
  1132. end
  1133.  
  1134. -- Return to the starting position (1,1,1) and deposit items
  1135. print("Mining complete! Returning to starting position...")
  1136.  
  1137. -- First get back to the bottom layer
  1138. while currentPos.y > 1 do
  1139. if not digAndMoveDown(simulate) then
  1140. print("Failed to return to bottom layer")
  1141. return false
  1142. end
  1143. currentPos.y = currentPos.y - 1
  1144. end
  1145.  
  1146. -- Then navigate back to the starting position
  1147. -- Use a direct path to minimize rotations
  1148.  
  1149. -- Decide which direction to move first (x or z) based on which requires fewer rotations
  1150. local xDiff = currentPos.x - 1
  1151. local zDiff = currentPos.z - 1
  1152.  
  1153. -- Calculate rotation costs for different approaches
  1154. local costXFirst = 0
  1155. local costZFirst = 0
  1156.  
  1157. -- If moving in x direction first
  1158. if xDiff > 0 then
  1159. costXFirst = costXFirst + getRotationCost(currentDir, DIRECTIONS.WEST)
  1160. -- After moving in x, calculate cost to turn for z
  1161. costXFirst = costXFirst + getRotationCost(DIRECTIONS.WEST, (zDiff > 0) and DIRECTIONS.NORTH or DIRECTIONS.SOUTH)
  1162. elseif xDiff < 0 then
  1163. costXFirst = costXFirst + getRotationCost(currentDir, DIRECTIONS.EAST)
  1164. -- After moving in x, calculate cost to turn for z
  1165. costXFirst = costXFirst + getRotationCost(DIRECTIONS.EAST, (zDiff > 0) and DIRECTIONS.NORTH or DIRECTIONS.SOUTH)
  1166. else
  1167. -- No x movement needed
  1168. costXFirst = costXFirst + getRotationCost(currentDir, (zDiff > 0) and DIRECTIONS.NORTH or DIRECTIONS.SOUTH)
  1169. end
  1170.  
  1171. -- If moving in z direction first
  1172. if zDiff > 0 then
  1173. costZFirst = costZFirst + getRotationCost(currentDir, DIRECTIONS.NORTH)
  1174. -- After moving in z, calculate cost to turn for x
  1175. costZFirst = costZFirst + getRotationCost(DIRECTIONS.NORTH, (xDiff > 0) and DIRECTIONS.WEST or DIRECTIONS.EAST)
  1176. elseif zDiff < 0 then
  1177. costZFirst = costZFirst + getRotationCost(currentDir, DIRECTIONS.SOUTH)
  1178. -- After moving in z, calculate cost to turn for x
  1179. costZFirst = costZFirst + getRotationCost(DIRECTIONS.SOUTH, (xDiff > 0) and DIRECTIONS.WEST or DIRECTIONS.EAST)
  1180. else
  1181. -- No z movement needed
  1182. costZFirst = costZFirst + getRotationCost(currentDir, (xDiff > 0) and DIRECTIONS.WEST or DIRECTIONS.EAST)
  1183. end
  1184.  
  1185. -- Choose the path with lower rotation cost
  1186. if costXFirst <= costZFirst then
  1187. -- Move in x direction first
  1188. if xDiff > 0 then
  1189. rotateTo(DIRECTIONS.WEST, simulate)
  1190. for i = 1, xDiff do
  1191. if not digAndMoveForward(simulate) then
  1192. print("Failed to return to starting x position")
  1193. return false
  1194. end
  1195. end
  1196. elseif xDiff < 0 then
  1197. rotateTo(DIRECTIONS.EAST, simulate)
  1198. for i = 1, -xDiff do
  1199. if not digAndMoveForward(simulate) then
  1200. print("Failed to return to starting x position")
  1201. return false
  1202. end
  1203. end
  1204. end
  1205.  
  1206. -- Then move in z direction
  1207. if zDiff > 0 then
  1208. rotateTo(DIRECTIONS.NORTH, simulate)
  1209. for i = 1, zDiff do
  1210. if not digAndMoveForward(simulate) then
  1211. print("Failed to return to starting z position")
  1212. return false
  1213. end
  1214. end
  1215. elseif zDiff < 0 then
  1216. rotateTo(DIRECTIONS.SOUTH, simulate)
  1217. for i = 1, -zDiff do
  1218. if not digAndMoveForward(simulate) then
  1219. print("Failed to return to starting z position")
  1220. return false
  1221. end
  1222. end
  1223. end
  1224. else
  1225. -- Move in z direction first
  1226. if zDiff > 0 then
  1227. rotateTo(DIRECTIONS.NORTH, simulate)
  1228. for i = 1, zDiff do
  1229. if not digAndMoveForward(simulate) then
  1230. print("Failed to return to starting z position")
  1231. return false
  1232. end
  1233. end
  1234. elseif zDiff < 0 then
  1235. rotateTo(DIRECTIONS.SOUTH, simulate)
  1236. for i = 1, -zDiff do
  1237. if not digAndMoveForward(simulate) then
  1238. print("Failed to return to starting z position")
  1239. return false
  1240. end
  1241. end
  1242. end
  1243.  
  1244. -- Then move in x direction
  1245. if xDiff > 0 then
  1246. rotateTo(DIRECTIONS.WEST, simulate)
  1247. for i = 1, xDiff do
  1248. if not digAndMoveForward(simulate) then
  1249. print("Failed to return to starting x position")
  1250. return false
  1251. end
  1252. end
  1253. elseif xDiff < 0 then
  1254. rotateTo(DIRECTIONS.EAST, simulate)
  1255. for i = 1, -xDiff do
  1256. if not digAndMoveForward(simulate) then
  1257. print("Failed to return to starting x position")
  1258. return false
  1259. end
  1260. end
  1261. end
  1262. end
  1263.  
  1264. -- Deposit final items
  1265. depositItems(simulate)
  1266.  
  1267. -- Print stats
  1268. print("\n--- Excavation Summary ---")
  1269. print("Room dimensions: " .. width .. "x" .. height .. "x" .. depth)
  1270. print("Total blocks mined: " .. minedBlocks .. "/" .. totalBlocks)
  1271. print("Blocks dug: " .. blocksDigged)
  1272. print("Movements: " .. movements)
  1273. print("Rotations: " .. rotations)
  1274. print("Total cost (with rotation = " .. ROTATION_COST .. "x movement): " .. totalCost)
  1275. print("Average cost per block: " .. string.format("%.2f", totalCost / totalBlocks))
  1276.  
  1277. return true
  1278. end
  1279.  
  1280. -- Calculate rotation cost between two directions
  1281. function getRotationCost(fromDir, toDir)
  1282. local rot = getRotation(fromDir, toDir)
  1283. return math.abs(rot) * ROTATION_COST
  1284. end
  1285.  
  1286. -- Function to check fuel level and refuel if necessary
  1287. function ensureFuel(requiredFuel)
  1288. local currentFuel = turtle.getFuelLevel()
  1289.  
  1290. if currentFuel == "unlimited" then
  1291. print("Fuel level: Unlimited")
  1292. return true
  1293. end
  1294.  
  1295. print("Current fuel level: " .. currentFuel)
  1296.  
  1297. if requiredFuel and currentFuel < requiredFuel then
  1298. print("Need more fuel! Attempting to refuel...")
  1299.  
  1300. -- Try to refuel from inventory
  1301. for slot = 1, 16 do
  1302. turtle.select(slot)
  1303. if turtle.refuel(0) then -- Check if item is valid fuel
  1304. local fuelNeeded = requiredFuel - currentFuel
  1305. if turtle.refuel(fuelNeeded) then
  1306. local newLevel = turtle.getFuelLevel()
  1307. print("Refueled to level: " .. newLevel)
  1308. if newLevel >= requiredFuel then
  1309. return true
  1310. end
  1311. end
  1312. end
  1313. end
  1314.  
  1315. print("Warning: Unable to reach required fuel level of " .. requiredFuel)
  1316. return false
  1317. end
  1318.  
  1319. return true
  1320. end
  1321.  
  1322. -- Calculate approximate fuel needed, accounting for rotation costs
  1323. function calculateFuelNeeded(width, height, depth)
  1324. -- Estimate movements (one per block)
  1325. local movements = width * height * depth
  1326.  
  1327. -- Estimate rotations based on room dimensions and pattern
  1328. local pattern = getBestPattern(width, depth)
  1329. local rotationsPerLayer
  1330.  
  1331. -- Estimate rotations per layer based on pattern
  1332. if pattern == "line" then
  1333. rotationsPerLayer = 0
  1334. elseif pattern == "tiny" then
  1335. rotationsPerLayer = 4
  1336. elseif pattern == "small_spiral" then
  1337. rotationsPerLayer = 4
  1338. elseif pattern == "optimized_spiral" then
  1339. rotationsPerLayer = 4
  1340. elseif pattern == "optimized_zigzag" then
  1341. rotationsPerLayer = math.min(depth - 1, 1) * 2
  1342. elseif pattern == "optimized_stripes" then
  1343. if width >= depth then
  1344. -- Horizontal stripes
  1345. rotationsPerLayer = math.min(depth - 1, 1) * 2
  1346. else
  1347. -- Vertical stripes
  1348. rotationsPerLayer = math.min(width - 1, 1) * 2
  1349. end
  1350. elseif pattern == "h_strips_optimized" then
  1351. rotationsPerLayer = depth - 1
  1352. elseif pattern == "v_strips_optimized" then
  1353. rotationsPerLayer = width - 1
  1354. else
  1355. -- Fallback estimate
  1356. rotationsPerLayer = math.max(width, depth)
  1357. end
  1358.  
  1359. -- Total rotations including layer transitions
  1360. local totalRotations = rotationsPerLayer * height + (height - 1) * 2
  1361.  
  1362. -- Add fuel for inventory trips (deposit items when full)
  1363. local inventoryTrips = math.ceil((width * height * depth) / 14) * 4 -- 4 moves per trip
  1364.  
  1365. -- Calculate total cost
  1366. local totalCost = (movements * MOVEMENT_COST) + (totalRotations * ROTATION_COST) + inventoryTrips
  1367.  
  1368. -- Add 20% buffer
  1369. return totalCost * 1.2
  1370. end
  1371.  
  1372. -- Main function to run the program
  1373. function main()
  1374. print("ComputerCraft Hybrid Optimal Mining Algorithm")
  1375. print("--------------------------------------------")
  1376. print("This program uses advanced pathing to mine rooms efficiently.")
  1377. print("It minimizes rotations and ensures optimal layer transitions.")
  1378. print("")
  1379.  
  1380. -- Get dimensions from user input
  1381. print("Enter the dimensions of the room to excavate:")
  1382.  
  1383. io.write("Width (X): ")
  1384. local width = tonumber(io.read()) or 3
  1385.  
  1386. io.write("Height (Y): ")
  1387. local height = tonumber(io.read()) or 3
  1388.  
  1389. io.write("Depth (Z): ")
  1390. local depth = tonumber(io.read()) or 3
  1391.  
  1392. io.write("Simulate only? (y/n): ")
  1393. local simulateStr = io.read():lower()
  1394. local simulate = (simulateStr == "y" or simulateStr == "yes")
  1395.  
  1396. -- Ensure dimensions are valid
  1397. if width < 1 or width > 200 or height < 1 or height > 200 or depth < 1 or depth > 200 then
  1398. print("Error: Dimensions must be between 1 and 200")
  1399. return
  1400. end
  1401.  
  1402. -- Calculate required fuel with rotation costs
  1403. local requiredFuel = calculateFuelNeeded(width, height, depth)
  1404. print("Estimated fuel required: " .. math.ceil(requiredFuel))
  1405.  
  1406. -- Check fuel if not simulating
  1407. if not simulate then
  1408. if not ensureFuel(requiredFuel) then
  1409. print("Warning: Proceeding with insufficient fuel. The turtle may stop before completing the excavation.")
  1410. end
  1411. end
  1412.  
  1413. -- Execute the excavation
  1414. local success = excavateRoom(width, height, depth, simulate)
  1415.  
  1416. if success then
  1417. print("Excavation completed successfully!")
  1418. else
  1419. print("Excavation failed or was interrupted.")
  1420. end
  1421. end
  1422.  
  1423. -- Run the program
  1424. main()
Add Comment
Please, Sign In to add comment