Protect and serve (lua)

Hi I'm really stuck i have no idea why my code won't run correctly I'm on the level protect and serve here is my code can some one explain and help thanks.

defend = {}
defend[1] = {x=98, y=28}
defend[2] = {x=84, y=7}

soldiers = {}

local friends = hero:findFriends()
for i=1,#friends do
      local friend = friends[i]
       if friend and friend.type == "soldier" then
            hero:say("added to soldiers")
            table.insert(soldiers, friend)
    else
        hero:say("added to defend")
        table.insert(defend, friend)
    end
end

while true do
    for i=1,#soldiers  do
    local soldier = soldiers[i]
        if soldier then 
            hero:command(soldier, "defend", defend[(i - 1) % #defend + 1])
        end
    end
end

Hi @Selston! Welcome to the CodeCombat Discourse! This is a safe place to chat and ask for level help. Before you begin your journey, could you please go through our rules that make this discourse an awesome place? It helps us all :grin: We hope you enjoy your stay!!

Could you tell us what the error is, the level name, and perhaps a screenshot of the error?

I’m not getting any errors i’ve asked the ai bot and it says im only here to discuss code.


and thats my gear. My soldiers don’t move i think its something to do with my choice of hero / gear but i could be mistaken.
also as a added side note you get thrown into this level with 0 understanding on what its needs you to type untill you ask the ai to which is tells you to type something you’ve never learned. for example:
hero:command(soldier, “defend”, defend[(i - 1) % #defend + 1]) no idea what it does.

also the level name is in the subject. “Protect and serve”

I’ll help you decipher this.

Since the line mentions an I as a variable I assume it’s meant to be in a loop.

I’m noticing that there’s a modulo (%) in the array index which most likely means it’s trying to create a kind of “loop”. Let me explain.

The way modulo works is that it gives the remainder for a division problem. Ex: 5 / 2 = 2 R 1 with R being the remainder. When you use the modulo in a loop with i being an index, then have i increase without limit, the result of i % x will always create a series of numbers that start at 0 and end at some number, which then loops back to 0 and the cycle repeats. Similar to a clock.

So basically, the code is trying to send the soldiers to defend but since the index always loops back to 0, the soldiers will split up instead of all going to one entity or something like that. This is because when the loop starts, the first soldier will go to index 0, then the next goes to 1, then 2, etc until one of the soldier’s defense index goes back to 0. Starting the cycle anew.

Now, I’m assuming the final plus 1 at the end is meant to make the index start at 1 since in lua arrays start at index 1, but i could be mistaken.

Unfortunately, I am no Lua expert so I don’t think I’ll be able to help to much with your problem, but I hope that my insight helped at least a little bit.

Also, I’m pretty sure your gear is completely fine.

thank you for the explanation that makes sense now how ever im still stuck on this level.

if some one could help it would be appreciated

So from my understanding there’s not many people who know lua so im kinda wasting my time here. if its java / python every 1 helps but lua its not the case.

Hey now don’t be rude. We all have lives other than just this discourse. I would help you but one: I haven’t done that level yet, and two: I don’t have the time to research about it as I have homework for 4 of my classes.

Yea lua is just not as popular cuz it has less versatileity

i wasn’t intending to come across as rude i apologise if it did. i was only making a statement so i apologise if any one thinks that was my intention.

1 Like

ill figure it out and when i do I’ll post it to help others.

1 Like

Wait, I think I found the problem. In the for loop where you’re inserting thangs (yes that’s what they’re actually called) into arrays you insert the friend into the defend array. Well, when you command a friend to defend something it uses positions not thangs. So try inserting the friend’s position into the defend array instead of just the friend itself.

2 Likes
    else
        hero:say("added to defend")
        table.insert(defend, friend.pos)
    end

So basically this instead

    else
        hero:say("added to defend")
        table.insert(defend, friend)
    end

this

3 Likes

i’ve already tried that it still doesn’t work

1 Like

Ok I reviewed my code to see what it’s supposed to look like and I think the problem is because what the ai told you is a little wack. The spot where you put the index for the defend array should just be an i instead of the gobbledeguck in it rn.

WAIT I FOUND IT. If you look in this if statement it says if friend and the friend’s type is a soldier then do something else do something else.

The problem is that since the if statement is asking if there’s a friend the else will only trigger if there isn’t a friend, when it’s supposed to trigger if the friend isn’t a soldier. Therefore since there’s always a friend there is nothing for the soldiers to defend in the first place

if friend.type == "soldier" then
            hero:say("added to soldiers")
            table.insert(soldiers, friend)
    else
        hero:say("added to defend")
        table.insert(defend, friend

So they should look like this and those if statements need to be nested inside an if friend statement.

still doesn't work im days into trying to get this to work now here's my current code.


local defend = {}
defend[1] = {x=98, y=28}
defend[2] = {x=84, y=7}

local soldiers = {}

local friends = hero:findFriends()
for i=1,#friends do
    local friend = friends[i]
    if friend then
        if friend.type ~= "soldier" then
            hero:say("added to defend")
            table.insert(defend, friend)
        else
            hero:say("added to soldiers")
            table.insert(soldiers, friend)
        end
    else
        hero:say("you have no friends")
    end
end

for i=1,#soldiers do
    local soldier = soldiers[i]
    if soldier then
        hero:command(soldier, defend[i])
    end
end

i even tried to make it so that it checks if its not a soldier first and add to defend then check if soldier etc.

idk if this’ll work or not but maybe try naming this for-loop’s variable (the i) to something else? Also, I’m pretty sure this is supposed to be in a while-true loop

Screenshot 2024-04-16 9.16.00 AM
Ok, after further investigation, the error is at line 13 and likely line 16 as well. You can tell because all the check marks mean the code ran fine, but the moment it tries to run line 13 an error occurs. Unfortunately, I literally have no idea what is wrong. So, you’re gonna have to find out yourself.