Sarven Treasure teleporters do not work

If you try to use to escape from the ogers using a teleporter, as suggested in the description, you get bashed:
Stepping on a transporter puts your hero to the opposite transporter, but then the hero immediately starts to run back to the start transporter, passing the ogers and getting damage.
This is probably because the transporters do not handle the moveXY correctly: just putting the hero to another location does not finish the method.

To demonstrate I used the following example code:


waitPositions = [[12, 45], [65, 24]]
porters = [[5, 49], [76, 19]]
counter = 0
while True:
item = hero.findNearestItem()
enemy = hero.findNearestEnemy()
hero.say(“waiting”)
#move to the wait position
pos = waitPositions[counter]
hero.moveXY(pos[0], pos[1])
porter = porters[counter]
#wait for enemy getting near
while enemy and hero.distanceTo(enemy) > 20:
enemy = hero.findNearestEnemy()
if enemy:
# move to the porter
hero.say(hero.distanceTo(enemy))
counter = (counter + 1) % 2
hero.moveXY(porter[0], porter[1])


Welcome to the forum!! Could you please format your code with the </> button

one question though is this your code because you learn this in the mountains(unless your returning to this level) and its because you put

that your hero keeps moving back to the first teleporter.

Eric_Tang: you are right: I just proceeded and learned that ‘move’ behaves differently .
So, using ‘move’ rather than ‘moveXY’ works perfectly:

def Pos(vect):
    return {"x": vect[0], "y": vect[1]}

waitPositions =  [[12, 45], [69, 21]] 
porters = [[5, 49], [76, 19]] 
counter = 0    
while True:
    waitPos = waitPositions[counter]
    hero.moveXY(waitPos[0], waitPos[1])
    enemy = hero.findNearestEnemy()
    while enemy and hero.distanceTo(enemy) > 15:
        hero.say(hero.distanceTo(enemy))
        enemy = hero.findNearestEnemy()
    portPos = Pos(porters[counter])
    while hero.distanceTo(portPos) < 10:
        hero.move(portPos)
    hero.say("ported") 
    counter += 1
    if counter == 2:
        counter = 0

So, I am very sorry to have reported this as a bug.
But I guess, players at the level this challenge is presented are not supposed to know about the different behaviour of ‘move’.
Maybe at least a hint in the description of the challenge could be an improvement…?

Teleporting works but I now get a serios problem with iterating lists.
The following code once passed and yielded me another level in ‘Sarven Treasure’, but when running locally I mostly get “your code is really slow or has and endless loop”.

And yes: it is incredibly slow! If more than 5 enemies are present an it iterates through hero.findEnemies() it halts noticeably, after some time ending with the message above.
I also had this issue when iterating through the coins list.
I am sure that there is no endless loop in my code as I use only ‘for’ loops and the main loop should always perform a ‘move’.

Btw.: is there any possibility to debug my code? I found some hints to a ‘debug()’ feature but that does not work for me.
File output using the common Python ‘open()’ does not work either: this method seems not to be known or is suppressed at purpose.

Here my code, once having passed the ‘sent’ run:

def DistBetweenObjects(obj1, obj2):
    dx = obj2.pos.x - obj1.pos.x
    dy = obj2.pos.y - obj1.pos.y
    return Math.sqrt(dx**2 + dy**2)
    
def DistOfObjectToPos(obj, pos):
    dx = obj.pos.x - pos.x
    dy = obj.pos.y - pos.y
    return Math.sqrt(dx**2 + dy**2)    

def FindNearestPorter(target, porters):
    minDist = 9999
    nearestPorter = None
    for porter in porters:
        dist = DistOfObjectToPos(target, porter)
        if dist < minDist:
            minDist = dist
            nearestPorter = porter
    return nearestPorter
    
# check if distance of any enemy to coin is smaller than my distance to coin
def IsSafeDistToEnemies(coin, myDistToCoin):
    enemies = hero.findEnemies()
    if len(enemies) == 0:
        return True
    for enemy in enemies:
        if DistBetweenObjects(coin, enemy) < myDistToCoin + 5:
            return False
    return True    
    
# check if distance of coin to the porter next to it 
# is bigger than any enemies distance to that porter    
def IsSafeDistToPorter(coin, porters):
    enemies = hero.findEnemies()
    if len(enemies) == 0:
        return True
    #porter next to the coin:        
    nextPorter = FindNearestPorter(coin, porters)
    coinDistToNextPorter = DistOfObjectToPos(coin, nextPorter)
    for enemy in hero.findEnemies():
        enemyDistToNextPorter = DistOfObjectToPos(enemy, nextPorter)
        if enemyDistToNextPorter < coinDistToNextPorter + 5:
            return False
    return True
    
def FindBestCoin(porters):
    maxWeight = 0
    bestCoin = None
    coins = hero.findByType("coin")
    for coin in coins:
        myDistToCoin = hero.distanceTo(coin)
        weight = coin.value / myDistToCoin
        if weight < maxWeight:
            continue
        # check if distance of any enemy to coin is smaller than my distance to coin
        if not IsSafeDistToEnemies(coin, myDistToCoin):
            continue
        # check if distance of coin to the porter next to it 
        # is bigger than any enemies distance to that porter    
        if not IsSafeDistToPorter(coin, porters):
            continue
        bestCoin = coin
        maxWeight = weight
    return bestCoin

porters = [{'x': 5, 'y': 49}, {'x': 5, 'y': 19}, {'x': 76, 'y': 19}, {'x': 76, 'y': 51}] 
counter = 0 
jumpTime = -1
# measured around 7 to 7.3, not official
jumpCooldown = 8
while True:
    enemy = hero.findNearestEnemy()
    missiles = hero.findEnemyMissiles()
    missile = hero.findNearest(missiles)
    
    coin = None
    if not enemy or hero.distanceTo(enemy.pos) > 10:
        coin = FindBestCoin(porters)
    if coin:
        hero.move(coin.pos)
    else:
        nextPorterToMe = hero.findNearest(porters)
        hero.move(nextPorterToMe)
        hero.move(nextPorterToMe)

Thanks for helping

Whoa, this is some pretty complex code though I might be wrong I think you don’t use all your functions.

Oh, you’re here, nice :slight_smile:
I am using all functions and I also tried to simplify as much as possible. However there are indeed some unused variables in the main loop relating to ‘jump’ and ‘missiles’ but that shouldn’t matter.
I really tried hard to get behind the problem and am at the end of my possibilities (note that I’m not a student but a professional software developer, mainly using C# and C up to now. But I’m new to Python and try this also for my son. Apart from the lagging problem here, ‘CodeCombat’ is actually great fun and educationally well made!)
Moreover, I think the challenge here (and others on this level) require complex code :wink:

And it will get more complex if missiles get involved which is the case at the next level: but that’s the point where it comes to an end for me because iterating through the missiles list (and doing some calculations) seems to be finally too much…

1 Like

This can sometimes be caused by the sheer amount of enemy units in a level rather than just your code. What stage are you on? If you’re on a high one like 6, 7+ then the problem could be that the game just can’t load all the troops.
I often find reloading the page works, even if there was an infinite loop with the code you ran during testing the level.
It could still be a problem with your code, so if that doesn’t work, I’ll copy it into my level and see if I can get it to work…
Danny

1 Like

Yes, infinite loop is often because of many ogres. I have quite big scores everywhere and I can’t submit them (because of infinite loop), even I have success. Sometimes, it can be solved by this:

  1. When you see the infinite loop error, and you are sure that you will have success after clicking “submit”, click submit.
  2. Then, you leave the tab open, go to drink tea and eat cookies). And then, after a couple of hours, or hopefully earlier the level loads and you get your money and XP.

Thank you very much for your responses :slight_smile:
It is reassuring that I am not the only one experiencing this.
On the other hand it should basically not be a big deal for a Python script to iterate through say 30 coins and 10 ogres (not really doing complicated calculations in there) once per let’s say 100ms but of course I don’t know how the underlying machine translates it…

I will think about some workaround and let you know if I find any approach.

I think in this case there are some flaws in the logic of the program. It gives me also “your code is really slow or has and endless loop”.
So I only simplified it:

1	porters = [{'x': 5, 'y': 49}, {'x': 5, 'y': 19}, {'x': 76, 'y': 19}, {'x': 76, 'y': 51}] 
2	while True:
3	    enemy = hero.findNearestEnemy()
4	    coin = hero.findNearestItem()
5	    if not enemy or enemy.distanceTo(coin.pos) > hero.distanceTo(coin.pos):
6	        hero.move(coin.pos)
7	    else:
8	        nextPorterToMe = hero.findNearest(porters)
9	        hero.move(nextPorterToMe)

Can you explain what exactly you want to achieve with FindBestCoin(porters) / porters is a global variable so no need to put it as function parameter. /
P.S. I have never been a software developer, only helping my son :slight_smile:

@xython:
The task of the challenge is to collect a certain value of coins in a given time without dying.
When you step on a ‘porter’ position, you will be immediately ported to the opposite ‘porter’ and that’s the way to escape from the enemies, heading for you in a very densely packed group.
Attacking them will probably of no use, so I don’t even try and use a hero with low health but relativly high speed (‘Amara’).
It is essential that collecting coins is done in a very safe way, i.e.

  • do not try for a coin if any(!) enemy is closer to it than you are
  • stay closer to the porter next to you as any(!) enemy - this has to be applied also for the coin you’re heading for

That’s the purpose of ‘IsSafeDistToEnemies()’ and ‘IsSafeDistToPorter()’ which are both are essential components of FindBestCoin().
And they both iterate through a list of all enemies. Maybe there are ways to optimize this by doing a pre-selection of the enemies, but this will make the code really complicated and, above all, I would expect that those iterations should be possible in an adequate time (of course supposed there are no real bugs in the code).
I started with a simple code, similar to the one you proposed, but you won’t reach the goal that way, at least for higher levels.
Btw. you are right about ‘porters’ being global - this has just not been in my focus…

Update:
it’s running now, more or less fluently (with Chrome more, with Firefox less, but … yeah).
I did not change anything to the code posted here apart from minor renaming, which should really not matter.
So - it’s magic…
Currently I have another annoying problem with the other ‘Sarvan’ challenge because, at a certain point, it apparently comes to a race condition where the hero shoots an enemy that is shot by a turret in parallel…
But maybe it’s only a broken server? Or even a new security feature??
(one of the debug messages is

DevTools failed to load SourceMap: Could not parse content for https://codecombat.com/play/level/treema.css.map: Unexpected token < in JSON at position 0

followed by

Access to fetch at 'https://codecombat.dexecure.net/play/level/treema.css.map' from origin 'https://codecombat.com' has been blocked by CORS policy: Request header field accept is not allowed by Access-Control-Allow-Headers in preflight response.

So yeah, it’s magic… but anyway:
If you really want to help your son, tell him to always save a text copy of his code before running it, at least if it is a more sophisticated challenge.
Because, what is REALLY ANNOYING is, that, if you transmit your code and it comes to a hang-up, your code may be completely deleted if you finally manage to rerun the challenge by either clicking ‘reset level’ or ‘comment out my code’ even if you try hours later - it seems to make no difference.
And there’s no way to restore it then.
That is really, really bad - tears and smashed keyboards guaranteed.

Ok, I have to stop, that’s enough for now…
Anyway, apart from all these technical issues, I still like CodeCombat - it has the perfect mix of simple introductions to a topic and, in the right measure, increased and ever more advanced challenges. <3

Ehm, “reset level” really delets the whole code, but “commenting out” only puts a couple of lines at the top of the code editor, and you can save it.
But yes, copying backup of the code somewhere else is a good practice and I do it from time to time.

If your code comes to a hang-up restart the level from the URL bar with another language:

https://codecombat.com/play/level/sarven-treasure?codeLanguage=javascript

is there any possibility to debug my code? do it in the browser Web Console image
for quick debug message use

pet.debug("debug message")

image never hero.say(“talking takes time”)
The distance between two objects can be found using Vector library:

enemyDistToNextPorter < coinDistToNextPorter # same as
enemy.pos.distance(porter.pos) < coin.pos.distance(porter.pos)

Officially you need Programmatication V but you don’t really have to own any book to use the language possibilities. How to see what is available?
Go to some Leader Board and find a person with that book:


select 7 GodieBoy watch
Go to Vector
image
and then

See Listen well, brothers and sisters, for I can teach you the power of the VECTOR (Nope, not the guy from Despicable Me…)
I think this isn’t the place for a programmer to learn Python because all code is “translated” to java script. You can teach your son python if he likes it more and write your code in java script ( it’s closer to C, C#) and you will need only to format it the python way.
For example see from same leader board image the array methods

You can safely use all of them in python code. The corresponding python table is so limited maybe
not to confuse the python learners:
image
And so on…

I think your code is slow because Code Combat strongly dislikes the nested loops…

2 Likes

Thank you very very much - this is extremely helpful :slight_smile: :slight_smile:
Have a happy new year !

For interested future readers who made it up to here: logging via Web Console works perfectly for me using Chrome: albeit I cannot use ‘debug()’, ‘console.log()’ works.
It did not work for me using Firefox but I tried this only once. I did not try other browsers.

1 Like

Thank you for your reply.
Maybe I did something wrong and clicked ‘reset’ rather than ‘comment out’, however I am pretty sure I didn’t - I will try again next time (hopefully not so soon)
And sorry for my irritated last post - it was just one of those hours where nothing worked…

1 Like