I almost want to remake Black Hole now, to see if I can make it more efficient or more robust, but by starting from scratch. It wouldn't be a winner (not with Windmill around) but could be fun
@Draco18s Note that Steamroller is not included in tournament leaderboards due to a historic disqualification that hasn't been corrected. It will be included again if edited, but it hasn't been for the last few months.
(in case that affects your testing)
@Draco18s Maybe I need to draw up the different combinations of queens and workers and explicitly state their outcomes so this can be tested more easily.
A static arrangement of two queens and one worker should lead to a net flow of food - it wasn't in my controller at the start but I fixed that back when Vampire was first being worked on. Maybe I need to find a more logical way of setting out the rules on food passing. I want people to be able to make best use of the possibility for ambushing rivals
@trichoplax It would help to make the food-passing rules completely explicit - I'm not sure my current understanding of them is entirely correct. It amounts to:
At the end of a worker's move, the worker is either laden or unladen. If she is laden and adjacent to her own queen, she delivers the food she is carrying. Otherwise, if she is unladen with one food-carrying enemy queen in view, she will steal one food from her. (If her own queen is also in view, this will not be delivered immediately. It will be delivered on the next turn when they are still adjacent then.)
(What happens when an unladen worker sees multiple food-bearing enemy queens? Only one food can be stolen, so the victim is chosen randomly?)
Furthermore, at the end of a queen's move, if she has food and one unladen enemy worker ant is nearby, one foot will be stolen / handed over at mandible point. (What happens when there are several unladen enemy workers? Do all of them get one food, while food lasts? randomly choosing among them when there's not enough food for all adversaries?)
@GNiklasch IIRC trichoplax answered that before. Not sure about the other stuff - I thought that a worker would always give the food to the queen immediately
Corollaries: When two queens and one worker of each queen all see each other, food will go round in circles, with no net gain and loss. When two queens and two workers of one, and one worker of the other, all see each other, there'll be a net stream of food to the larger gang.
(Trichoplax did explain it months ago here in this chat, but I'm not sure it was 100% unambiguous, due to all the edge cases...)
@DestructibleLemon It depends on which ant (worker or queen) is processed first. If a queen has its turn and is then adjacent to a worker that also has another queen neighbour, the queen that has just moved will interact with the worker (gaining or losing food accordingly). If a worker has its turn and is then adjacent to more than one queen, then if the worker is laden it will give to its own queen, or if the worker is unladen it will take from an enemy queen at random.
Also, when it's the beginning of a queen's turn (during execution of her ant function) and she detects a laden worker of her own in her view, then she can conclude that this worker must have stolen this food from an enemy on her move, just a moment ago (and thus the victim enemy queen is at most 2 cells away)
@dzaima I'm afraid this explanation preceded some subsequent bugfixes to the controller code...
I'm sure about this particular bit - as far as the present behavior of the official controller is concerned - because it came up in my debugging of the Windmill immune system
Another detail I'm not sure about is whether the queen picks up a food delivery from a laden worker of hers at the end of her turn, too (after the queen's ant function has run and the controller has otherwise acted on the result returned).
at the end of a queens turn, the queen randomly shuffles the cells around her, and in the shuffled order gives food away to enemies. Then it collects food from friends.
workers at the end of their move first give their food to their queen, and then possibly take food from a random enemy queen
and that seems to be all there is to food transfer
(at least in GameManager.stepAnt), only workers, at the end of their moves, do any food passing.
the workers go trough the view once (so already a difference), and on either hitting an enemy queen or own queen (and respectively getting/giving food), stop doing any food transfer after that.
in addition, it doesn't seem to shuffle the views searching for queens (though I may be missing stuff as I'm not going to understand the whole daves controller codebase in a few minutes :p)
oh wait, made a mistake on explaining Trichoplax's controller
this is incorrect - it only chooses to either give food or take food depending on own food status. So my (so already a difference) isn't correct :/
so it's hard to tell what differences there are without testing
in particular, how much of a difference does the fact that Daves controller doesn't have the queens doing food transfer make
@dzaima I need to check my own understanding of this too, in case there are cases I've overlooked. But I believe it should currently be as @GNiklasch describes: a laden worker arriving back at its own queen will pass the food at the end of its own turn, so the queen never sees it laden. She will only see her own worker laden if the food arrives while the worker is unladen (being stolen from an enemy queen), without the worker actually moving.
So yes this does leak information that narrows down the location of the enemy queen even if she is not adjacent to this queen
(I don't see a problem with this - there is still no direct knowledge of anything beyond the 9 visible cells - but it will be interesting to see if this knowledge can be put to use)
@GNiklasch I agree it needs to be fully specified in the challenge spec. @dzaima's description covers my understanding of my own source code six months after writing it. I need to write out in plain English what the rules are, along with relevant points about turn order, then edit the challenge spec, then double check the source code actually matches that, then look at Dave's source code.
If there are workers and a queen from player A and workers and a queen from player B all in sight of each other, it's worth keeping in mind the turn order. It's workers from A, followed by their queen, followed by workers from B, followed by their queen (cyclically - where it starts will depend on when you start watching that group)
Thank you both for bringing my attention to this
Once both controllers are consistent, I'll also need to see if I can modify Dave's controller to implement the joint places calculation based on 6 subsets of the games played. Either that or make an export game history option for Dave's controller and an import game history option for mine
I've just been watching a Vampire Mk.V attack on the Windmill in slow motion (the first I've been able to catch life) on Dave's controller. What I've seen matches dzaima's description: With two Vampire workers adjacent to both queens (who can't see each other directly), and no Windmill workers playing a part, it takes two steps to transfer each food: The two workers each steal one food in one step, and deliver it to their queen on (the end of) the next step.
But I swear I also caught vampire/windmill action where it was 1 worker 1 queen on both sides (a Q1/1Q sort of arrangement) and food flowed AWAY from vampire
I've seen some deadlocks with vampire on MoaR recently, but it was a clog of workers, none were getting through
Oh, BTW, I discovered when debugging ants recently that console.log(JSON.stringify(view)) works. Made it a lot easier to get the view dump.
And for what it's worth, Glider (in trichoplax's controller) is scoring a solid 14 points a round (each 15 and 13 evenly matched) after 38 games. Lightspeed has 13.77 and Windmill 12.42, in Dave's controller Glider and Lightspeed both score ~13.6 to 13.8
The current tournament using my controller is 295 games in and has Windmill 14.17, Glider 13.76, Lightspeed 13.63, all marked as joint first so that order isn't consistent between 6 subsets of the games.
I ran a tournament in daves controller with SlM and decided to look at the differences in places of daves scoring mechanism and average food of all games. The bot which would gain the most is Wildfire - by my scoring mechanism it would go up 8 places. Then black hole with 6, then FireFly - 5, SlM - 4 (Sliding Miners is first by average food gain :D)
Maybe a sensible first task would be to match Dave's controller to mine (or vice versa) in terms of seeded RNG per player. Once we know the seeded random behaves consistently it should be much easier to discover differences in behaviour between the controllers, so we can work out which differs from the spec (or any holes in the spec)
Yes the scoring mechanism is an essential part of the game. I chose the current one to reward consistent performance higher than occasional ridiculously high scores interspersed with low scores
@Draco18s It should, but I was under the impression that Dave's currently used a different RNG
@trichoplax and I wanted to see what would it be if the opposite were true, because IMO the consistency requirement really lessens the power of complicated bots (and indeed it did)
Sorry - I think we may be having 2 separate conversations. My point about needing to align the RNG mechanisms was independent of @dzaima's alternative scoring mechanism
Certainly complex bots are much harder to make reliable and consistent, but even with the scoring mechanism rewarding consistency, I would still describe the best performing bot as "complex" ;)
And the emergence of new players can sometimes shift the relative performance of existing players around in surprising ways. (Which IMHO is a good thing.)
Scoring based on food makes it harder for modest collectors to win, because they need to win by huge gains when they do win. A single uncontested Windmill game (600 food) requires Glider to spend 4 games at the top to come close.
I'm tempted to make my next KotH one on one, as it means far fewer games to run after a new player or edit arrives, but I am torn because of how interesting it gets with lots of players all in contact at once
Yeah, the mix of bots makes things more interesting. Nothing wrong with one-v-one KOTHs, but Formic Functions would have suffered if it hadn't been a free for all
If when we get Dave's controller working in a way that can produce leaderboards, with the joint places calculated correctly, I'll be able to run a tournament in a few days. At that point I might run a tournament with just 2 players per game to see how it affects the order
I wanted to look into how does Daves controller do random, but then I realized that I'd have to learn both Daves and Trichoplax's randomness systems to get anything done..
IMHO the subsets-of-16 have turned out really well now that we have rather more than 16 entrants. Keeps things comparable. I've been running a succession of games of 27-28 players on Dave's, and the scoring ends up a mess because so many players (not always the same ones) in each game end up with no food and no points, and everyone else gets that many points merely for having hoarded more than 0 food, and loses them when they themselves end up with 0 food.
My seeded random is a few lines of code that returns a function, and is just called once for each player to give them all their own independent functions
I'm glad 16 worked out well. It was really hard to guess how many players per game would work well with this size arena up front before I knew how many workers the players would be likely to produce. I wonder how much I made a good guess and how much the players have been built to suit this choice...
ok I have no idea where I would add player specific random in Daves controller.. (really I have no idea how to really do anything in daves controller :p)
Otherwise, it means that one of the controllers is using a different random at some point. It only takes one call to the wrong random function and the whole sequence is out by one
@dzaima Just plain xorshift for mine (the 13, 17, 5 example from Wikipedia)
Thinking about the rules for food passing, I think it allows faster than light food transport if you build up a chain or queen/worker/queen/worker
(not that it is of any practical use...)
I already knew it was possible to do faster than light information transport with tile colours or ant position changes if you line up your workers in the order they take their turns. Also can't see much practical use for that unless you want to build a very expensive single use alarm system
If you define light speed as how far you can move in one game turn (every ant taking one turn), then a chain of 100 ants can pass a message the entire length of the chain by colouring a cell that the next ant can see, and it will only take one game turn. It only works in one direction though - if you wanted to pass a message back you'd need a parallel line of ants with their turn order reversed (turn order is the same as ant age - oldest moves first)
@dzaima Mine just passes the random function around so it doesn't need access to anything (it stores its seed internally and updates it each time it's called)
If you can prove that it's possible to simulate GoL with workers, then a player has a Turing Complete army, but I'm not sure that's going to help you with anything practical...
@dzaima It's a while since I looked at mine, but I don't think it can switch between seeded and cryptorandom during a game. The appropriate random function is just assigned at the start of the game when the players are selected
@Draco18s You'd probably need to use several colours too, and use more than one game turn per GoL step, otherwise the updated colour would affect the decision of the next ant.
Sounds workable - that gives 2 bits - one for the state and one for whether it's an update turn or a consolidation turn
@Alion Touche. And I wouldn't dare suggest that Langton's ant isn't practically useful :P
@dzaima If you needed to switch part way through a game, you could assign both to each player at the start of the game then the player could choose which to call based on your switch
That's what I mean - assign the player a function that either calls Dave's random or my random based on the value of the switch. Then Dave's random class never needs to know about the switch
(I haven't seen Dave's random class or how it integrates with the controller so sorry if I'm missing something)