Play Home Contribute Github Join Us! Discourse Staff Members Github Contribution Guides Team

[solved] Raiders of the Long Dark he lp

So I think I have a specific problem with my isPathClear for my peasant, and I can’t identify why.

# Your goal is to protect the peasant and move to the right.
# Arryn Stonewall will defend the front, and command the soldiers.
# You need to cover the rear and command the peasant.

arryn = hero.findByType("raider")[0]
peasant = hero.findByType("peasant")[0]

def chooseHeroStrategy():
    enemy = hero.findNearestEnemy()
    # Return either "fight" or "advance".
    # Try to stay 5m behind the peasant when not fighting.
    # Don't get more than 15m away from the peasant.
    if hero.distanceTo(peasant) > 15:
        return "advance"
    if enemy and hero.distanceTo(enemy) < 5:
        return "fight"
    else:
        return "advance"
    pass

def heroFight(enemy):
    # Stop the ogres from rushing past you to get to the peasant!
    # Hint: try to slow them down if you can
    if hero.isReady("bash"):
        hero.bash(enemy)
    else:
        hero.attack(enemy)
    pass

def heroAdvance():
    # Stay behind the peasant
    hero.moveXY(peasant.pos.x - 2, peasant.pos.y)
    pass

def choosePeasantStrategy():
    # Return "follow", "build-above", or "build-below"
    # Hint: use isPathClear() to determine where the hallways are
    arryn = hero.findByType("raider")[0]
    peasant = hero.findByType("peasant")[0]
    if peasant.distanceTo(arryn) > 5:
        return "follow"
    if peasant.isPathClear(peasant.pos.x, peasant.pos.y + 5):
        return "build-above"
    if peasant.isPathClear(peasant.pos.x, peasant.pos.y - 5):
        return "build-below"
    pass

def peasantAdvance():
    # Keep the peasant behind Arryn and her soldiers.
    behind = {'x': arryn.pos.x - 3, 'y': arryn.pos.y}
    hero.command(peasant, "move", behind)
    pass

def peasantBuild(x,y):
    # Command the peasant to build a palisade.
    hero.buildXY("palisade", x, y)
    pass

while True:
    enemy = hero.findNearestEnemy()
    heroStrategy = chooseHeroStrategy()
    if heroStrategy == "fight":
        heroFight(enemy)
    elif heroStrategy == "advance":
        heroAdvance()
    
    peasantStrategy = choosePeasantStrategy()
    if peasantStrategy == "build-above":
        peasantBuild(peasant.pos.x, peasant.pos.y + 5)
    elif peasantStrategy == "build-below":
        peasantBuild(peasant.pos.x, peasant.pos.y - 5)
    elif peasantStrategy == "follow":
        peasantAdvance()
    

This is where exactly, and it says “cannot read property”

def choosePeasantStrategy():
    # Return "follow", "build-above", or "build-below"
    # Hint: use isPathClear() to determine where the hallways are
    arryn = hero.findByType("raider")[0]
    peasant = hero.findByType("peasant")[0]
    if peasant.distanceTo(arryn) > 5:
        return "follow"
    if peasant.isPathClear(peasant.pos.x, peasant.pos.y + 5):
        return "build-above"
    if peasant.isPathClear(peasant.pos.x, peasant.pos.y - 5):
        return "build-below"
    pass

I tried defining an up and down variable for when the function runs, so it would check whether the peasant.pos and up is clear, but it didn’t work.

Hmm…I see several issues and at least a couple of definite problems. Would you prefer to work one code block at a time, or have them itemized in a list?

i think i want the specifics for one at a time. thnaks

1 Like

Ok, starting from the top down, Starting with choosePeasantStrategy:

You are defining arryn and the peasant at the top, which is good. Next, you have your if statements/clauses…you should have only one if statement and one else clause…there are three things you need to test for:

  1. is the hero more than 15 away from the peasant, or
  2. is there an enemy, or
  3. is the peasant more than 15 away from the enemy…as defined by the peasant, not the hero

If true, then advance
if not true, fight

The problem is that the isPathClear is done wrong

if peasant.isPathClear(peasant.pos.x, peasant.pos.y + 5):

Your suppose to do this

if hero.isPathClear(peasant.pos, targetPos):
  1. Your peasant don’t have the ability to check isPathClear
  2. Your putting the peasant’s x and y in the brackets instead of the peasant’s pos

thanks i will try these

I tried to do these to the extent of what I know, and I probably made a mistake. There’s also a new(maybe not?) problem of peasant needing to be defined, so I put peasant in as a parameter, but it’s still not working. Can you help on peasant being defined?

# Your goal is to protect the peasant and move to the right.
# Arryn Stonewall will defend the front, and command the soldiers.
# You need to cover the rear and command the peasant.

arryn = hero.findByType("raider")[0]
peasant = hero.findByType("peasant")[0]

def chooseHeroStrategy(peasant):
    enemy = peasant.findNearestEnemy()
    # Return either "fight" or "advance".
    # Try to stay 5m behind the peasant when not fighting.
    # Don't get more than 15m away from the peasant.
    if enemy and peasant.distanceTo(enemy) < 5:
        return "fight"
    elif hero.distanceTo(peasant) > 15:
        return "advance"
    pass

def heroFight(enemy):
    # Stop the ogres from rushing past you to get to the peasant!
    # Hint: try to slow them down if you can
    if hero.isReady("bash"):
        hero.bash(enemy)
    else:
        hero.attack(enemy)
    pass

def heroAdvance(peasant):
    # Stay behind the peasant
    hero.moveXY(peasant.pos.x - 2, peasant.pos.y)
    pass

def choosePeasantStrategy(peasant):
    # Return "follow", "build-above", or "build-below"
    # Hint: use isPathClear() to determine where the hallways are
    up = {'x': peasant.pos.x, 'y': peasant.pos.y + 50}
    down = {'x': peasant.pos.x, 'y': peasant.pos.y - 50}
    if peasant.distanceTo(arryn) > 5:
        return "follow"
    if hero.isPathClear(peasant.pos, up):
        return "build-above"
    if hero.isPathClear(peasant.pos, down):
        return "build-below"
    pass

def peasantAdvance(peasant, arryn):
    # Keep the peasant behind Arryn and her soldiers.
    behind = {'x': arryn.pos.x - 3, 'y': arryn.pos.y}
    hero.command(peasant, "move", behind)
    pass

def peasantBuild(x,y):
    # Command the peasant to build a palisade.
    hero.buildXY("palisade", x, y)
    pass

while True:
    arryn = hero.findByType("raider")[0]
    peasant = hero.findByType("peasant")[0]
    enemy = peasant.findNearestEnemy()
    heroStrategy = chooseHeroStrategy(peasant)
    if heroStrategy == "fight":
        heroFight(enemy)
    elif heroStrategy == "advance":
        heroAdvance()
    
    peasantStrategy = choosePeasantStrategy(peasant)
    if peasantStrategy == "build-above":
        peasantBuild(peasant.pos.x, peasant.pos.y + 5)
    elif peasantStrategy == "build-below":
        peasantBuild(peasant.pos.x, peasant.pos.y - 5)
    elif peasantStrategy == "follow":
        peasantAdvance(peasant, arryn)
    

just changed the code to have a lot of parameters that i feel are unnecessary, but I couldn’t find any other ways to troubleshoot. I’m probably following your directions wrong and may need further guidance.

You didn’t put ‘peasant’ here

Actually, for the chooseHeroStrategy definition, you are pretty close.

The methodology I’m proposing is: If there is an enemy, is it close enough? If it is far enough away, go ahead and advance…otherwise fight.

Your if statement needs three elements to it: is hero > 15 from peasant, or is there no enemy, or is the peasant more than 15 from the enemy…if any one of these are true, then advance, else fight.

There should be no elif here.

I just found two more problems.

  1. In your peasantBuild(x,y) function, you have to command the peasant to build the palisade.
  2. Try using hero.move() instead of hero.moveXY()

Brodudes I am happy to say I followed your instructions and it worked out with a big green success.

1 Like

Sorry mr ded I meant that I wanted each block of code to be explained to me so I can solve it good

aha…I misunderstood that part then…glad you got it resolved :slight_smile: