Help on Mages Might!

@Hydrobolic there is this spell called “fire-burn”, The animation of the fireball in making comes over the hero’s head, but nothing happens after that, No projectile comes from the hero after that and my mana gets wasted. Is this a bug or is it something else.

The “fire-burn” spell is a spell that damages the opponent’s collectors

1 Like

Ohhhhh, now if I look at the collectors I see the fire animation over their heads😅. Thanks @Code_Master

Yep, it’s a spell to directly attack the opponent’s collectors!

The documentation (“hints”) should be the first place you look for this kind of information. It’s briefly mentioned under “special spells.”

Hey everyone, I have a doubt, can you use time and wait in mages might. Or is there some other command to do that

goutham123

1 Like

That is interesting to learn. I had been running into issues previously, where a while loop which I thought would let time pass apparently didn’t. I found out it was something like only the outermost while loop that would cause time to pass. (In Python at least). Needed some ugly work-arounds.

1 Like

I haven’t written competitive Python code in CodeCombat in a while, so I’m not clear on the intricacies of how it works. CodeCombat’s method of forcing a delay between iterations of a while-true is rather unnatural and undoubtedly leads to unexpected behaviour.

Reformatting a Mage’s Might program from casting spells in utility functions to focus on the event loop makes it trivial to run commands at arbitrary times, which works around these kinds of problems. In my program I maintain a schedule of spells I’d like to send in the future, so the main loop is as simple as “Forever: If I have a spell scheduled for this tick, cast it.”

2 Likes

If I recall correctly, we add a one-tick delay to the while true loop if there has been no other blocking action called during that while loop frame, but we don’t do that when the while loop has some other condition other than a Boolean literal like True. There might be some other exceptions, like nesting other while loops inside. This should be the same in all languages, not just Python. Code for that is here:

makeYieldFilter = (aether) -> (engine, evaluator, e) ->

  frame_stack = evaluator.frames
  #console.log x.type + " " + x.ast?.type for x in frame_stack
  #console.log "----"

  top = frame_stack[0]


  if e? and e.type is 'event' and e.event is 'loopBodyStart'

    # Legacy programming languages use 'Literal' whilst C++ and Java use 'BooleanLiteral'.
    if top.srcAst.type is 'WhileStatement' and (top.srcAst.test.type is 'Literal' or top.srcAst.test.type is 'BooleanLiteral')
      if aether.whileLoopMarker?
        currentMark = aether.whileLoopMarker(top)
        if currentMark is top.mark
          # console.log "[Aether] Frame #{this.world.age}: Forcing while-true loop to yield, repeat #{currentMark}"
          top.mark = currentMark + 1
          return true
        else
          # console.log "[Aether] Frame #{this.world.age}: Loop Avoided, mark #{top.mark} isnt #{currentMark}"
          top.mark = currentMark

  if aether._shouldYield
    yieldValue = aether._shouldYield
    aether._shouldYield = false
    frame_stack[1].didYield = true if frame_stack[1].type is 'loop'
    return true

  return false
2 Likes

Thanks Everyone, and I have one more question. How does @JWH changes the shield at the correct second wasting my mana and fooling my code. I tried using the opponent shield method I use for the fireball and arrow method. but it doesn’t work. Please help me.

P.S If you have an suggestions for me PLEASE post them I am literally desperate for help…
and one more thing what is a good level to be in (in regular codecombat)

Thanks A lot,
goutham123

2 Likes

Hello! Thanks for this arena! It’s interesting and cool. Although I would like to receive some help on Mages Might. I can’t see opponent’s mana. Please, tell me where am I wrong.
Here is a part of my code:

enFire = 1
enWater = 1
enEarth = 1
def findBall():
    enHero = hero.getEnemyHero()
    fire = enHero.fire
    water = enHero.water
    earth = enHero.earth
    if enHero: 
        if enFire-fire > 1:
            return "water"
        elif enWater-water > 1:
            return "earth"
        elif enEarth-earth > 1:
            return "fire"
        else:
            return "no"
    global enFire
    enFire = fire
    global enWater
    enWater = water
    global enEarth
    enEarth = earth

while True:
    enHero = hero.getEnemyHero()
    hero.chooseItem = chooseMana    
    ball = findBall()
    if not ball == "no":
        if hero.water >= 3 and ball == "water" :
            hero.cast("water-shield")
        elif hero.earth >= 3 and ball == "earth":
            hero.cast("earth-shield")
        elif hero.fire >= 3 and ball == "fire":
            hero.cast("fire-shield")

:eyes:
Unfortunately I do not have much time (I say this quite often now) to play CodeCombat now, so do not wait me on the ladders.
Also, I would be glad if someone would tell me how to debug here. hero.say() does not work so it’s difficult. Another question: can you command collectors to move to the place I want them to go?
All help would be appreciated. :slight_smile:
I really like this arena and it reminds me Escort Duty. I like the idea of taking some chests/fruits or something like that and it would be great if there were more arenas as these.

2 Likes

@PeterPalov I am not an epic coder but I might be able to help you on the debug part. I was reading lots of mages might topic for help and I ran through someone with the same situation, and @nick said you could use console.log to do the debugging. I will try and find that topic, if I do I’ll send you the link.

glad to help,
goutham123

2 Likes

I know how to also send the collectors to a specific place, you have to go into the function which had count in it (I think it was a collector function). Then in the return you would have to type return {"x": x, "y": y} and it would go to that specific place.

glad to help,
goutham123

2 Likes

Your if enHero block always returns, regardless which part if it executes. Returning from a function skips the rest, which means everything below that if-statement is unreachable. The result is enFire, enWater, and enEarth are always 1.



can you command collectors to move to the place I want them to go?

As goutham123 said, you can assign a function to hero.chooseItem that returns a position. The collector the function was run for will seek out the fruit nearest to that position.

3 Likes

Hi Hydrobolic,
I would like help on some code.
In my “while True” loop, when I do
enemy = hero.getEnemyHero()
shield = enemy.getActiveShield()
My character just waits for the enemy to create a shield.
Can you help? Is there a way to fix this?

Welcome to the forum! This is a family-friendly place where coders can share bugs, ask for help on any CodeCombat level (don’t forget to post your code correctly), or just hang out with other coders. But before you proceed, please check out our guidelines: this topic.
Have a great time! :partying_face:

Your code shouldn’t block on finding the enemy’s shield, so you should be able to proceed with normal attack code regardless of whether the enemy has a shield or not. I’m not quite sure what your question is. Perhaps on how to structure your program?

enemy = hero.getEnemyHero()

while True:
  shield = enemy.getActiveShield()

  if shield:
    pass # The enemy has a shield! Let's counter it!

  else:
    pass # The enemy doesn't have a shield, so let's attack normally.
2 Likes

Okay, thanks!
I did this and I think it works.
Here’s a snippet:

while True:
    if shield and shield.mana == "fire" and not hero.canCast("water-ball"):
        while shield and shield.mana == "fire" and not hero.canCast("water-ball"):
            hero.cast("water-arrow")
    elif shield and shield.mana == "water" and not hero.canCast("earth-ball"):
        while shield and shield.mana == "water" and not hero.canCast("earth-ball"):
            hero.cast("earth-arrow")
    elif shield and shield.mana == "earth" and not hero.canCast("fire-ball"):
        while shield and shield.mana == "earth" and not hero.canCast("fire-ball"):
            hero.cast("fire-arrow")

I have a question: how long is a tick?

A tick is a tenth of a second. You can always while True: print(hero.time) and inspect it in the console.

I believe the three if statements in your snippet are not necessary, as each while-loop will be skipped if its condition is not met. Also, make sure you call enemy.getActiveShield() again as necessary. Your reference to shield won’t automatically update.

1 Like

I am trying to block attacks this way.

oldfire = enemy.fire
oldwater = enemy.water
oldearth = enemy.earth
i = 0
while i<5:
    i+=1
if oldfire>enemy.fire+5:
    hero.cast("water-shield")
if oldwater>enemy.water+5:
    hero.cast("earth-shield")
if oldearth>enemy.earth+5:
    hero.cast("fire-sheild")

It is not working. Can you help?
This is in my while loop.