DominatorOmer Giménez Jordi Petit Enric Rodríguez |
In this game, four players have control over an army of
farmers, knights and witches on a 37 × 37 board.
The goal of the game is to “farm” as many cells as possible,
converting them to the team color. Initially, the cells have no color.
Every round, the number of cells of each color is added to the
corresponding score. The winner of the game is the player with the
highest score after the last round.
Each player has a quadrant where their units are initially
born, and where they are reborn when captured (killed) from other
teams. Player 0 has the top-left quadrant, player 1 the bottom-left
quadrant, player 2 the bottom-right quadrant, and player 3 the
top-right quadrant. At the beginning of the game, each player gets 20
farmers, 10 knights and 2 witches on its quadrant.
The game lasts 200 rounds. Every round, every player can move
each own unit at most once. Farmers and witches can only move
horizontally and vertically. Knights can also move diagonally, and
attack rival units.
The boards have walls, that is, obstacles that units cannot
visit nor traverse. The top row, bottom row, lef-most column, and
right-most column only have walls. Trying to move a unit into a wall is
an invalid move.
Initially, farmers have health 100, and knights have health
200. Deliberately not moving a unit (or moving it in the None
direction) will increase its health by 30 units. A unit cannot have
more health than its initial amount. Performing an invalid move results
in that unit not moving, but does not regenerate health.
Witches are immortal. Witches can move to any adjacent empty
cell. Any cell at Manhattan distance at most two from a witch (that is,
at most two horizontal or vertical steps away from a witch, or
diagonally adjacent to a witch) is haunted, even if there is a wall in between.
Any farmer or knight in a
haunted cell dies immediately, even if the spell comes from a witch of
the own team.
A witch gets “deactivated” when there are one or more
witches at Manhattan distance at most two from her, even if there is
just one such witch, and from the same team. Deactivated witches do not
haunt any sorrounding cells, and farmers and knights can move around
them (until the witches get activated again, of course).
Farmers can move to any adjacent empty cell. If that cell is
haunted, the farmer dies. Otherwise, the cell is painted with the
farmer’s team color.
Knights can move to any adjacent or diagonally adjacent empty
cell. If that cell is haunted, the knight dies.
A unit killed by the spell of one or more witches
will be reborn as a unit of another team.
If all the killing witches belong to the same team of the dead unit,
the new team will be selected uniformly at random among the rest of teams.
Otherwise, the new team will be selected with probability proportional
to the number of killing witches of the other teams.
For instance, if a unit of player 2 dies under the spell
of one witch of team 0, two witches of team 1,
and one witch of team 2,
then the new team will be 0 with probability 1/3,
and will be 1 with probability 2/3.
Knights can attack any adjacent or diagonally adjacent
rival farmer or rival knight (by an order to move there).
Trying to attack an own unit or a witch
is an invalid movement. Otherwise, the rival unit loses a random amount
of health between 60 and 90. If the new health drops to 0 or below,
that unit is captured by the team of the attacking knight.
Every round, more than one order can be given to the same
unit, although only the first such order (if any) will be selected. Any
player program that tries to give more than 1000 orders during the same
round will be aborted.
Every round, all the selected orders will be executed using a
random order. For instance, if two farmers try to move to the same
empty cell, only the farmer that happens to move first will move there.
As another example, assume that one farmer and one rival knight
try to move to the same empty cell.
If the knight happens to move first,
afterwards the farmer will not move,
because it would be an illegal movement.
However, if the farmer moves first,
afterwards the knight will attack the farmer,
by trying to move to the farmer’s position.
After all the selected movements of a round are played, the
units captured by each team are reborn in its corresponding quadrant.
Whenever possible, all units are reborn at Manhattan distance at least
3 from witches. Additionally, farmers are not placed adjacent to rival
knights, and knights are not placed adjacent or diagonally adjacent to
any rival unit. In the rare cases when this cannot be accomplished,
units are reborn on any legal cell in the own quadrant, or on any legal
cell in any other quadrant, in even more exceptional situations.
Although there are four players, with numbers 0 to 3, when
programming your strategy you must always assume that you are player 0.
If you are not, the board will be rotated consistently with your
illusion. For instance, if you are player 1, any movement in the
Right direction by you will be automatically transformed into
a movement to the Top.
Note that the valid directions are
Bottom, BR, Right, RT, Top,
TL, Left, LB and None,
corresponding to integers from 0 to 8.
This circular definition can be used
to simplify the implementation of your player.
See the Demo player for some examples.
If you need (pseudo) random numbers,
you must use two methods provided by the game:
random(l, u), which returns a random integer in [l..u],
and (less frequently) random_permutation(n),
which returns a vector<int>
with a random permutation of [0..n-1].
A game is defined by a board and the following set of parameters:
The first thing you should do is downloading the source code. It includes a C++ program that runs the games and an HTML viewer to watch them in a reasonable animated format. Also, a “Null” player and a “Demo” player are provided to make it easier to start coding your own player.
Here, we will explain how to run the game under Linux, but it should work under Windows, Mac, FreeBSD, OpenSolaris, …You only need a recent g++ version, make installed in your system, plus a modern browser like Firefox or Chrome.
make all
to build the game and all the players. Note that Makefile identifies as a player any file matching AI*.cc.
./Game Demo Demo Demo Demo -s 30 -i default.cnf -o default.res
This starts a match, with random seed 30, of four instances of the player Demo, in the board defined in default.cnf. The output of this match is redirected to default.res.
Use
./Game --help
to see the list of parameters that you can use. Particularly useful is
./Game --list
to show all the recognized player names.
If needed, remember that you can run
make clean
to delete the executable and object files and start over the build.
To create a new player with, say, name Sauron, copy AINull.cc to a new file AISauron.cc. Then, edit the new file and change the
line to
The name that you choose for your player must be unique, non-offensive and at most 12 characters long. This name will be shown in the website and during the matches.
Afterwards, you can start implementing the virtual method play(), inherited from the base class Player. This method, which will be called every round, must decide the orders to give to their units.
You can define auxiliary type definitions, variables and methods inside your player class, but the entry point of your code will always be the play() method.
From your player class you can also call functions to access the state of the game. Those functions are made available to your code using inheritance, but do not tell your Software Engineering teachers because they might not like it. The documentation about the available functions can be found in an additional file.
Note that you must not edit the factory() method of your player class, nor the last line that adds your player to the list of available players.
When you think that your player is strong enough to enter the competition, you can submit it to the Jutge. Since it will run in a secure environment to prevent cheating, some restrictions apply to your code: