Omer 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.
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.
to see the list of parameters that you can use. Particularly useful is
to show all the recognized player names.
If needed, remember that you can run
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
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: