Fantastic Bits - Feedback & Strategy

I really liked the idea of this game, so first of all, thanks for bringing out something like this. It’s such a shame that I couldnt’t find any time to participate, finished at 793, which is by far the worst place I’ve ever been since I’ve started doing CG contest two years ago.

My basic strategy which I’ve implemented only in four hours was something like:

  • move towards the closest snaffle
  • after catching a snaffle, throw it towards the opponent’s goal
  • after throwing a snaffle, cast the accelerating spell on it
  • check the velocity of each snaffle in each frame, and if one got accelerated by a spell and is heading towards my goal, cast freeze on it

Although I prefer grid based games, I look forward to challenges like this in the future.

1 Like

This contest was really funny, but it was really hard to simulate all elements and in addition we didn’t know the mana of the opponent so it was hard to know if he can cast or not a spell, I had so many bugs. I just finished to fix them the last afternoon of the contest.
So for my strategy I simulated the ennemy with basic heuristic like targeting the closest snaffle and if holds one then he casts in the direction of the center of my goal. for my solution I simulate during 95ms with a MC at depth 3 with 12 angles and just flippendo spell. And finally I pick my best solution using this criterias:

  1. minimizing the distance between each snaffles and the opponent goal
  2. minimizing the distance between me and the closest snaffle
  3. If I can score a snaffle then I give a big bonus and a malus if ennemy scores

I was 160 in gold at 1 hour of the end of the contest without flippendo and with 360 angles (around 270 in total) then I submitted at 5 minutes of the end a best solution using flippendo and 12 angles and I was promoted in legend and finished 29th.

2 Likes

I think everybody liked the challenge, It was interesting and very fun. Easy to enter (nearest snaffle and throw to goal) but hard to master (full game simulation).
I won’t give any type of strategy because it’s not worth it, I ended 100 with a naive bot and a horrible spaghetti code. Don’t do that, kids!

Pros:
Fun, more appealing than CSB.
Good performance of servers.
Multiple solutions were possible, from simple conditionals to evolutionary algorithms.
Nice graphics and effects.
Cons:
Hard to get some game vars: magic, spells being used, score.
Impossible to get some vars: Enemy magic.
The huge gap between GA AIs and the rest.
Many reusable code from poker chip race and CSB, led to a natural advantage to veterans.
Time restrictions.
Huge changes on rankings between submits, like more than 100 positions. Maybe it’s a matter of waiting enough time to stabilize, but given the short span time this is a problem. Seems like the first 10 matches weight a lot.
Many doubts from the statement, and rules are all scattered on the description. I prefer an advanced section with pseudocode and less chit chat that in the end is not so clear. Like magic, it says you get 1 point but it’s not clear when on the turn (before actions, after?). Pseudocode doesn’t have room for natural languages imprecisions. But maybe this is intended as real life problems.
Sometimes the whole page get almost blocked in chrome, had to restart chrome. Problems with, pause/play/rewind with replays on leaderboard.

My cons are not criticism but points to review, for future improvements.
Keep the good work guys.

1 Like

My Feedback as a 1st time competitor:

  • Was a very interesting game with some challenging problems to get your head around
  • The visualisation of the game was great and often enjoyable to watch a battle
  • The fellow competitors were awesome, very helpful and a real nice community :slight_smile: <3
  • Liked the livestream :slight_smile:
  • I didn’t like the fact that spells took 1 frame to take effect. It made planning them more complex than it would otherwise be.
  • It would definitely have been nice if the game supplied more information about the current state
  • Had lots of issues with the site timing out/becoming unresponsive on firefox (seemed better on chrome).

Very much looking forward to the next competition, and to learn about the (many) things I did wrong :slight_smile:
Keep up the good work guys!

3 Likes

Feedback from another first time competitor. I made lower-half gold.

  • I enjoyed it a lot. The visual aspect made it fun to play
  • I had to brush up on a lot of math I haven’t seen in 20 years or so (edu +1)
  • I am a programmer by trade, but not a game programmer. It was interesting to see how game mechanics worked (edu +2)
  • I was blown away by the CG interface and game play. When I signed up, I didn’t expect anything this cool.
  • I intentionally chose a language that I don’t normally use at work. It was a great place to brush up and learn about new language features that weren’t there before (edu +3)

The most difficult part for me was estimating locations of objects into the future. The vector part I got easy enough, but how to make it all work together I never totally got correct (although I had a pretty good estimation). I never really got a good goal keeping algorithm, so I kept getting beat on the last snaffle. I need to make more use of the chats and such (still figuring some of that out as a GG newbie).

Overall, it was incredibly enjoyable and I learned a lot, which was my goal. I would do another one for sure.

4 Likes

Hey,

I haven’t participated in a CG contest for a while, and decided to give it a shot. Well, lo and behold, after some 16 hours I had the 1st global bot written in Python3.

My decision-tree based bot had some nice heuristics and trig calculations to do projections (check for throw collisions). I think the main idea which got me so high was the fact, that I started doing flipendo shots at y coordinates -3500, 10500, -10500 and -14000. My observation being, that you can essentially treat a shot which bounces off the wall the same, as the shot for the goal at y: -3500/10500. And the same for multiple bounces. The bot in the end ranked 22nd Legend, which given the complexity of bots in similar positions I’m very pleased with.

I also have a full sim implementation in C++, which I didn’t manage to take advantage of due to shortage of time over the week. What with work and pubs and all. I’ll start with a simulation next time.

+:

  • A complex and really fun sim based game.
  • Nice animations.
  • Physics/trig!

-:

  • Random t-shirts
  • Non-full input (really, don’t do this again please)
  • The 7 extra days allowed simulation people to overtake my heuristics :smiley:
1 Like

Very frustating contest beacause of nearly random ranking of my IA. A difference of 200 to 300 places on the gold league between two submits of the same code. Impossible to test enhancements in these conditions.
The submission need more matches to be more stable.

But an interesting game with nice animations.

These simple heuristics allow me to rank 16th in gold league :

  1. If I carry a snaffle, throw it to the goal
  2. If I have a snaffle in front of me in the goal direction and enough mana : flipendo
  3. If I have enough mana : Accio on a snaffle behind me.
  4. If a snaffle is moving to my own goal, petrificius it
  5. Move to the nearest snaffle
4 Likes

Hi everybody,

Here is my approach in this great contest. This was my 10th contest, and I knew the short time allowed, one week, would not permit to try something new. Multi contests are made for that.

So I didn’t focus on implementing a complete simulator. I did that in the Accountant challenge, and passed 3 days to have it working. So I used my CB strategy because I worked many weeks on this multiplayer game, and I found that FB was similar on many points : free map, multi agent, and a lot of features and possibilities.

So, on CB, I knew that the main feature was how to assign each Buster on each Ghost. It is very important, because the high strategy level of the game follows a logic which is far away from taking the next ghost at the lower distance…

In FB, it is the same. You got two wizard, and many snaffles, and the best snaffle to chose will not always be the nearest, because of the many possible configurations of the game :

  • Do I win ?
  • Do I lose ?
  • How many points do I need to win ?
  • How many points does my opponent need to win ?
  • Is there sufficient snaffle near opposite camp to win ?
  • Those snaffle are they all in front of my wizards or behind them ?
  • Is there sufficient snaffle near my camp to let the opponent win ?

Gold League

By the way, the nearest snaffle rule led me in Gold league, and only there I began to think on the assignment problem. No need to say that, to reach Gold league, spells were very important too. I think that all those spell situations were in my code since Silver league :

  • Flipendo when snaffle is in alignment on goal
  • Flipendo if a snaffle is near my camp (and good orientation too)
  • Accio to capture an assigned snaffle if it is in rear
  • Accio to protect my camp if a snaffle is to near
  • Petrificus to Stop snaffle which is running to my camp
  • Petriricus to Stop snaffle which is running fast to my camp
  • Petrificus to prevent an opponent wizard to catch a snaffle
  • Petrificus to make an opponent wizard miss his catching
  • Petriricus to react an opponent throw
  • Accio to react an opponent throw

I ignored Obliviate which I found not very valuable in the game. I discussed this point with Magus, and the only positive thing he found would have been to disturb the opponent simulation.

To give priorities to some spells, I implemented a reserve of mana to use it only in emergency. So some spells could use this mana and others could not use it. Prioritizing some spells avoids the lack of mana when you need it the more.

So once in Gold League, the main purpose was to acceed to Legend…

To do that, I specialized my wizards in two kinds : defenders and attackers :

  • The defender will search snaffles which are nearest from my base,
  • and the attacker will search snaffles… nearest from him (the naive logic is good for attack ;).

An other thing I found very important was not to lose a snaffle, sadly because you are shooting in the goal and an opponent wizard or a Bludger is next ahead. So I implemented a simple test :

  • Is there an opponent wizard ahead ?
  • Is there a Bludger ahead ?
  • Is there one of them at 45° or -45°
  • Is there one at North ? at South ?

But what to do if the answer is yes ? In this case, I decided to let my future simulator to decide, but for now (I’m still in Gold), try some interesting things in function of the situation :

  • Throw snaffle up, down (mainly when next to my camp)
  • Throw snaffle 45° of -45°
  • Moving 45° or moving -45° with the snaffle with me. This is made by moving with a thrust of 100 : the snaffle stay in the wizard circle. It should work up to 130 but I’m not sure (? 130 + 130 + 130 = 390 < 400)

This last feature is very interesting, because when a wizard keeps his snaffle in his radius, the opponent cannot get it without casting a spell. It is a very important point of the strategy : If you don’t loose your snaffles, the opponent would use many spells to get them.

But how to decide if my wizard has to keep his snaffle. Well, the fact is that many times, when you shoot in the direction of the goal, your snaffle doesn’t go very far, just because your wizard is going on the other way. So here is the point. If the speed of the wizard is not enough to throw the snaffle with a sufficient speed, so you can keep it. My test was here on a wizard speed of 100 on the X axe to the opponent side (writing that, I’m just now thinking about a more generic direction which could have solved some many other situations…)

Here is a replay from Gold league to show the game experience of this feature : https://www.codingame.com/replay/161493034

So, when Legend league opened, I was in the subway. On my phone I found me 98th in Gold… after the Legend openning !!! I tried out an IDE match against the Gold Boss to find out how it was possible and saw that the boss had a basic strategy but with one attacker and one defender ! Ho ! My code can do that too ! But for now, it had 2 attackers and always try to dodge (keep snaffle while go around opponent). So I just had to change all my parameters.

Still in subway, I assigned 1 attacker and 1 defender, saying them to dodge only if I lose the game (negative difference between my score and the opponent score). The reason is, in Gold legend, many players had very offensive tactics and speed attack is generally better against them, but on top of the ranking, my dodge strategy would be better… The dodge condition would permit to have two game styles within the same unique submit.

I waited to take on the bus to submit, survey the progression all the way, and when I arrived at my destination, I was in Legend league in top 50. My best travel in a bus on a friday evening !

Legend League

But the Legend league was another story. My Gold version was well placed, but while 2 days, I had worked on a new version, with a new assignment function, the beginning of a simulator implementation, and with a lot of new features. I didn’t push it in Gold league because I waited Legend to avoid the risk of a regression in Gold (I have made this mistake too much in league contests). That was my best idea on this contest, because the regression happened… but in Legend.

It was like hell with incomprehensible bugs I spent more than 1 day to find out : Timeouts, Segmentation fault, memory overflow (the worst, when your variables are overflowed by your stack you know ? Oh sorry, stack overflow is not only a great web site, my code is C code)…

On the last day (sunday), my Legend code was ready with my new assignment function and my “half” simulation engine.

Assignment function

Here my wizard can be posted on 4 different roles. Each role can be redesigned so I could have add other roles if I needed, but I had not enough time for that :

  • Defender : As in my Gold code, find the snaffle with a good combination with nearest from my camp, nearest from enemy, nearest from me
  • Attacker : As in my Gold code, prefer the nearest from me, but nearest the opponent camp too
  • Chaser : Only find nearest from me, but also a little nearest from enemy
  • Guardian : The guardian is mainly assigned when one snaffle only is left in game, so he can help the other wizard, but he can also play a role in some situations. The guardian has to intercept enemies and protect your camp.
  • Isolator : I didn’t implement it, but the idea is to keep snaffles with you in a corner, when the game is nearly ended and the win will be for you (a trick from CB)

I need to say that all distances are calculated on future rounds (t + 1 or more) to anticipate all movements and positions. For snaffle, the evaluated position is an intercept factor between his actual position and the final approximated position.

So now, how to assign your 2 wizards on a role. There, the game is evaluated (win, lose, points left, snaffles positions, enemy positions, …) and the result is the 2 roles you need in this situation. Then the assignment function calculates all possibilities (4 roles x 2 wizards x N snaffles) and returns the best one, principally with distances evaluation.

To catch his snaffle, then each wizard can :

  • Go to it, compensating all speeds with a simple logic : calculate the final position of the snaffle, apply the intercept factor, finally substract your speed on this target position (trigo doesn’t disagree too much :slight_smile: )
  • If the snaffle is on your back, and if mana allows it, casting an Accio spell can be a good thing, in situations where the game strategy is saying that catching this snaffle far away on your back is a good thing.
  • One of a feature coded in the last 2 hours was to kick opponent wizard if you compete vs him on the same snaffle. Simply go to the point between him and the snaffle in this case.
  • Another deadline one was to avoid bludgers, with a repulsive vector. But I think this vector was buggy and didn’t work well, or not at all…

Actions

When a snaffle is caught, you know it because of the state input. But because of the different choices we will have among actions, the condition here will be not only the state, but also the distance condition (< 400). With this information, you know that the snaffle is yours or not. Then :

  • Throw to the goal (if speed condition is OK)
  • If you are in the defense area (near your goal) throw up or throw down (You can throw to the opposite goal but be very sure of that)
  • If there are obstacles on the way, throw to other directions (here my simulator will take relay in the last hour of the contest)
  • If speed is not enough, go 45° north or 45° south, keeping the snaffle with me (dodging).

All those actions may be different if wizards are on a role or an other. I can regret the lack of time for trying more different combinations, principally the dodge one. Only guardians have it in my final submit.

Simulation

I read all interesting posts made on the CSB contest simulations. I know that it is the way to follow, but also that implemention of all the needed calculations is not a piece of cake. When Magus describes how he cuts the time axis in pieces to detect collisions beteen 2 time units, the first thing I’m saying to myself is “Wow, how all that can be possible… ?”

Actually, all my strategy is based on searching open space to throw my snaffles, so I didn’t need to calculate collisions for that. If collision occurs, so let it be and we’ll see. Nevertheless, I needed to know if my throws were secure to improve my chances of marking points. To do that, my simulation function will only calculate positions and bouncing against walls. If a collision is detected with the snaffle I threw, the simulation rejects this case and go to the next. Detection will simply be made with distance comparison after adding some margin to the radius of entities, when I don’t know exactly where it can be. The speed friction is also adapted because bludgers and wizards never let their thrust to zero.

With this kind of simulator, I could simulate 180 angles (-90 to 90) with a depth of 12 without any performance limit (near 15 to 25 ms). The good thing is that the simulation gives the exact final position of the snaffle I want to throw. The bad thing is I can’t be certain of the position of all others entities. So collisions may occur and I will not detect them.

With a complete simulator, I don’t think I would have change my high level strategy, but I could have simulate other angles (on my back), which would have permit to find improbable moves, to search bludger bouncing to accelerate, to use walls or other bouncing for marking more points, to improve the spell casting decisions, …

Yes ! Simulation is a great thing. I’ll wait the multiplayer game to give it a try :slight_smile:

Oh, finally, I ended this contest in 43th position.

This was a great challenge and I enjoyed it.
Thanks to all of you for this.

16 Likes

thanks for feedback, very interesting, especially the 45° move that is clever, and the subway story ^^.

EDIT : After seeing the Legend part, even more interesting :slight_smile: imho you did great in balancing creativity and efficiency !

1 Like

I really enjoyed it. Was able to use a lot of game physics from CSB, which was a leg up. I didn’t have time to try any GA etc but still managed to rank in the top 150 or so, which surprised me. It was a very very basic bot most of which was done on Sunday, and only a few minor tweaks during the week. I hate to admit, but almost everything I tried to make it a better competitor failed, and I wound up tweaking a few small parameters on just 4 basic rules.

  1. Throw any ball you’re holding toward the goal (try and work out nearest point in the goal, but don’t hit post).
  2. Flippendo anything in direct line to the goal, but not too far away.
  3. Accio anything behind you. But not too far away.
  4. Move toward the nearest snaffle.
    I borrowed some of the movement rules from CSB to try and improve steering. More than anything I think this helped my bot score well.
    I was really impressed at the way the GA bots were able to avoid the snaffles right at the start. I couldn’t reverse engineer that logic.
    Need to build a good sim and GA harness before the next one.

Really interesting observation that you were able to carry the snaffle at 130 thrust!

1 Like

Hi pin72,

I implemented 100 because it is always safe. The 130 value is only a theoric case because you have to take consideration of your speed and direction when you don’t hold the snaffle. On a straight line, at t+1, the snaffle will follow the wizard at his same speed (frictions are the same). So only your thrust make the difference. If thrust A is applied all the time on the same direction :

  • t : Wizard and his snaffle got same position and speed
  • t+1 : distance between Wizard and Snaffle = A
  • t+2 : distance = A + A * 0.75 = A * 1.75
  • t+3 : distance = A * 1.75 ^ 2 = A * 3.0625

At t+3, if distance < 400 the snaffle is caught again. So the theoric limit for thrust should be 400 / 3.0625 = 130.6 but I didn’t test it… (and in fact I’m not pretty sure of this calculations…)

[edit] this calculation was false.

After watching replays, it seems that the test for the distance < 400 is made on t+2 because, on t+3, the snaffle is moving to the center of the wizard. My calculation was false too, because you need to sum all distances. So the values would be :

  • t : distance 0
  • t+1 : distance = A
  • t+2 : distance = A (prec. dist.) + A (thrust) + A * 0.75 (speed) = A * 2.75
  • t+3 : snaffle moves to the wizard’s center if dist(t+2) < 400, but when is made this condition testing ?
  • before adding the last speed or thrust ?
  • before adding thrust ?
  • before adding speed ?

I think I will have to test to be sure… :astonished:

To develop another idea about following your snaffle, I even tested one more tactic, but I didn’t activate it because it was too difficult to manage :

The principle was to throw the snaffle with an adjusted force, just to be able to follow it with the max thrust 150 and then recatch it. The actions are in order : throw snaffle (190) + thrust (150) + thrust (150) + throw snaffle again (190). The speed is very good and the snaffle is always in your radius.

My purpose was for instance : when you throw the snaffle, it sometimes stops just before the goal and you have to reach it again to mark (generally 10 turns). If you had accompanied it a little more with a small throw aligned to your speed, you could have mark your point sooner (in 3 turns with chance) :slight_smile: .

So I’m pretty sure that this 190 thrust throw could be a good move to submit in a simulation engine. I’m curious to know if some top players used it in the contest…

1 Like

Great contest. Finished #123 in Legend. I started off by writing a simple if-then bot following the same pattern everyone else seemed to, just to get familiar with the game. Then I dusted off my PCR collision code and started adapting it. 2 days later, I finally had something usable. I started on a simulated annealing solution and shortly afterwards realized I had no idea how to do it well and stepped back. A contest is no place to try stuff you’ve never done before.

When my schedule cleared up on Thursday I watched the CG stream where they went from zero to silver in an hour and said ‘what the heck, let’s keep it simple this time.’ So my bot was that one in C#, with a few tweaks:

  • If you have a snaffle in hand and you’re in front of your own goal, don’t throw it at the other goal; it’s safer to throw it towards the sideline (soccer/football tactics). That way, flipendos can’t hurl it back in.
  • Similar checks for bludgers or opponent wizards when throwing forward as have been described above.
  • A minor change to the flipendo code allowed me to bounce them off the wall into the goal. This happened a lot and was a huge gain.
  • Used petrificus as a last-ditch goal saving measure.
  • RockyMullet suggested improving my snaffle chasing code with some vector math, which worked very well.

The only thing I did with my simulation code in the end was calling it once before I selected my moves with good old if-then-else. I think that probably hurt me as much as it helped; I was feeding it zero speed so spells would have been improved and moves would have been wrong. I just couldn’t bear all that work going to waste :slight_smile:

Moral of the story, you need good simulation and AI to finish high, but getting to Legend can be done just with tactics and a bit of math.

3 Likes

Hi Jahz,

No doubt, the game will be released in the multiplayer section soon. It has always been. I’m waiting for it too :slight_smile:

1 Like

I loved this competition, I prefer to write heuristics verse do some form of simulation. I know I wont get top 20 but was happy with 104 final legend rank…

We had 10 people from work competing so was awesome fun, the banter as people ranks ducked and dived…

I loved the rules where given, yet, the scope of a perfect solution seemed hard enough to avoid 100’s of me-to cpu burning simulating players, so right up to Sunday the server was responsive enough… and if you were prepared to wait an hour you could see how thing more or less improved if it was a big enough jump/fall on the ladder…

Look forward to Ghost in the Cell

1 Like

Nice challenge as always.
Writing the complete simulation was a big work compared to previous contests, but made the difference.
with a functionnal simu, a simple eval, you can always finish top50, but it requires you have the good language.
The point is, all languages are not equals ; you should think about according ressources
200 ms for interpreted languages
100 ms for common “semi-compiled” language
10 ms for C / C++, …

for the challenge it self
Pros :

  • 8 days are still good (if you guys want to go further with your code, go in challenge)
  • the rules were ok
  • easy to enter, hard to master ; anyone could easily access to the contest

Cons :

  • Random tee-shirt (even if I’d be happy to get one with my … 51th rank)
  • always the language disparity on such contest, especially with lots of collision ; I don’t think watching 70% IA with C++ in top20 is a good add for newcomers.
6 Likes

I’ll suck up my pride and toss my experience onto the pile, though it’s an outlier, and should be interpreted as a cautionary tale…

I started looking at the contest on the second day, and I misunderstood something fundamental. I saw the following:

  • Elastic collisions
  • Max velocity 10^6 (in the constraints)
  • A warning worded something along the lines of “if you go too fast, it can be difficult to control your wizard”
  • No mention of friction (that I remember) in Wood 2

I (wrongly) interpreted this to mean that wizards, snaffles, etc could be moving VERY fast, causing multiple collisions with walls and each other within a single turn. I started to try to write something that would intelligently handle multiple, iterative sub-turn collisions. After a couple of hours of just playing with it in a simulated environment, I gave up.

Here’s the CAUTIONARY part of the tale: I never tried to submit code. I never tested my assumptions about the physics. I ran off, half-cocked, and slammed myself hard into a wall. :slight_smile: The moral of the story: always start out any project (contest or otherwise) with a simple prototype that can be used to “test the waters”.

I later realized my mistake, and within the last 24 hours I was able to submit a serviceable AI that got to silver without using any spells. I never did get around to even reading the rules for the spells.

  • danBhentschel
4 Likes

Friction are in Wood 1, but not in Wood 2 ! :frowning:

Oh yeah. I meant to say Wood 2. Editing post. :slight_smile:

  • danBhentschel

Does anyone think it would help the competitions if the game instructions included fairly detailed pseudocode of the simulation engine? That way it might remove a lot of headache for people creating their simulators. Players can spend more time on solving the game, and less time trying to divine the rules and/or bugs of the simulation.

2 Likes