Conway's Battlegrounds
game-of-life king-of-the-hill python
Conway's Battlegrounds will be a mix of PUBG and Conway's Game of Life. In this challenge, you will need to make a Python bot that will play it.
Game rules
The controller, at the beginning of the round, will create a two-dimensional 500x500 toroidal (edge wrapping) board with chosen cells being alive, the others are dead.
The players are then separated into equal teams, each with 4 bots. If there isn't enough players in the team, some of them might be duplicated.
Gameplay
"Parachuting" phase
Everybody in the game will be given the array representing the starting state of the board. Each bot's class will be initialized, with these arguments in order:
num
- an int between 2 and 5 inclusive, representing the number you'd be marked with on the map during the game. The other numbers in the range will be your party members.
area
- Dictionary, where each key is a 2 value tuple (x,y)
and each value is either a 0 (dead cell) or 1 (alive cell)
During this phase, each bot's method parachute
will be called exactly 10 times. It will be given only one argument:
team
- 4 item dictionary with your and each teammate's ID (between 2 and 5) as key and a 2 item tuple as value, representing the (x,y)
position they chosen, or None
if they didn't yet chose any.
The method can return a 2 value tuple, representing where the bot want to start or None, if the bot can't decide. The returned value will be visible to every other teammate.
The method will be called again, even if the player already chose a location. The next return value will replace previous. You can prevent that by returning team[self.num]
, assuming you saved the num
parameter from __init__
.
It is recommended to spawn your bot near teammates, so it's easier to cooperate later.
If the method has been called the 10th time and the bot didn't return that time a (int, int)
tuple, it will be removed from the game.
Each bot will then be spawned at a random location in a 9x9 rectangle, with the returned location in the center. The bot will not collide with other players.
Starting phase
This phase will take exactly 25 turns. It's almost the same as the later, main phase of the game, except that no cell will die or be created in it.
The start
method of each bot will be called once every turn. It will take these arguments in order:
area
- Basically the same as in the previous phase, but with several modifications:
- It will be only a 25x25 fragment of the map, with the bot in the middle.
- It might also contain the ints in range 2..5 representing each teammate.
- It might also contain the int
-1
representing an opponent.
turn
- The number of the turn, starting with 0. In the last turn of the phase it will be 24.
chat
- a list of new chat messages, stored in tuples (author_id, msg_id)
The method must return a 0..4 value tuple or list, which may contain up to three actions the bot will perform during it and optionally a single chat message. Each item in tuple is a one move, depending on the value:
- Falsy values (0,
None
, False
) - Do nothing
Positive int - Move in given direction, according to the rule (where the bot is in the center):
1 2 3
4 6
7 8 9
Bot can only move to a neutral position.
- Negative int - Replace a neighbour dead cell with a neutral alive cell, according to the rule above, ex.
-1
.
- String - Send a chat message with the given ID, explained later
Main phase
Similar to the previous phase, but in this one, cells can die. It won't end until only one team is on the board.
The main
method of each bot will be called once every turn. It will take these arguments in order:
area
- Same as in starting phase
team
- Dictionary with position of teammates id: (x, y)
turn
- The number of the turn, starting with 0. In the last turn of the phase it will be 24.
hp
- The amount of health points the bot has, explained later. Initially 4.
chat
- a list of new chat messages, stored in tuples (author_id, msg_id)
The return value is the same as in the previous phase.
Neighbours, dying and reproducing
- A neighbour of a cell a is an another cell that is positioned next to the cell a, either orthogonal or diagonal.
- A neutral cell is any cell that is either
0
or 1
(isn't a bot).
- A bot cell is any cell occupied by a bot, that is, the negative number
-1
and positive 2
, 3
, 4
, 5
.
- A dead cell is any cell that is exactly
0
.
- An alive cell is any cell that is not dead (
0
). This includes both bot cells and 1
's.
In this round, cells can die. They can also reproduce.
- Neutral cells (marked
1
) will die (turn to 0
) if amount of their alive neighbours is not 2 nor 3.
- Dead cells (marked
0
) will reproduce (turn to 1
) if amount of their alive neighbours is exactly 3.
Rules about bot cells (-1
and greater than 1
) are a bit different though.
- Bot cells will lose 1 hp if amount of their alive neighbours is not 2 nor 3 and no natural cells were reproduced in the neighbourhood.
- Bot cells will die if they have 0 hp.
- Bot cells will gain 1 hp if amount of their alive neighbours is equal to 3 and at least 1 neighbour is a teammate. Cell will not gain hp if it has 3 or more hp.
- Bot cells will be moved if amount of their alive neighbours is not 2 nor 3 and a single nearby cell was reproduced (it will replace it). Bot cells cannot duplicate.
The red zone
Every 100 generations (turns), the red zone will start in the place with most dead cells. It will end after 10 turns, and every second turn it will spawn a glider.
Chatting
Bots in the same team can communicate between themselves during the game.
Some of the messages were made because of how the board is generated. Make sure you read this before, so you can use it to collaborate with other bots easier.
Here's a list of all "built-in" messages:
1
- Help!
2
- Wait!
3
- Need healing!
4
- Come here
5
- Enemies are nearby
6
- I'll fight
7
- I'll build
8
- Search for boats/Build a boat
9
- Get in the boat
10
- Exit the glider
The controller
WIP, I won't probably have time to make it this week.
Example bot
A classic random bot, won't survive long.
import random
class RandomBot:
def __init__(*args): pass
def parachute(self, team: dict):
return random.choice([x for x in team.values() if x])
def start(*args):
return random.randint(-9, 9)
def main(*args):
return RandomBot.start()
Additional rules
- You have access only to non-superuser built-in Python packages
- You must not create, write nor open any files
- You cannot access any of internal or other bot's classes
- You cannot modify any mutable arguments given to your methods, only their copies
- You shouldn't throw any exceptions
- You must return only specified values.
- The code you publish here must not output anything