Note: I'm putting this challenge on the back burner for a indefinite time in favor of the Hierarchies challenge. Go check that or the Formic Forest out if you're interested in a Formic sequel.
Formic Functions 3: Memory
This is a preliminary write-up of a new challenge heavily inspired by Formic Functions. The spec is based on the original challenge's spec - credits for most of what you'll read here to trichoplax.
Each player starts with one ant - a queen, who collects food. Each piece of food can be held or used to produce a worker. Workers also collect food to be brought back to the queen.
All players compete in one arena. The winner is the queen holding the most food after she has taken 8,000 10,000 [Thanks @Draco18s] turns. Ants can communicate by changing the colors of the arena squares (which can also be modified by rivals), as well as by storing messages for their peers.
The arena
The arena is a toroidal (edge wrapping) grid of hexagonal cells arranged in a rhombus of side length 1000. All cells start as color 1.
Initially exactly 1% 0.5% of cells will contain food. The 5000 pieces of food will be scattered uniformly randomly. No new food will be introduced during the game.
The queens will be placed randomly on empty cells, with no guarantee that they will not be adjacent to each other (although this is very unlikely).
Ant abilities
- Sight: Each ant sees the 7 cells in its neighborhood. It has no knowledge of any other ants outside this neighborhood. It sees the contents of each of the 7 cells (other ants and food), and also each cell's color.
- Memory: Each ant has access to a string as its memory. It is initially empty for the queen, and must be initialized by the queen when spawning a worker. For ways to change the memory after initialization, see Output below.
- No orientation: An ant does not know where it is or which way it faces - it has no concept of North. The neighborhood will be presented to it at a randomly rotated orientation that changes each turn so it cannot even walk in a straight line unless it has colors to guide it. (Making the same move every turn will result in a random walk rather than a straight line.)
- Moving, color marking, producing workers and transferring food: See Output below.
- Immortality: These are highland ants that cannot die. You can confuse rival ants by changing the colors around them, or constrain them from moving by surrounding them with 6 ants of your own, but they cannot be harmed apart from this. [Should ants be able to die? If so, how?]
- Carrying food: A worker can carry up to 1 piece of food. A queen can carry an arbitrary amount of food.
Coding
Provide a function body
Each ant is controlled by an ant function. Each turn the player's ant function is called separately for each ant (not just once per player, but once for the queen and once for each worker that player controls). Each turn, the ant function will receive its input and return a move for that particular ant.
Post an answer containing a code block showing the body of a JavaScript function, and it will be automatically included in the controller. The name of the player forms the title of the answer, in the form # PlayerName
.
No access to outside data
Functions must be fully deterministic. When called with a given input, they must return the same output every time. A function must not access global variables and must not store state between turns in other ways than through the provided memory string. It may use built in functions that do not involve storing state or accessing data from the outside. For example, the use of Math.abs()
is fine, but Date.getTime()
, Math.random()
must not be used.
An ant function may only use a pseudo random number generator that it supplies itself, that utilizes data provided through input. For example, it may implement its own pseudo RNG via its memory string, seeded by the environment (or statically).
A simple random strategy is still possible due to the random orientation of the input - an ant that always chooses the same direction will perform a random walk rather than a straight line path.
An ant function is permitted to contain further functions within its body.
Input and output
Input
The orientation of the input will be chosen at random for each ant and for each turn. The input will be rotated by 0, 60, 120, 180, 240 or 300 degrees, but will never be reflected.
Cells are numbered in this order:
0 1
5 6 2
4 3
The ant function will receive an array called view
, containing an object for each of the 7 visible cells. Each object will have the following:
color: a number from 1 to 8
food: 0 or 1
ant: null if there is no ant on that cell, or otherwise an ant object
[Is 8 colors perhaps too many?]
If a cell contains an ant, the ant object will have the following:
food: 0 or more (maximum 1 for a worker)
queen: true or false
friend: true or false
memory: memory string when friendly, otherwise undefined
[Should ants be able to read rivals' memories? This would cause rampant edit wars. Rejected.]
The ant can determine its own details by looking at the ant in the central cell, view[6].ant
. For example, view[6].ant.memory
contains the memory of the executing ant.
Output
Output is returned as an object representing the action to take. This can have any of the following:
cell: a number from 0 to 6 (mandatory)
color: a number from 1 to 8 (optional)
spawn: a string (optional)
memory: a string (optional)
If color
and spawn
are omitted or non-truthy, then cell
indicates the cell to move to.
If color
is a number, the indicated cell is set to that number.
If spawn
is a string, a worker ant is created on the indicated cell. The new worker will have its memory
initialized to that string. The string cannot be longer than 256 characters. Only a queen can create a new worker, and only if she has food, as this costs one piece of food per worker.
If memory
is a string, the executing ant will have its memory
immediately changed to that string. The string cannot be longer than 65,536 characters for the queen, and 256 characters for workers. An ant may change its memory while also performing a different action - changing memory does not take a turn.
[Should changing own memory take a turn?]
[Should ants be able to send a message directly to another ant's inbox
? For example, a message could look like this: {title:"help", content:view_array_of_sender}
. An ant should also be able to perform an action while sending a message, otherwise the described behavior could be emulated.]
[Should ants be able to see the age of an ant? This behavior will often be emulated with memory. Is there a reason not to do that?]
[Is 65,536 characters a good number to pick for the max length of memory? Thanks to @Draco18s's and @dzaima's advice, workers now have significantly less memory than a queen.]
Example outputs:
{cell:0}: move to cell 0
{cell:5, memory:"abc"}: move to cell 5 and set own memory to "abc"
{cell:6}: move to cell 6 (that is, do nothing, as 6 is the central cell)
{cell:6, color:8}: set own cell to color 8
{cell:2, color:1, memory:"hey"}: set cell 2 to color 1 and set own memory to "hey"
{cell:1, spawn:"def", memory:"5252"}: create a worker with its memory initialized to "def" on cell 1 and set own memory to "5252"
{cell:3, color:0}: equivalent to just `{cell:3}` - move rather than set color
{cell:1, spawn:0}: equivalent to just `{cell:1}` - move rather than create worker
{cell:4, color:0, spawn:0}: move to cell 4 - color 0 and type 0 are ignored
Invalid outputs:
{cell:7}: cell must be from 0 to 6
{cell:0, color:9}: color must be from 1 to 8
{cell:0, spawn:true}: spawn must be a string
{cell:6, spawn:"254"}: cannot create a worker on a non-empty cell
{cell:0, color:1, spawn:"77"}: cannot set color and create worker in the same turn
{cell:3, memory:true}: cannot set memory to non-string
{cell:2, spawn:true}: cannot create a worker with a non-string memory
{cell:0, memory:long_string}: (if long_string is a string of length > 65536) cannot set memory to a string of length greater than 65536
[Missed any?]
An ant moving onto a cell containing food will automatically pick up the piece of food. If that ant is a laden worker, it will move onto the cell without picking up the piece of food.
An unladen worker trying to move onto an enemy queen with food will steal one piece of food from her instead. A laden worker trying to move onto an unladen friendly worker or a friendly queen will give its food to their target instead.
Turn order
Ants take turns in a set order. At the start of a game the queens are assigned a random order which does not change for the rest of the game. When a queen creates a worker, that worker is inserted into the turn order at the position before its queen. This means that all other ants belonging to all players will move exactly once before the new worker takes its first turn.
Limit on number of players
Obviously an unlimited number of players cannot fit into the arena. If there are more than 8 answers, only 8 of them will play in any one game.
[Good max number of players?]
Time limit per turn
Each time the ant function is called, it should return within 20 milliseconds. Since the time limit may be exceeded due to fluctuations outside the ant function's control, an average will be calculated. If at any point the average is above 20 milliseconds and the total time taken by that particular ant function across all calls so far is more than 10 seconds, the relevant player will be disqualified.
[Enough time?]
Disqualification
This means the player will not be eligible to win and their ant function will not be called again during that game. They will also not be included in any further games. If a player is disqualified on the tournament machine during a leaderboard game then it will be excluded from all future leaderboard games until edited.
A player will be disqualified for any of the following for any of its ants (queen or worker):
- Exceeding the time limit as described.
- Returning an invalid move as described under Output.
- The cell to move to contains an ant and the case isn't defined under Output.
- The cell to produce a worker on contains an ant.
- A worker is trying to produce a worker.
[Did I miss any?]
It may seem harsh to disqualify for invalid moves, rather than simply interpreting this as no move. However, I believe that enforcing correct implementations will lead to more interesting strategies over time. This is not intended to be an additional challenge, so a clear reason will be displayed when a player is disqualified, with the specific input and output alongside to aid in fixing the code.
Multiple answers and editing
You may provide multiple answers, provided that they do not team up against the others. Provided each answer is working solely towards its own victory, you are permitted to tailor your strategy to take advantage of weaknesses in specific other strategies, including changing the color of the cells to confuse or manipulate them. Bear in mind that as more answers come in, the likelihood of meeting any particular player in a given game will diminish.
You may also edit your answers whenever you choose. It is up to you whether you post a new answer or edit an existing one. Provided the game is not flooded with many near-identical variations, there should be no problem.
If you make a variation of another person's answer, please remember to give them credit by linking to their answer from yours.
Scoring
At the end of each game, a player's score is the number of other players who have less food carried by their queen. Food carried by workers is not counted. This score is added to the leaderboard, which is displayed in order of average score per game.
Joint places indicate that the order of players is not yet consistent between 6 subsets of the games played so far. The list of games is split into 6 subsets because this is the minimum number that will give a probability of less than 5% that a given pair of players will be assigned distinct places in the wrong order.
[Scoring mechanism subject to change.]
[New feature/modification recommendations are very welcome! I want this challenge to be as different from the original Formic as possible, while keeping its spirit.]
hexagonal-grid
game
king-of-the-hill
javascript