Advertisement
TeoremaPi

Tremaux (resolver laberintos)

Apr 10th, 2020
697
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.27 KB | None | 0 0
  1. -- programa para resolver un laberinto por el algoritmo de tremaux
  2. -- hay que cargar lana amarilla en la primera mitad del inventario
  3. -- y roja en la segunda mitad
  4.  
  5. -- marca de la salida
  6. success, dataExit = turtle.inspectDown()
  7. exitName = dataExit.name
  8. exitMeta = dataExit.metadata
  9.  
  10. -- marca de camino recorrido 1 vez (lana amarilla)
  11. oneName = "minecraft:wool"
  12. oneMeta = 4
  13.  
  14. -- marca de camino recorrido 2 veces (lana roja)
  15. twoName = "minecraft:wool"
  16. twoMeta = 14
  17.  
  18. -- funcion para colocar un bloque del siguiente slot con recursos
  19. -- si no quedan recursos devuelve false, en caso contrario true
  20. function placeBlock(n)
  21.     -- si n = 1 coloca un bloque de la pimera mitad del inventario (una marca)
  22.     -- si n = 2 coloca un bloque de la segunda mitad del inventario (dos marcas)
  23.  
  24.     if n == 1 then
  25.         turtle.select(1)
  26.         maxSlot = 8
  27.     else
  28.         turtle.select(9)
  29.         maxSlot = 16
  30.     end
  31.  
  32.     while turtle.getItemCount() == 0 do
  33.         turtle.select(turtle.getSelectedSlot() + 1)
  34.        
  35.         if turtle.getSelectedSlot() == maxSlot and turtle.getItemCount() == 0 then
  36.             print("nasti")
  37.             return false
  38.         end
  39.     end
  40.     turtle.place()
  41.     turtle.select(1)
  42.     return true
  43. end
  44.  
  45.  
  46. -- funcion para detectar en que direcciones hay caminos
  47. -- devuelve:
  48. -- paths: un vector de cuatro componentes con la informacion de las cuatro direcciones
  49. --  0: si no hay nada, 1: una marca, 2: dos marcas, 3: otro bloque
  50. -- nPaths: un vector de cuatro componentes con el numero de caminos concurrentes de cada tipo
  51. --  1a: una marca, 2: dos marcas, 3: otro bloque (pared), 4: nada
  52. -- IMPORTANTE: la tortuga termina mirando hacia la izquierda
  53. function isPath()
  54.     -- pahts = {delante, derecha, detras, izquierda}
  55.     paths  = {0,0,0,0}
  56.     nPaths = {0,0,0,0}
  57.  
  58.     -- para cada uno de los lados
  59.     for k = 1, 4 do
  60.         -- detectamos si hay un bloque delante
  61.         if turtle.detect() then
  62.             -- si lo hay, lo inspeccionamos
  63.             success, dataPath = turtle.inspect()
  64.             dataName = dataPath.name
  65.             dataMeta = dataPath.metadata
  66.  
  67.             -- apuntamos si es una marca o una pared
  68.             if dataName == oneName and dataMeta == oneMeta then
  69.                 paths[k] = 1
  70.                 nPaths[1] = nPaths[1] + 1
  71.             elseif dataName == twoName and dataMeta == twoMeta then
  72.                 paths[k] = 2
  73.                 nPaths[2] = nPaths[2] + 1
  74.             else
  75.                 paths[k] = 3
  76.                 nPaths[3] = nPaths[3] + 1
  77.             end
  78.         else
  79.             -- si no hay bloque lo apuntamos que hay un bloque vacio
  80.             nPaths[4] = nPaths[4] + 1
  81.         end
  82.  
  83.         -- en la ultima direccion no hace falta girar (acabamos mirando hacia la izquierda)
  84.         if k < 4 then
  85.             turtle.turnRight()
  86.         end
  87.     end
  88.  
  89.     return paths, nPaths
  90. end
  91.  
  92.  
  93. -- funcion para avanzar y poner una marca en el suelo
  94. -- devuelve true si hemos terminado y false en caso contrario
  95. function move(mark)
  96.     -- mark = 0: solo avanza, 1: pone una marca, 2: pone dos marcas
  97.  
  98.     -- si encontramos un bloque lo quitamos
  99.     if turtle.detect() then
  100.         turtle.dig()
  101.     end
  102.  
  103.     -- avanzamos una casilla
  104.     turtle.forward()
  105.  
  106.     -- inspeccionamos el bloque bajo la tortuga para ver si hemos salido
  107.     success, dataDown = turtle.inspectDown()
  108.     finish = dataDown.name ~= exitName or dataDown.metadata ~= exitMeta
  109.  
  110.     -- si no hemos salido
  111.     if finish then
  112.         -- avanzamos otra casilla
  113.         turtle.forward()
  114.  
  115.         -- si hay que colocar una marca
  116.         if mark ~= 0 then
  117.             -- damos la vuelta
  118.             turtle.turnRight()
  119.             turtle.turnRight()
  120.  
  121.             -- colocamos un nuevo bloque
  122.             finish = placeBlock(mark)
  123.             print("place: ",finish)
  124.  
  125.  
  126.             -- volvemos a dar la vuelta para mirar hacia delante
  127.             turtle.turnRight()
  128.             turtle.turnRight()
  129.  
  130.         end
  131.     end
  132.  
  133.     print("end: ",finish)
  134.     return finish
  135.  
  136. end
  137.  
  138.  
  139. -- bucle principal
  140. turtle.forward()
  141. success, dataDown = turtle.inspectDown()
  142. finish = dataDown.name ~= exitName or dataDown.metadata ~= exitMeta
  143.  
  144. -- guardo en una variable cuantas veces he recorrido el camino actual
  145. nTimes = 1
  146.  
  147. while finish do
  148.     -- miramos que caminos hay alrededor
  149.     paths, nPaths = isPath()
  150.  
  151.     -- guardamos que hay en el camino que vamos a tomar
  152.     --  0: si no hay nada, 1: una marca, 2: dos marcas, 3: otro bloque (pared)
  153.     nextBlock = 0
  154.  
  155.     -- si hay no hay cruce (numero de paredes = 2)
  156.     if nPaths[3] == 2 then
  157.         -- NOTA: terminamos la busqueda de caminos mirando a la izquierda
  158.         if paths[1] ~= 3 then
  159.             -- si no hay pared delante
  160.             turtle.turnRight()
  161.  
  162.             nextBlock = paths[1]
  163.        
  164.         elseif paths[2] ~= 3 then
  165.             -- si no hay pared a la derecha
  166.             turtle.turnRight()
  167.             turtle.turnRight()
  168.        
  169.             nextBlock = paths[2]
  170.  
  171.         elseif paths[4] ~= 3 then
  172.             -- si no hay pared a la izquierda
  173.             nextBlock = paths[4]
  174.         end
  175.  
  176.         finish = move(0)
  177.  
  178.     elseif nPaths[3] == 3 then
  179.         -- si llegamos a un callejรณn sin salida (numero de paredes = 3)
  180.         -- volvemos hacia atrรกs
  181.         turtle.turnLeft()
  182.  
  183.         -- guardamos que estamos recorriendo el camino por segunda vez
  184.         nTimes = 2
  185.  
  186.         -- nos movemos
  187.         finish = move(0)
  188.  
  189.     else
  190.         -- en caso contrario estamos en un cruce (numero de paredes < 2)
  191.         -- primero cerramos el camino por el que hemos venido con la marca correspondiente
  192.         turtle.turnLeft()
  193.         if not placeBlock(nTimes) then
  194.             return
  195.         end
  196.  
  197.  
  198.         -- guardamos el camino por el que hemos venido con la marca que hemos puesto
  199.         paths[3] = nTimes
  200.  
  201.         -- nos quedamos mirando hacia atras
  202.         -- buscamos si hay algun camino que no hayamos recorrido previamente
  203.         -- si no hay, buscamos uno que solo hayamos recorrido solo una vez
  204.         -- lo haremos en el orden que nos permita movernos haciendo menos giros
  205.         -- modificamos la variable que almacena las veces que hemos recorrido un camino en consecuencia
  206.         if paths[2] == 0 then
  207.             -- si vamos por la derecha
  208.             turtle.turnLeft()
  209.             nTimes = 1
  210.         elseif paths[4] == 0 then
  211.             -- si vamos por la izquierda
  212.             turtle.turnRight()
  213.             nTimes = 1
  214.         elseif paths[1] == 0 then
  215.             -- si vamos hacia delante
  216.             turtle.turnRight()
  217.             turtle.turnRight()
  218.             nTimes = 1
  219.         elseif paths[3] == 1 then
  220.             -- si volvemos hacia atras
  221.             nTimes = 2
  222.         elseif paths[2] == 1 then
  223.             -- si volvemos a ir por la derecha
  224.             turtle.turnLeft()
  225.             nTimes = 2
  226.         elseif paths[4] == 1 then
  227.             -- si volvemos a ir por la izquierda
  228.             turtle.turnRight()
  229.             nTimes = 2
  230.         elseif paths[1] == 1 then
  231.             -- si volvemos a ir hacia delante
  232.             turtle.turnRight()
  233.             turtle.turnRight()
  234.             nTimes = 2
  235.         end
  236.  
  237.         -- avanzamos y colocamos la marca correspondiente
  238.         finish = move(nTimes)    
  239.  
  240.     end
  241. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement