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

[Solved][LUA] [Error] Bad argument: string expected, got nil

Started by karrotsrkool, 09 June 2012 - 05:15 PM
karrotsrkool #1
Posted 09 June 2012 - 07:15 PM
So I'm making space invaders, I know that it has almost defiantly been made before, and have been experiencing the error above. The code that is giving the error is:

for i = 0, invaderwidth do
for i = 0, invaderheight do
  invaders[i][ii] = invaders[i + firstinvader][ii]
end
end
The full source is:
Spoiler

function clear()
term.clear()
term.setCursorPos(1, 1)
end
function moveCar(oldPos, mov)
term.setCursorPos(oldPos, 18)
write("   ")
term.setCursorPos(oldPos + mov, 18)
write("_^_")
term.setCursorPos(1, 1)
end
function updateBullet(bulletX, oldBulletY)
term.setCursorPos(bulletX, oldBulletY)
write(" ")
term.setCursorPos(bulletX, oldBulletY - 1)
write("|")
term.setCursorPos(1, 1)
end
function drawInvaders(invaderX, invaderY)
for i = 0, invaderwidth do
  for ii = 0, invaderheight do
   if (invaders[i][ii] == true) then
	if (directionRight) then
	 term.setCursorPos(i * 2 + invaderX - 1, ii * 2 + invaderY)
	 print(" *")
	else
	 term.setCursorPos(i * 2 + invaderX, ii * 2 + invaderY)
	 print("* ")
	end
   end
  end
end
term.setCursorPos(1, 1)
end
function clearInvaders()
for i = 0, invaderwidth do
  for ii = 0, invaderheight do
   if (invaders[i][ii] == true) then
	term.setCursorPos(i * 2 + invaderX, ii * 2 + invaderY)
	print(" ")
   end
  end
end
term.setCursorPos(1, 1)
end
function updateWidth()
firstinvader = 11
lastinvader = 0
for i = 0, invaderwidth do
  for ii = 0, invaderheight do
   if (invaders[i][ii] == true) then
	firstinvader = i
	break
   end
  end
  if (firstinvader < 11) then
   break
  end
end
for i = 0, invaderwidth do
  for ii = 0, invaderheight do
   if (invaders[invaderwidth - i][ii] == true) then
	lastinvader = invaderwidth - i
	break
   end
  end
  if (lastinvader > 0) then
   break
  end
end
invaderX = invaderX + firstinvader
write(firstinvader)
invaderwidth = lastinvader - firstinvader
if (firstinvader == 11) then
  win()
end
for i = 0, invaderwidth do
  for i = 0, invaderheight do
   invaders[i][ii] = invaders[i + firstinvader][ii]
  end
end
end
function win()
clear()
write("You won, press any key to quit!")
while true do
  os.pullEvent()
end
clear()
end

clear()
local timer = os.startTimer(0)
carPos = 23
moveCar(carPos, 0)
bulletX = 0
bulletY = 0
bulletMoving = false
multi = 0
invaderX = 10
invaderY = 1
invaderwidth = 10
invaderheight = 5
directionRight = true
invaders = {}
for i = 0, 10 do
invaders[i] = {}
end
for i = 0, 10 do
for ii = 0, 5 do
  invaders[i][ii] = true
end
end
while (true) do
e, p1, p2 = os.pullEvent()
if (e == "key") then
  if (p1 == 203 and carPos > 1) then
   moveCar(carPos, -1)
   carPos = carPos - 1
  elseif (p1 == 205 and carPos < 47) then
   moveCar(carPos, 1)
   carPos = carPos + 1
  elseif (p1 == 16) then
   clear()
   break
  elseif (p1 == 57 and bulletMoving == false) then
   bulletX = carPos + 1
   bulletY = 18
   bulletMoving = true
  end
end
if(e == "timer") then
  if (bulletMoving == true) then
   bulletY = bulletY - 1
   if (bulletY > 0) then
	updateBullet(bulletX, bulletY)
   else
	bulletMoving = false
   end
   if (bit.band(invaderX, 1) == bit.band(bulletX, 1)) then
	t1 = (bulletX - invaderX) / 2
	t2 = (bulletY - invaderY) / 2
	if (t1 >= 0 and t2 >= 0 and t1 <= invaderwidth and t2 <= invaderheight) then
	 if (invaders[t1][t2] == true) then
	  invaders[(bulletX - invaderX) / 2][(bulletY - invaderY) / 2] = false
	  bulletMoving = false
	  term.setCursorPos(bulletX, bulletY - 1)
	  write(" ")
	  updateWidth()
	 end
	end
   end
  end
  multi = multi + 0.1
  if (multi > 0.8) then
   multi = 0
  end
  if (multi == 0.2) then
   if (directionRight == true) then
	if (invaderX + invaderwidth * 2 < 48) then
	 invaderX = invaderX + 1
	elseif (invaderX + invaderwidth * 2 == 48) then
	 clearInvaders()
	 invaderY = invaderY + 1
	 directionRight = false
	 if (invaderY + invaderheight > 12) then
	  clear()
	  write("You lost, press any key to quit!")
	  while(true) do
	   os.pullEvent()
	   break
	  end
	  clear()
	  break
	 end
	end
   else
	if (invaderX > 1) then
	 invaderX = invaderX - 1
	elseif (invaderX == 1) then
	 clearInvaders()
	 invaderY = invaderY + 1
	 directionRight = true
	 if (invaderY + invaderheight > 12) then
	  clear()
	  write("You lost, press any key to quit!")
	  while(true) do
	   os.pullEvent()
	   break
	  end
	  clear()
	  break
	 end
	end
   end
   drawInvaders(invaderX, invaderY)
  end
  timer = os.startTimer(0.1)
end
end
If you need to know anything else or don't get how something works then just let me know and I will do my best to explain the code.
Thanks Andy A
Cloudy #2
Posted 09 June 2012 - 07:19 PM
Please advise us of the exact error message please (including line number) - we can easier find out where the problem lies then!
karrotsrkool #3
Posted 09 June 2012 - 07:23 PM
The exact error message is "bios:48: bad argument: string expected, got nil" and line 48, to avoid you having to count, is "invaders[i][ii] = invaders[i + firstinvader][ii]".
Thanks Andy A
archit #4
Posted 09 June 2012 - 07:50 PM
So I'm making space invaders, I know that it has almost defiantly been made before, and have been experiencing the error above. The code that is giving the error is:

for i = 0, invaderwidth do
for i = 0, invaderheight do
  invaders[i][ii] = invaders[i + firstinvader][ii]
end
end
The full source is:
Spoiler

function clear()
term.clear()
term.setCursorPos(1, 1)
end
function moveCar(oldPos, mov)
term.setCursorPos(oldPos, 18)
write("   ")
term.setCursorPos(oldPos + mov, 18)
write("_^_")
term.setCursorPos(1, 1)
end
function updateBullet(bulletX, oldBulletY)
term.setCursorPos(bulletX, oldBulletY)
write(" ")
term.setCursorPos(bulletX, oldBulletY - 1)
write("|")
term.setCursorPos(1, 1)
end
function drawInvaders(invaderX, invaderY)
for i = 0, invaderwidth do
  for ii = 0, invaderheight do
   if (invaders[i][ii] == true) then
	if (directionRight) then
	 term.setCursorPos(i * 2 + invaderX - 1, ii * 2 + invaderY)
	 print(" *")
	else
	 term.setCursorPos(i * 2 + invaderX, ii * 2 + invaderY)
	 print("* ")
	end
   end
  end
end
term.setCursorPos(1, 1)
end
function clearInvaders()
for i = 0, invaderwidth do
  for ii = 0, invaderheight do
   if (invaders[i][ii] == true) then
	term.setCursorPos(i * 2 + invaderX, ii * 2 + invaderY)
	print(" ")
   end
  end
end
term.setCursorPos(1, 1)
end
function updateWidth()
firstinvader = 11
lastinvader = 0
for i = 0, invaderwidth do
  for ii = 0, invaderheight do
   if (invaders[i][ii] == true) then
	firstinvader = i
	break
   end
  end
  if (firstinvader < 11) then
   break
  end
end
for i = 0, invaderwidth do
  for ii = 0, invaderheight do
   if (invaders[invaderwidth - i][ii] == true) then
	lastinvader = invaderwidth - i
	break
   end
  end
  if (lastinvader > 0) then
   break
  end
end
invaderX = invaderX + firstinvader
write(firstinvader)
invaderwidth = lastinvader - firstinvader
if (firstinvader == 11) then
  win()
end
for i = 0, invaderwidth do
  for i = 0, invaderheight do
   invaders[i][ii] = invaders[i + firstinvader][ii]
  end
end
end
function win()
clear()
write("You won, press any key to quit!")
while true do
  os.pullEvent()
end
clear()
end

clear()
local timer = os.startTimer(0)
carPos = 23
moveCar(carPos, 0)
bulletX = 0
bulletY = 0
bulletMoving = false
multi = 0
invaderX = 10
invaderY = 1
invaderwidth = 10
invaderheight = 5
directionRight = true
invaders = {}
for i = 0, 10 do
invaders[i] = {}
end
for i = 0, 10 do
for ii = 0, 5 do
  invaders[i][ii] = true
end
end
while (true) do
e, p1, p2 = os.pullEvent()
if (e == "key") then
  if (p1 == 203 and carPos > 1) then
   moveCar(carPos, -1)
   carPos = carPos - 1
  elseif (p1 == 205 and carPos < 47) then
   moveCar(carPos, 1)
   carPos = carPos + 1
  elseif (p1 == 16) then
   clear()
   break
  elseif (p1 == 57 and bulletMoving == false) then
   bulletX = carPos + 1
   bulletY = 18
   bulletMoving = true
  end
end
if(e == "timer") then
  if (bulletMoving == true) then
   bulletY = bulletY - 1
   if (bulletY > 0) then
	updateBullet(bulletX, bulletY)
   else
	bulletMoving = false
   end
   if (bit.band(invaderX, 1) == bit.band(bulletX, 1)) then
	t1 = (bulletX - invaderX) / 2
	t2 = (bulletY - invaderY) / 2
	if (t1 >= 0 and t2 >= 0 and t1 <= invaderwidth and t2 <= invaderheight) then
	 if (invaders[t1][t2] == true) then
	  invaders[(bulletX - invaderX) / 2][(bulletY - invaderY) / 2] = false
	  bulletMoving = false
	  term.setCursorPos(bulletX, bulletY - 1)
	  write(" ")
	  updateWidth()
	 end
	end
   end
  end
  multi = multi + 0.1
  if (multi > 0.8) then
   multi = 0
  end
  if (multi == 0.2) then
   if (directionRight == true) then
	if (invaderX + invaderwidth * 2 < 48) then
	 invaderX = invaderX + 1
	elseif (invaderX + invaderwidth * 2 == 48) then
	 clearInvaders()
	 invaderY = invaderY + 1
	 directionRight = false
	 if (invaderY + invaderheight > 12) then
	  clear()
	  write("You lost, press any key to quit!")
	  while(true) do
	   os.pullEvent()
	   break
	  end
	  clear()
	  break
	 end
	end
   else
	if (invaderX > 1) then
	 invaderX = invaderX - 1
	elseif (invaderX == 1) then
	 clearInvaders()
	 invaderY = invaderY + 1
	 directionRight = true
	 if (invaderY + invaderheight > 12) then
	  clear()
	  write("You lost, press any key to quit!")
	  while(true) do
	   os.pullEvent()
	   break
	  end
	  clear()
	  break
	 end
	end
   end
   drawInvaders(invaderX, invaderY)
  end
  timer = os.startTimer(0.1)
end
end
If you need to know anything else or don't get how something works then just let me know and I will do my best to explain the code.
Thanks Andy A

isn't your nested loop suppose to be ii ?

Did not look at your full code, so other thing to check is to be sure firstinvader is actually assigned as well. Could put in a print statement right before the 2 nested for loops to ensure it's set properly as you want it.
Cloudy #5
Posted 09 June 2012 - 08:02 PM
The error is at bios:48 - meaning that it's an error there. However, it is caused by you passing a nil value to write() somewhere.
karrotsrkool #6
Posted 09 June 2012 - 08:19 PM
Wow, I feel really stupid now, the error was that the second for loop was meant to be ii as archit suggested. The I knew what the error meant, it was not in fact that I was giving a bad argument to write() however the fact that I was copying a bad argument in to an object in the array.
Thanks for the help, this bug was driving me mad.
-Andy A