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

Endless errors of ending a function

Started by Brod8362, 19 July 2015 - 05:05 AM
Brod8362 #1
Posted 19 July 2015 - 07:05 AM
Hello,
I have been having some strange issues with Functions in my program.
I have been creating an RPG and while I was coding part of it, I got an error with one of my functions.
Here is the error:

bios:367: [string "battle"]:109: 'end' expected (to close 'function' at line 101)

I have tried adding and removing ends and it doesn't want to stop giving this error.

Spoiler

function drawHUD()
shell.run("/rom/programs/clear")
img = paintutils.loadImage("/rpg/imgs/btl")
paintutils.drawImage(img,1,1)
  term.setCursorPos(1,2)
  print("ATTACK")
  term.setCursorPos(1,5)
  print("MAGIC")
  term.setCursorPos(1,8)
  print("ITEMS")
  term.setCursorPos(1,11)
  print("RUN")
  term.setCursorPos(10,1)
  print("XP")
  term.setCursorPos(10,2)
  print(XP)
  term.setCursorPos(27,1)
  print("HP")
  term.setCursorPos(27,2)
  print(HP)
  term.setCursorPos(33,1)
  print("MP")
  term.setCursorPos(33,2)
  print(MP)
  term.setCursorPos(39,1)
  print("STATUS")
  term.setCursorPos(39,2)
  print(STATUS)
  term.setCursorPos(47,1)
  print("LV")
  term.setCursorPos(47,2)
  print(LV)
  term.setCursorPos(27,4)
  print("Enemy")
  term.setCursorPos(28,5)

	print("HP")
  term.setCursorPos(28,6)
  print(eHP)
  term.setCursorPos(6,14)
end

function playerAction()
term.setCursorPos(6,12)
input = read()
if input == "A" or input == "a" then
attackEnemy()
drawHUD()
enemyAttack()
drawHUD()
checkWin()
checkLose()
playerAction()
end
if input == "M" or input == "m" then
print("MAGIC")
end
if input == "I" or input == "i" then
print("ITEMS")
end
if input == "R" or input == "r" then
print("RUN AWAY")
end
if input == "W" or input == "w" then
enemyAttack()
checkWin()
checkLose()
drawHUD()
playerAction()
end
end

function attackEnemy()
dmg = ATT*1
eHP = eHP-dmg
end

function enemyAttack()
eDMG = eATT*1
HP = HP-eDMG
end

function checkWin()
if eHP < 1 then
print("VICTORY")
sleep(3)
shell.run("/rpg/menu")
end
end

function checkLose()
if HP < 1 then
print("LOSS...")
sleep(3)
shell.run("/rpg/menu")
end
end

function magicList()
print("1. Blast -- 20 MP, 3 DMG")
select = read()
if select  == "1" then
  mATT = 10
  mpCost = 20
  useMagic()
end
else if
  magicList()
end
end
end



function useMagic()
if MP > mpCost or if MP = mpCost then
mDMG = MAG*mATT
MP = MP - mpCost
eHP = eHP - mDMG
end
-- HERE IS A TON OF VARIABLES
HP = 50
MP = 50
ATT = 5
DEF = 5
MAG = 5
STATUS = "OK"
LV = 1
XP = 15
-- HERE IS SOME ENEMY VARS
eHP = 20
eMP = 20
eATT = 5
eDEF = 5
eMAG = 5
eSTATUS = "OK"
-- END OF VARIABLES
-- START BATTLE
drawHUD()
playerAction()

Thank you for your help!
Bomb Bloke #2
Posted 19 July 2015 - 07:13 AM
This is why indentation is your friend.

First off, remember you can't "else" if you've "end"ed your "if" block already. Read through this guide to see how it's done.

The "fixed" version of your listMagic() function would look like:

function magicList()
	print("1. Blast -- 20 MP, 3 DMG")
	select = read()
	if select  == "1" then
		mATT = 10
		mpCost = 20
		useMagic()
	else
		magicList()
	end
end

… though it honestly shouldn't be calling itself in order to loop - the tutorial linked above also covers "while" and "repeat" loops, so read up on those while you're in there.

You're also missing an "end" under your useMagic() function.
HPWebcamAble #3
Posted 19 July 2015 - 07:16 AM
Edit: :ph34r:/>

Line 101 isn't a function declaration.. But oh well.

This is the function that's causing the problem:

function magicList()
  print("1. Blast -- 20 MP, 3 DMG")
  select = read()
  if select  == "1" then
	mATT = 10
	mpCost = 20
	useMagic()
  end
  else if
	magicList()
  end
  end
end

Here it is corrected:


function magicList()
  print("1. Blast -- 20 MP, 3 DMG")
  select = read()
  if select  == "1" then
	mATT = 10
	mpCost = 20
	useMagic() --# When using 'elseif', you don't need an end here
  elseif --# 'elseif' is one word
	magicList()
  end
end --# There was an extra end here
Edited on 19 July 2015 - 05:16 AM
Brod8362 #4
Posted 19 July 2015 - 07:30 AM
Thanks for your help. I recently have gotten back into lua so I had forgotten some things. Stupid me.
Brod8362 #5
Posted 19 July 2015 - 07:35 AM
This is why indentation is your friend.

First off, remember you can't "else" if you've "end"ed your "if" block already. Read through this guide to see how it's done.

The "fixed" version of your listMagic() function would look like:

function magicList()
	print("1. Blast -- 20 MP, 3 DMG")
	select = read()
	if select  == "1" then
		mATT = 10
		mpCost = 20
		useMagic()
	else
		magicList()
	end
end

… though it honestly shouldn't be calling itself in order to loop - the tutorial linked above also covers "while" and "repeat" loops, so read up on those while you're in there.

You're also missing an "end" under your useMagic() function.

I know I'm missing an End under the useMagic function. I stopped when I ran into this error trying to fix it and I stopped working on that one.
Lignum #6
Posted 19 July 2015 - 01:15 PM
If you are going to use recursion in your magicList function, at least use a tail call. Without one, you'd get a stack overflow error eventually:

if select == "1" then
   ...
else
   return magicList() --# 'return' makes this call a tail call.
end
flaghacker #7
Posted 19 July 2015 - 03:10 PM
If you are going to use recursion in your magicList function, at least use a tail call. Without one, you'd get a stack overflow error eventually:

if select == "1" then
   ...
else
   return magicList() --# 'return' makes this call a tail call.
end

Good point, but recursion is not appropriate in this case. Use an actual loop structure instead.