This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
IceCrasher's profile picture

[Lua][Error] Mine:30: Attempt To Index ?(A Nil Value)

Started by IceCrasher, 07 October 2013 - 03:41 PM
IceCrasher #1
Posted 07 October 2013 - 05:41 PM
Hi guys

I wrote a mining program, which should survive world reloads. Basically i write every step the turtle makes in a file. But if i run the program i keep getting the error message "mine:30: attempt to index ?(a nil value)". I tried to debug it for like 2 hours now :/
Just for your information, the turtle stops after it went sideways 5 instead of 4 meters and stops after a turning.

I really hope you help me, because i don't now further.

Here the pastebin link: http://pastebin.com/hil3nfyt

Here the Code:
Spoiler

--files:
--stripDist,  turning,
--turnDirect, goDown, goHome, nHeightHome,
--nWidthHome, nLenghtHome,
--mainControl, widthControl, downControl

local length = 4 -- mineLength(amount of turns)
local width = 4 -- mineWidht(amount stripDist)
local depth = 6 -- mineDepth(must go through 3)
local startDirect = l -- start to (r or l)
local trashSlot = 16 -- Ender for Mined Blocks
local fuelSlot = 15 -- Ender for Fuel
local lastTrashSlot = 14 -- Slot before first Ender
--------------------------------------------- files
function write(a, B)/>
  local file = fs.open(a, "w")
  file.writeLine(B)/>
  file.close()
 
--  local file = fs.open("debug", "w")
--  file.writeLine(a)
--  file.close()
end
function read(a)
  local file = fs.open(a, "r")
  local b = file.readLine()
  return b
end
-------------------------------------------- basics
function trash(a)
  if a or turtle.getItemCount(lastTrashSlot - 2) > 0 then
    turtle.select(trashSlot)
    while not turtle.placeUp() do
	  turtle.digUp()
	  turtle.attackUp()
    end
    for i = 1, lastTrashSlot do
	  turtle.select(i)
	  if not turtle.dropUp() then
	    os.sleep(1)
	  end
    end
    turtle.select(trashSlot)
    turtle.digUp()
  end
end 
function refuel(a)
  while turtle.getFuelLevel() < a do
    trash(true)
    turtle.select(fuelSlot)
    while not turtle.placeUp() do
	  turtle.digUp()
	  turtle.attackUp()
	  turtle.drop()
    end
    turtle.suckUp()
    turtle.refuel()
    turtle.digUp()
  end
end   
---------------------------------------- easy files
function chegCreate(a,B)/>
  if not fs.exists(a) then
    write(a, B)/>
  end
end
function rTurn()
  return read("turning") + 0
end
function addTurn()
  write("turning", read("turning") + 1)
end
function subTurn()
  write("turning", read("turning") - 1)
end
function rDown()
  return read("goDown") + 0
end
function addDown()
  write("goDown", read("goDown") + 1)
end
function subDown()
  write("goDown", read("goDown") - 1)
end
function rHome()
  return read("goHome") + 0
end
function addHome()
  write("goHome", read("goHome") + 1)
end
function subHome()
  write("goHome", read("goHome") - 1)
end
--------------------------------------- Mine / Move
function strip()
  refuel(read("stripDist") + 100)
  while read("stripDist") + 0 > 0 do
    turtle.dig()
--    print("strip after dig()")------------------------------------
    write("stripDist", read("stripDist") - 1)
    if not turtle.forward() then
	  write("stripDist", read("stripDist") + 1)
	  turtle.dig()
	  turtle.attack()
    else
	  turtle.digUp()
	  turtle.digDown()
    end
    trash(false)
  end
  write("stripDist", width - 1)
end
function turn()
  trash(false)
  while rTurn() ~= 6 do		
	 
    if rTurn() == 1 then
	  if read("turnDirect") == "r" then
	    addTurn()
	    turtle.turnRight()
	  else
	    addTurn()
	    turtle.turnLeft()
	  end
    end
   
    if rTurn() == 2 then
	  turtle.dig()
	  addTurn()
	  if not turtle.forward() then
	    subTurn()
	    turtle.dig()
	    turtle.attack()
	  end
    end
   
    if rTurn() == 3 then
	  addTurn()
	  turtle.digUp()
    end
   
    if rTurn() == 4 then
	  addTurn()
	  turtle.digDown()
    end
		  
    if rTurn() == 5 then
	  addTurn()
	  if read("turnDirect") == "r" then
	    write("turnDirect", "l")
	    turtle.turnRight()
	  else
	    write("turnDirect", "r")
	    turtle.turnLeft()
	  end
    end
  end
  write("turning", 1)
end
function down()
  trash(false)
  while rDown() ~= 6 do
   
    if rDown() == 1 then
	  turtle.digDown()
	  addDown()
	  if not turtle.down() then
	    subDown()
	    turtle.digDown()
	    turtle.attackDown()
	  end
    end
   
    if rDown() == 2 then
	  turtle.digDown()
	  addDown()
	  if not turtle.down() then
	    subDown()
	    turtle.digDown()
	    turtle.attackDown()
	  end
    end
   
    if rDown() == 3 then
	  turtle.digDown()
	  addDown()
	  if not turtle.down() then
	    subDown()
	    turtle.digDown()
	    turtle.attackDown()
	  end
	  turtle.digDown()
    end
   
    if rDown() == 4 then
	  addDown()
	  turtle.turnRight()
    end
   
    if rDown() == 5 then
	  addDown()
	  turtle.turnRigth()
    end
  end
  write("goDown", 1)
end			 
function home()
 
  if math.fmod(width, 2) == 1 then
    local directHome = l
  else
    local directHome = r
  end
 
  if math.fmod((depth / 3), 2) == 1 then
    local whereHome = ending
  else
    local whereHome = starting
  end
 
  if whereHome == starting then
   
    while rHome() ~= 12 do
	 
	  if directHome == r then
	   
	    if rHome() == 1 then
		  addHome()
		  addHome()
		  addHome()		 
	    end
	   
	  else
	    if rHome() == 1 then
		  addHome()
		  turtle.turnLeft()
	    end
	   
	    if rHome() == 2 then
		  addHome()
		  turtle.turnLeft()
	    end
	   
	    if rHome() == 3 then
		  refuel(read("nWidthHome") + 100)
		  for i = 1, read("nWidthHome") + 0 do
		    trash(false)
		    write("nWidthHome", read("nWidthHome") - 1)
		    if not turtle.forward() then
			  write("nWidthHome", read("nWidthHome") + 1)
			  turtle.dig()
			  turtle.attack()
		    end
		  end
		  addHome()
	    end
	  end 
	   
	  if rHome() == 4 then
	    refuel(read("nHeightHome") + 100)
	    for i = 1, read("nHeightHome") + 0 do
		  trash(false)
		  write("nHeightHome", read("nHeightHome") - 1)
		  if not turtle.up()then
		    write("nHeightHome", read("nHeightHome") + 1)
		  end
		  turtle.digUp()
		  turtle.attackUp()
	    end
	    addHome()
	  end	   
    end
  else
    while rHome() ~= 8 do
	
	  if directHome == r then
	   
	    if rHome() == 1 then
		  addHome()
		  addHome()
		  addHome()
	    end
	   
	  else
	 
	    if rHome() == 5 then
		  addHome()
		  turtle.turnRight()
	    end
	   
	    if rHome() == 6 then
		  addHome()
		  turtle.turnRight()
	    end
	   
	    if rHome() == 7 then
		  refuel(read("nWidthHome") + 100)
		  for i = 1, read("nWidthHome") + 0 do
		    trash(false)
		    write("nWidthHome", read("nWidthHome") - 1)
		    if not turtle.forward() then
			  write("nWidthHome", read("nWidthHome") + 1)
			  turtle.dig()
			  turtle.attack()
		    end
		  end
		  addHome()
	    end
	  end
	 
	  if rHome() == 8 then
	    if startDirect == r then
		  addHome()
		  turtle.turnRight()
	    else
		  addHome()
		  turtle.turnLeft()
	    end
	  end
	 
	  if rHome() == 9 then
	    refuel(read("nLenghtHome") + 100)
	    for i = 1, read("nLengthHome") + 0 do
		  trash(false)
		  write("nLengthHome", read("nLengthHome") - 1)
		  if not turtle.forward() then
		    write("nLengthHome", read("nLengtHome") + 1)
		    turtle.dig()
		    turtle.attack()			
		  end
	    end
	  addHome()
	  end
	 
	  if rHome() == 10 then
	    if startDirect == r then
		  addHome()
		  turtle.turnLeft()
	    else
		  addHome()
		  turtle.turnRight()
	    end
	  end
	 
	  if rHome() == 11 then
	    refuel(read("nHightHome") + 100)
	    for i = 1, read("nHightHome") + 0 do
		  trash(false)
		  write("nHightHome", read("nHightHome") - 1)
		  if not turtle.up() then
		    write("nHightHome", read("nHightHome") + 1)
		    turtle.digUp()
		    turtle.attack()
		  end
	    end
	    addHome()
	  end
    end
  end
  write("goHome", 1)
end										
			 
------------------------------------------ Controls	 
function widthController()
  while read("widthControl") ~= width * 2 - 1
  do
    if math.fmod(read("widthControl") + 0, 2) == 0 then   
	  strip()
	  write("widthControl", read("widthControl") + 1)
    else
	  turn()
	  write("widthControl", read("widthControl") + 1)
    end   
  end
  write("widthControl", 0)
end
function downController()
  while read("downControl") ~= depth * 2 - 1 do
    if math.fmod(read("downControl") + 0, 2) == 0 then
	  widthController()
	  write("downControl", read("downControl") + 1)
    else
	  down()
	  write("downControl", read("downControl") + 1)
    end
  end
end
 
function mainController()
  if read("mainControl") + 0 == 0 then
    downController()
    write("mainControl", 1)
  end
 
  if read("mainControl") + 0 == 1 then
    home()
    write("mainControl", 2)
  end
 
  if read("mainControl") + 0 == 2 then
    print("Now I stop because I'm lazy too :P/>")
  end 
end
function createFiles()
  chegCreate("stripDist", width - 1)
  chegCreate("turning", 1)
  chegCreate("turnDirect", startdirect)
  chegCreate("goDown", 1)
  chegCreate("goHome", 1)
  chegCreate("nHeightHome", depth - 1)
  chegCreate("nWidthHome", width - 1)
  chegCreate("nLengthHome", length - 1)
  chegCreate("mainControl", 0)
  chegCreate("widthControl", 0)
  chegCreate("downControl", 0) 
end
------------------------------- putting it together   
print("I'm mining because you're to lazy :P/>")	 
if turtle.getItemCount(fuelSlot) == 0 then
  turtle.digUp()
end
if turtle.getItemCount(trashSlot) == 0 then
  turtle.digUp()
end
createFiles()
mainController()
DerKoch #2
Posted 07 October 2013 - 06:21 PM
You forgot the file.close() in your read()-function, I think that could be the reason.
The first time you use the read() it opens the file-handle but does not release it, thus the second time you call the function the handle can't be initialized because it wasn't released yet.
Anavrins #3
Posted 07 October 2013 - 08:12 PM
The problem wasn't the file.close(), but it's preferable to have it anyway.
Your problem at line 30 seem to be that the file you're trying to read does not exist, or you have the wrong path to it, a good habit would be to use shell.resolve().

So your code should be something like this…

function read(a)
  local file = assert(fs.open(shell.resolve(a), "r"), "File not found")
  local b = file.readLine()
  file.close()
  return b
end
DerKoch #4
Posted 07 October 2013 - 09:42 PM
Just ran some tests with OP's program and the fs.close() in general, and I come to the conclusion that it is 100% the fault of the missing fs.close(). I guess the CC hardware can open about 128 handles before getting into trouble.
AgentE382 #5
Posted 07 October 2013 - 10:32 PM
Why don't you try adding some debug output to your program? The deal is that CC isn't opening the file. Try replacing your read() function with this one to find out what's causing the error.

function read(a)
  local file = fs.open(a, "r")
  if not file then
    error("Unable to open file in read mode: " .. a)
  else
    local b = file.readLine()
    file.close()
    return b
  end
end

That way, you'll know what file it's failing on. You should also be able to read the stack traceback to find which function called read() to open the file.

Also note: By defining your read() function, you're replacing the default global read() function. If you forgot and tried to get some input from the user, you need to name this function something else, because that's your error.