[SOLVED] Need Help with Rectangle Formation

I did not understand very well what I have to do at this level can someone please help me
Here is the code:

# Form up soldiers and archers in rectangle formations.

# The distance between units.
step = 8

# First form up soldiers.
sergeant = hero.findNearest(hero.findByType("soldier"))
# The coordinates of the bottom left corner.
soldierX = 8
soldierY = 8
# The width and height of the formation.
width = sergeant.rectWidth
height = sergeant.rectHeight

for x in range(soldierX, soldierX + width + 1, 8):
    for y in range(soldierY, soldierY + height + 1, 8):
        hero.summon("soldier")
        lastUnit = hero.built[len(hero.built)-1]
        # Command the last built unit by using the  x/y variables:
        
# Next form up archers.
sniper = hero.findNearest(hero.findByType("archer"))
# The coordinates of the bottom left corner.
archerX1 = 48
archerY1 = 8
# The coordinates of the top right corner.
archerX2 = sniper.archerX2
archerY2 = sniper.archerY2

for x in range(archerX1, archerX2 + 1, 8):
    for y in range(archerY1, archerY2 + 1, 8):
        # Summon an archer.
        hero.summon("archer")
        # Find the last built unit.
        
        # Command the last built unit by using the  x/y variables:
        
        pass

You basically have two code blocks that you need to add code to. In the first block (the first big yellow arrow), you just need to command the soldier to move to x, y.

Using that first block as a template, you need to flesh out the second block. They are almost identical, except for one targets soldiers and the other archers.

You only need to add code where the arrows indicate:

This is my code now

for x in range(soldierX, soldierX + width + 1, 8):
    for y in range(soldierY, soldierY + height + 1, 8):
        hero.summon("soldier")
        lastUnit = hero.built[len(hero.built)-1]
        # Command the last built unit by using the  x/y variables:
        soldiers = self.findFriends()
        soldierIndex = 0
        soldier = soldiers[soldierIndex]
        hero.command(soldier, "move", {"x": 24, "y": 25})
# Next form up archers.
sniper = hero.findNearest(hero.findByType("archer"))
# The coordinates of the bottom left corner.
archerX1 = 48
archerY1 = 8
# The coordinates of the top right corner.
archerX2 = sniper.archerX2
archerY2 = sniper.archerY2

for x in range(archerX1, archerX2 + 1, 8):
    for y in range(archerY1, archerY2 + 1, 8):
        # Summon an archer.
        hero.summon("archer")
        # Find the last built unit.
        lastUnit = hero.built[len(hero.built)-1]
        # Command the last built unit by using the  x/y variables:
        archers = self.findFriends()
        archerIndex = 0
        archer = archers[archerIndex]
        hero.command(archer, "move", {"x": 48, "y": 24})
        pass

I get this error

Looks like you are missing a few lines…what you just posted starts at line 15…please post all of your code.

Here is all the code

# Form up soldiers and archers in rectangle formations.

# The distance between units.
step = 8

# First form up soldiers.
sergeant = hero.findNearest(hero.findByType("soldier"))
# The coordinates of the bottom left corner.
soldierX = 8
soldierY = 8
# The width and height of the formation.
width = sergeant.rectWidth
height = sergeant.rectHeight

for x in range(soldierX, soldierX + width + 1, 8):
    for y in range(soldierY, soldierY + height + 1, 8):
        hero.summon("soldier")
        lastUnit = hero.built[len(hero.built)-1]
        # Command the last built unit by using the  x/y variables:
        soldiers = self.findFriends()
        soldierIndex = 0
        soldier = soldiers[soldierIndex]
        hero.command(soldier, "move", {"x": 24, "y": 25})
# Next form up archers.
sniper = hero.findNearest(hero.findByType("archer"))
# The coordinates of the bottom left corner.
archerX1 = 48
archerY1 = 8
# The coordinates of the top right corner.
archerX2 = sniper.archerX2
archerY2 = sniper.archerY2

for x in range(archerX1, archerX2 + 1, 8):
    for y in range(archerY1, archerY2 + 1, 8):
        # Summon an archer.
        hero.summon("archer")
        # Find the last built unit.
        lastUnit = hero.built[len(hero.built)-1]
        # Command the last built unit by using the  x/y variables:
        archers = self.findFriends()
        archerIndex = 0
        archer = archers[archerIndex]
        hero.command(archer, "move", {"x": 48, "y": 24})
        pass

Hi @Ry4n_17, you’re not quite following the instructions here.
It says:

And you wrote:

Your code won’t work here, soldierIndex doesn’t increment so you will always command the same soldier. Make sure you follow the instructions…
Use the variables lastUnit, x and y.
You only need one line after the comment.
Danny

hero.command(lastUnit, "move", x, y)

dont understand the x, y part

The x and y are variables that can be used to represent the coordinates you want to move to. These are being calculated via the 'for loop’s at the beginning of each code block. Remember, each block is very similar, except for either targeting soldier, or archer.

In the full code you posted above, you have:

This is very close, but instead of using literal coordinates (the 24 and 25), you want to use the variables instead.

This is my code now

# Form up soldiers and archers in rectangle formations.

# The distance between units.
step = 8

# First form up soldiers.
sergeant = hero.findNearest(hero.findByType("soldier"))
# The coordinates of the bottom left corner.
soldierX = 8
soldierY = 8
# The width and height of the formation.
width = sergeant.rectWidth
height = sergeant.rectHeight

for x in range(soldierX, soldierX + width + 1, 8):
    for y in range(soldierY, soldierX + width + 1, 8):
        hero.summon("soldier")
        lastUnit = hero.built[len(hero.built)-1]
        # Command the last built unit by using the  x/y variables:
        hero.command(lastUnit, "move", {"x":soldierX, "y": soldierY})
# Next form up archers.
sniper = hero.findNearest(hero.findByType("archer"))
# The coordinates of the bottom left corner.
archerX1 = 48
archerY1 = 8
# The coordinates of the top right corner.
archerX2 = sniper.archerX2
archerY2 = sniper.archerY2

for x in range(archerX1, archerX2 + 1, 8):
    for y in range(archerY1, archerY2 + 1, 8):
        # Summon an archer.
        hero.summon("archer")
        # Find the last built unit.
        lastUnit = hero.built[len(hero.built)-1]
        # Command the last built unit by using the  x/y variables:
        hero.command(lastUnit, "move", {"x": archerX1, "y": archerY1 })
        pass


The x and y that you want to use are from the for loops:

for x in range(soldierX, soldierX + width + 1, 8):
    for y in range(soldierY, soldierX + width + 1, 8):

They are the variables being used to calculate the coordinates.

But how do i use the code

hero.command(lastUnit, "move", {"x":soldierX, "y": soldierY})

thats the code that i used but the soldiers and archers move to one x only.

That’s because those are not the correct variables and you are only defining them once, so they will only point to one coordinate (location). You literally need to use the x and y variables.

it said success in the run but it dosent work now

Nevermind i refreshed and it worked
Thanks again ded

1 Like

The Soldier for loop with the y range is not quite correct. You happened to get a seed (arrangement of variables to change the level and test reliability) that worked with the error.

The y value: does it expect width or height?

1 Like

Good catch!..completely missed that one :slight_smile: