#57 Legend in python
Comments
Thanks CG for the contest, I liked the format and the when it happened, I believe that being a holiday season allowed many players to find time to play. One thing: can we get a fix for move cancellation when a recycler is placed on a neighbor cell please? I want to spend some more time on the multiplayer but I find tedious to work around whatever java queue is doing.
I was impressed by the level, on the last Friday I managed to reach 19th but went down to 40th by Saturday end-of-day. Had to ship multiple improvements to get back up.
Thanks also @bourgeof for pushing me into Legend, I was <0.3 below the boss and you pushed it down just enough I had the pleasure to exchange with @slamo, @DumbassDan , @davidshhh and @VisualDev-FR , discussing replays and ideas.
Bot
Not much to add to other PMs, so I will focus on the steps I took. I hope it will help folks making incremental improvements.
Starting simple
I tend to start with really simple bots. Getting out of wood and messing around in Bronze:
- Assign units to their nearest opponent or neutral cell, don’t send another unit to that cell, no ordering of units. As dumb as it sounds it was enough to compete and start building some intuition about the game.
- Build one recycler in the first cell on the first turn. That worked for a while.
- Simple “battle” code: spawn to protect or build recycler. Nothing fancy initially, just enough to get a sense of what data was needed (# opponents, count units coming to the cell from neighboring cells, etc.)
- Use Manhattan distance, I used it until the last weekend, t’was enough. Sometimes units get stuck.
Iterating
From that bot I decided to focus on:
- From the above simple bot: sort units by distance to the nearest opponent.
- Spawn not 1 but 2 recyclers! My final version was doing that: up to 2 recyclers before meeting the opponent.
- Better combat code: block if I cannot spawn enough units otherwise spawn, then bring neighbor units not facing an opponent to that cell. Attack when possible.
This helped but not that much since I was meeting the opponent on my side of the board. - Improve spreading units to meet the opponent at the center of the map: this was a constant source of improvement until the last Friday where I refactor the code. Save where the initial frontier is, then combine spawn/move to have units reach it as fast as possible.
One thing that helped most of the contest (it’s now holding me back), if a stack of units is moving to the same cell and there are neutral cells around then split the stack (unless the neutral cell is behind). Until I assigned units to the initial frontier that encouraged spreading without much complexity (no BFS, just checking neighboring cells). - Units that are not taken for attack/defense would go to the nearest neutral cell if any.
All of the changes where tested locally, I was looking for a winrate of +5% to test in the arena.
Final thoughts
Given the different game mechanics (see how everyone is splitting their logic) I’m glad we had more time than usual for the contest. It feels like this could be a great beginner friendly multiplayer: smart ordering of orders works (I mean if-else spaghetti), scoring cells works, some search can help (like identifying a frontier or a player’s influence), etc.
Until next time