[SOLVED] Help with "Magic Exam", Lua

I am having an issue on the Magic exam level, my character will get to this door with a potion in it and then they will just stand there. I can’t seem to figure out why. The door before it was a scout that I used a spell on and my character wouldn’t move for some reason so i just added another move() function after the kill() function runs and it appeared to fix it. But now i am stuck on this potion door.

Here’s my Code:

-- Try to get the best grade (gold) at the magic exam.
-- Move to each X mark, then use a spell.
local function move()
    if num == 0 then
        hero:moveXY(18, 40)
    end
    
    if num == 1 then
        hero:moveXY(34, 40)
    end
    
    if num == 2 then
        hero:moveXY(50, 40)
    end
    
    if num == 3 then
        hero:moveXY(66, 40)
    end
    
    if num == 4 then
        hero:moveXY(66, 24)
    end
    
    if num == 5 then
        hero:moveXY(50, 24)
    end
    
    if num == 6 then
        hero:moveXY(34, 24)
    end
    
    if num == 7 then
        hero:moveXY(18, 24)
    end
end

local function kill()
    local enemy = hero:findNearestEnemy()
    if enemy.type == "scout" then
        hero:cast("poison-cloud", enemy)
    end
    num = num + 1
    move()
end

local function found()
    local item = hero:findNearestItem()
    if item.type == "potion" then
        hero:say(num)
        local itemPosition = item.pos
        local itemX = itemPosition.x
        local itemY = itemPosition.y
        hero:moveXY(itemX, itemY)
    end    
    
    if item.type == "poison" then
        hero:say(num)
        local itemPosition = item.pos
        local itemX = itemPosition.x
        local itemY = itemPosition.y
        hero:moveXY(itemX, itemY)
        hero:cast("regen", self)
    end
    num = num + 1
    
end

local function help()
    local friend = hero:findNearestFriend()
    if friend.type == "soldier" then
        hero:cast("heal", friend)
    end
    
    if friend.type == "goliath" then
        hero:cast("grow", friend)
    end
    
    num = num + 1
end

local num = 0
while true do
    move()
    local enemy = hero:findNearestEnemy()
    local item = hero:findNearestItem()
    local friend = hero:findFriends()
   
    if enemy then
        kill()
    end
    
    if item then
       found()
    end
    
    if friend then
        help()
    end
    
hero:say(num)
end

I’m not very familiar with Lua, but I’d suggest calling the num = num + 1 operator in the while true do loop. It would remove some of the redundancies. If that doesn’t work, I’d suggest trying to call the local variable in the function, for example,

...
local function found(item)
    if item.type == "potion" then
        hero:say(num)
        local itemPosition = item.pos
        local itemX = itemPosition.x
        local itemY = itemPosition.y
        hero:moveXY(itemX, itemY)
    end
    ...
end
...
while true do
    move()
    ...
    local item = hero:findNearestItem()
    if item then
       found(item)
    end
    num = num + 1
end

Again, I’m not that familiar with Lua, so I might be wrong. Other than that, your code looks pretty good!

That’s actually what I originally had however, if I put my num code there my character will stop at the door with the scout. I am pretty sure it is connected with the same reason my character needed the extra move function in my kill() function.

Hmm … you might want to try ... if item and item.type == "potion" then ... I’m not sure if that would help anything, but it would be worth a try. I’d also suggest removing the hero:say(num). There’s nothing really wrong with it, but I’ve found it can really slow down the code. If neither of those things work, you might want to make sure "potion" is the correct item.type. I think it is, but, then again, I’m not positive.

Yeah it was worth a try. I took a shot at it, I had to add the num = num + 1 code back to the kill function to allow my hero to move to the potion room again. Once I did that I added the if item and item.type code but it didn’t seem to do anything. I also took out the hero:say(num) code but it also didn’t change anything, I used that to test things in the past for my code. I have potion and poison as possible types but my hero just doesn’t do anything still hmm. So far I’m still at a loss unfortunately, thanks for the help though.

Okay, to see whether your hero can see the potion you might want to try hero:say(potion.id). If it doesn’t see the potion, that’s a problem. Other than that, though, I really don’t know what to say …

I put it in the potion portion of my found() function. But the hero still stands there.

Like this:

local function found()
    local item = hero:findNearestItem()
    if item.type == "potion" then
        hero:say(potion.id)
        local itemPosition = item.pos
        local itemX = itemPosition.x
        local itemY = itemPosition.y
        hero:moveXY(itemX, itemY)
    end    
    
    if item.type == "poison" then
        hero:say(num)
        local itemPosition = item.pos
        local itemX = itemPosition.x
        local itemY = itemPosition.y
        hero:moveXY(itemX, itemY)
        hero:cast("regen", self)
    end
end

However, i’ve noticed the checkmark that shows you when your code has succefully been run appears next to local function found() but doesn’t appear next to anything else in the function. Which tells me my hero for some reason may not be seeing the potion/poison.

Would you please post all your code to test the whole thing :slight_smile:

P.S. Welcome to the discourse :partying_face:

Thanks, and sure.

Here’s what I have right now:

-- Try to get the best grade (gold) at the magic exam.
-- Move to each X mark, then use a spell.
local function move()
    if num == 0 then
        hero:moveXY(18, 40)
    end
    
    if num == 1 then
        hero:moveXY(34, 40)
    end
    
    if num == 2 then
        hero:moveXY(50, 40)
    end
    
    if num == 3 then
        hero:moveXY(66, 40)
    end
    
    if num == 4 then
        hero:moveXY(66, 24)
    end
    
    if num == 5 then
        hero:moveXY(50, 24)
    end
    
    if num == 6 then
        hero:moveXY(34, 24)
    end
    
    if num == 7 then
        hero:moveXY(18, 24)
    end
end

local function kill()
    local enemy = hero:findNearestEnemy()
    if enemy.type == "scout" then
        hero:cast("poison-cloud", enemy)
    end
    num = num + 1
    move()
end

local function found()
    local item = hero:findNearestItem()
    if item.type == "potion" then
        hero:say(potion.id)
        local itemPosition = item.pos
        local itemX = itemPosition.x
        local itemY = itemPosition.y
        hero:moveXY(itemX, itemY)
    end    
    
    if item.type == "poison" then
        hero:say(num)
        local itemPosition = item.pos
        local itemX = itemPosition.x
        local itemY = itemPosition.y
        hero:moveXY(itemX, itemY)
        hero:cast("regen", self)
    end
end

local function help()
    local friend = hero:findNearestFriend()
    if friend.type == "soldier" then
        hero:cast("heal", friend)
    end
    
    if friend.type == "goliath" then
        hero:cast("grow", friend)
    end
end

local num = 0
while true do
    move()
    local enemy = hero:findNearestEnemy()
    local item = hero:findNearestItem()
    local friend = hero:findFriends()
   
    if enemy then
        kill()
    end
    
    if item then
       found()
    end
    
    if friend then
        help()
    end
num = num + 1
end

1 Like

Maybe you can try adding num a parameter for the move function, maybe it doesn’t know what num is,

also indent the num incrementation once here

num is a local variable, and it reflects the current stage of the exam.

You might want to try this:

local function found()
    local item = hero:findNearestItem()
    hero:moveXY(item.pos.x, item.pos.y)
    if item.type == "poison" then
        hero:cast("regen", self)
    end
end

Again, I’m not positive that will work, but it would eliminate some of the possible problems.

i havent done codecombat lua before, mainly roblox but ill try.

you put the variable num after you assigned it, maybe put it before the if statements.

Yeah, that should be totally okay, because the code calls the num variable in a function, and the function is called in a while true do loop, so num needs to be called before the while true do loop, and it is.

1 Like

alr, didnt know that with codecombat.

It was definitely worth a try, but my hero will just sit that with that code as well. The checkmark tells me it sees that there’s a local function found() but it doesn’t run the function for some reason. I’m starting to wonder if it’s some kind of glitch on this level with lua code perhaps.

Also, thanks for all the explaining. You sure know some about lua even if you don’t use it very much.

I did the indent, I didn’t catch that when I wrote it lol. But I previously had hero:say(num) in my code so I know my hero knows what it is and the value is being changed as it gets through the first 3 doors.

Alright, thats pretty weird

I have a question, does the function below run, and if it does, what happens?

All that happens is a check mark appears next to where local function found() is at. That tells me that it recognizes there is a function for when my hero sees an item but it doesn’t run the function for some reason. Other than that my character just sits there and doesn’t do anything.

If it were to run all that should happen is the character will move to coordinates of the item and if it’s a potion, they will pick it up and if it’s a poison they will heal after picking it up.

For what it’s worth, I just realized that the code has a potential formatting error.

if item then
       found()
    end

the found() function only has a three-space indent. So maybe this:

if item then
        found()
    end

I don’t know if that would change anything. I know that in JavaScript it wouldn’t, but in Python it does. I’m not sure about Lua, though.