You have to print thrust each turn so that the lander lands without crashing.
I need help with level 1
Ok. I still can’t understand what I have to do:neutral_face:… Can someone please give me full code about this…? in C++…?
On Lev 1 please…
Why not the full code for Nintendo?
Hi there, is there a single algorithm that is successful in all levels, or is each level coded differently?
You have to find a generic solution to adapt every situation! You have variables that give you information, you compile them and with them you determine which action you have to do!
Grand, I think I kind of cheated by using trial and error method…
I know I want to go left/right a bit then down a bit etc and then use some additional thrust to ensure a soft landing.
I used a counter with some event triggers by using multiple if-else-if statements
if count < x seconds apply ? thrust and ? rotate
else if count < x+10 seconds apply…etc etc
Tweaking the times and outputs allows for a nice soft landing (eventually)!
My next steps are to look at a more automated approach potentially using some equations of motion.
Still hardcoding the co-ordinates of the landing site for simplicity for now.
i think i will subdivide controlling horizontal movement in one phase and then vertical movement in the next and alternate (perhaps ~4 timesteps each noting the game does not just go from power 0->4 in one step but 0,1,2,3,4.) using small rotations.
Testing my recollection of GCSE/A level maths/physics.
Very interesting puzzle and is more addictive than sugar!
Can the game inputs be modified to have a user defined level?
My current state step code looks like this:
thr = radians(thetan) co = cos(thr) si = -sin(thr) vxn = vx+powern*si vyn = vy+powern*co+g #g is negative xn = x+vxn#vx yn = y+vyn#vy fueln = fuel-powern
In the game loop, I compare the projected state to the one I get from CodinGame, like this:
errors = tuple(int(round(root[i]))-int(env_root[i]) for i in range(len(root)))
and (only) the positions deviate over time.
Rounding position at the end of the step has little to no impact. Rounding velocity before or after the position update worsens the error.
What am I not getting?
Finally I’ve solved it, all 3 episodes. Man, what a relieve. It only took me about 6 months with an year break in the middle. Using C++. I had to go through almost all physics learned in school from this site:
I was determined to solve the task using Genetic Algorithm. I had to go through many tutorials, such as:
But I still couldn’t get my algorithm to converge. I enrolled in online course for the Genetic Algorithm:
Which took me about a month to complete to get deeper knowledge in the field.
I cannot imagine writing such an algorithm without visual debugging.
I had very difficult time coming up with good evaluation function also, used above 10 of those.
After above 100 iterations of my code my algorithm started to converge, this was AWESOME. But it was very slow…
I’ve started to analyze my solution using Visual Studio native profiler. And I’ve found out that I’m using very much memory and started optimizing it. I couldn’t get very good results until it hit me, I could use only 2 populations the current and the next after each crossover next becomes current and current is overwritten with next. And for this I had to rewrite again the whole solution.
The thoughessest puzzle of all 3 episodes was “Initial speed, wrong side” There I have some convergence to a local maximum and my algorithm needed above 400 populations to escape that maximum.
The puzzle for which biggest optimizations were needed, to get in the time frame, was “Cave, wrong side”. It passed for around 150 populations, but was slow
And also the biggest optimization was to reduce the use of STL to minimum.
After this optimizations I still didn’t get in time for all solutions until I found that I use too few genes in each chromosome. And BOOOOOM the tests and the submit passed
After that I took it further to pass the “Stalagtite” test form the tech.io tutorial. There 200 chromosomes were needed in each population and above 1000 populations.
I feel very proud of myself, to see all efforts paid off is one of the best feeling ever. The main lesson I learned from this: “Keep it simple” no need to overengineere something, no need of all C++ fancy syntax, at the end I solved the task using plain old C++. Never stop beliving
Congrats! Awesome achievement. I’m impressed by your perseverance. Want to write about it in the blog?
Sure What’s the procedure?
it’s simple, you write a draft and I help you publish it.
more details here: https://www.codingame.com/playgrounds/40701/contribute---help/articles
Can someone help me figure out how to determine the coordinates for the landing pad…?
I got it! Thanks!!
Finally solved last episode as well, using sklearn.optimize in Python3 to minimizing a scoring function
The scoring function takes into account:
- Distance from landing pad (taking wall into consideration)
- Speed, and angle of arrival
- Used fuel.
Still not super happy with my solution: converging is so slow I can’t run it in on Coding Game limit of 100ms (writing the simulator in Python might not have been the best idea).
I ended up running it on my computer, and copy pasting the list of moves into the editor (which oddly works, because the terrain must be the same between tests and validation).
The breakthough between “this is never converging to anything useful” and “hey this might work” was when updating the distance calculation from a “straight line” to a “let’s not ignore the walls” in the scoring function
It made everything converge much much faster (cf screenshot).
Where did you get the last level you’are showing on the screenshots?
I only had two of them in the “very hard” training.
I did not find anything on tech.io.
Did you build it by hand to test your solution?
These are the coordinates for the test:
"Stalagtite upward start": [ "15", "0 2500", "100 200", "500 150", "1000 2000", "2000 2000", // Landing area "2010 1500", "2200 800", "2500 200", "6899 300", "6999 2500", "4100 2600", "4200 1000", "3500 800", "3100 1100", "3400 2900", // Lander config "6500 1300 0 50 1750 0 0" ]
This is the tech.io tutorial:
This is their github repository:
I wrote in more detail for my solution in a blog post:
Level 1, Java - I’m trying to figure out how the actual Y is computed. The vertical speed in each round is the speed from previous round minus gravity (3.711) plus power (that’s correct, read numbers match). With this I would expect that Y is the Y from the previous round plus speed. But that’s somehow wrong.
For example, with no power, the speed after the first round is -3.711 (rounded to -4, matches the read value). And I expect Y to be 2496.289 (2500 + (-3.711)) and rounded to 2496. But the read value is 2498. What am I missing?
I have tried to divide the speed by 2, subtract 1/(round number) and few other adjustments, but my computations never match the Y given by the line reading.
The 3.711 is acceleration. At the start of the turn you are at 0, at the end you are at -3.711. During the turn you slowly change from one speed to the other. Your speed for the turn will be velocity + (acceleration/2), which gives 2500 + (0 + (-3.711/2)) = 2498.1445. Unfortunately the server only sends you the integer part so if you need an accurate position / velocity you need to track it yourself and ignore the server.
Awesome series. But why so few tests? I substituted my primitive inefficient algorithm from the 2nd to the 3rd episode, and received a 250XP freebie for passing the “half” of tests without any complicated mathematics