Help on Mages Might!

Is it possible to use the opposite mana on the shield your opponent is using.

I know its possible with hero.getEnemyHero() but the problem is I don’t understand how these kinds of code work. I already know that it returns a copy of my hero object which it could be used to get your enemy’s state, I am wondering how I can use this to actually use the state of the enemy.

Can anyone explain?

1 Like

Your own hero has all the methods listed down the center of the screen. The opponent, returned by hero.getEnemyHero() has all the same methods, but CodeCombat will only let you call some of them. hero.getActiveShield() is one of them.

Example:

opponent = hero.getEnemyHero()
shield = opponent.getActiveShield()
# Do something with shield.mana, which is one of "fire", "earth", "water"

For countering, you want to send the element the enemy shield type is weak against.

affinities = {
  "fire":  {"weak": "water", "strong": "earth"},
  "water": {"weak": "earth", "strong": "fire" },
  "earth": {"weak": "fire",  "strong": "water"},
}
2 Likes

I am getting a error saying that
Screenshot 2021-06-14 130747
can you please help me

Cannot read property 'mana' of null

In the same way that hero.attack(hero.findNearestEnemy()) does not always work in a normal level (what if there is no enemy at all?), hero.getActiveShield().mana will not work if the hero has no shield. You need to check for the existence of the shield first:

shield = hero.getActiveShield()
if shield and shield.mana == "fire":
  pass # Your code here
1 Like

Thanks @Hydrobolic, going to try that out

Umm @Hydrobolic, I have one last question before I venture into fighting other people in mages’ might on my own. Is there anyway I can check the incoming projectiles from the enemy and act accordingly or is there anyway I know what spells the enemy casts??

With Great Thanks,
goutham123

You are not able to directly read what they enemy is casting or read what projectiles are currently traveling, but you are able to make educated guesses on what the opponent has cast by watching their current mana and seeing if it changes. Say, if the opponent’s fire jumps down by 15, you know they just cast a fire ball and can prepare a shield against it.

You are able to read if the opponent is building a collector or not by looking at opponent.action.

Keep in mind that you won’t be able to perfectly predict what the opponent is casting as the only times you can run code are when you yourself aren’t casting or building and when a collector chooses its next item. If you are summoning a spell or building a collector, you are mostly blind to the opponent’s actions.

2 Likes

@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.

1 Like

@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