Getting started
Last updated: April 1, 2025Task
Your task in this year’s Algorithms-and-Datastructures contest is developing a bot for our game Terratactician-Expandoria (TTE),
that can reach round 5
in Challenge Mode.
You’ll be writing a Java-file, which is then handed in on the course website.
Installation
To be able to work on the task, you have to set up two components:
- the Game
- the Bot-library (
.jar
file), which handles communication with the game
Installing the Game
Depending on the platform, there are different ways to install the game.
The easiest way to play the game is playing online.
If you want to take full advantage of available performance,
or want to test your bot without the UI (allowing for faster simulation),
you have to install the game (recommended).
You can find a full setup-guide [here][setup guide].
All game releases are available on Codeberg.
If Codeberg isn’t available, you can also get the game from the vccourses mirror.
Setting up the javabot library
Download the latest version of the tte-bot-full.jar
from the bot release page.
You can find detailed instructions and alternative installation types in the bot setup guide.
It also details how you can use a build.gradle
to use the bot.
Creating a new bot
Start by creating a new Java file called MyBot.java
.
A template is available in the bot repository.
Copy the content into your newly created file and edit the Bot Name, your Student Name and registration number.
Your task is implementing the executeTurn
method.
You can add additional classes in the file but not in other files, because you can only hand in one file.
Starting and testing your bot
To build and run the bot, you have to execute the following commands.
Note that you might have to adjust the file path to point to your copy of the tte-bot-full.jar
and your bot.
# compile the bot
javac -cp tte-bot-full.jar bots/MyBot.java
# run the bot
java -jar tte-bot-full.jar -c bots/MyBot.class
To connect the game to the bot, you have to activate bot support:
- launch the game
- select Challenge Mode as the gamemode
- check the box next to
Activate Bot
- click
Start
(you have to start the bot before, as the game connects to it)
We will test your Bot with the seed XXX
.
If you want to run a fast simulation (without the UI), you can start the game with the following command:
terratactician-expandoria --challenge --bot --headless
(If the game is not in your $PATH
, you have to use the path to the binary.)
Tips & Tricks
Gameplay
You can find a detailed Challenge Mode breakdown in the Game Book.
TerraTactician Expandoria is a round-based strategy game.
Your goal is to survive as long as possible.
To survive a round, you have to collect the required resource amount.
If you fail to meet the resource target in two succeeding rounds, you lose the game.
Each round lasts for one minute.
There are two ways to collect resources:
- tiles produce resources over time
- collecting a reward gives you resources
You can place a card at a given position if
- the field is empty,
- it is within the build area,
- the tile has at least one neighbour (or it is the first tile on the map),
- and you have the card in your hand.
You can get new cards by redrawing:
- You can redraw for free every 20 seconds, refilling your hand.
- You can pay to redraw if you have enough resources, and no free redraw is available. This will remove your current cards and replace them with 5 new cards.
- Your hand is automatically refilled at the beginning of every round.
You can pick up tiles for a couple of seconds after placing them down.
Rewards appear every 19 seconds above tiles on the map.
Cards
You can increase the resource production, by strategically placing the cards on the map.
You can find more information in the tile documentation.
The following is a short tile overview:
- Grass: Doesn’t produce resources, only useful to separate other areas.
- Forest: produces Materials. The amount increases linearly with the amount of adjacent forest tiles.
- Wheat: produces Food. The best production rate can be achieved by building clusters with 9 wheat tiles.
- Beehive: produces Food. The amount can be increased by increasing the amount of Forest and Wheat tiles in the surroundings.
- Windmill: produces Food. Has to be placed near Wheat tiles. You can increase the production rate by increasing the amount of Wheat tiles.
- Single House: produces a constant amount of Money.
- Double House: produces Money. The best production rate can be achieved by placing exactly 3 other houses adjacent to it.
- Moai: doesn’t produce resources, but can be used to boost the production rate of houses in the surroundings. This effect can be increased by having a larger variety of other tiles surrounding the Moai statue.
- Marketplace: Sells Materials and Food for Money. The possible amount depends on the amount of resources produced in the surroundings of the marketplace. The price depends on the amount of houses in the area. You can select the amount of resources sold.
- Rocks: Doesn’t produce anything. It is a Level 1 Stone-Tile.
- Hill: Doesn’t produce anything. It is a Level 2 Stone-Tile.
- Berg: Doesn’t produce anything. It is a Level 3 Stone-Tile.
- Quarry: Produces Materials by collecting Materials from Stone-Tiles. The amount depends on the Level of the tile. Quarries are automatically assigned the best possible Stone-Tile.
Bot Library Features
CubeCoordinates
As you might have noticed already, the TerraTactician Expandoria world is made up of hexagons.
This is why we have to use a different coordinate system: CubeCoordinates.
You can find a helpful introduction on redbloggames.com.
In short, every coordinate is made up of 3 numbers. Their sum has to be 0. You can also use cube coordinates as a vector between two coordinates, like you would with regular coordinates.
You don’t have to fully understand CuebCoordinate
s to be able to develop a bot.
We have implemented a CubeCoordiante class, which does most of the work for you.
Useful methods include:
this.getRing(int)
: Returns a Java Iterator, which iterates over all tiles on the hexagon-circle aroundthis
with a radiusint
.this.getArea(int)
: Returns a Java Iterator, which iterates over all tiles in the area betweenthis
and the hexagon-circle with radiusint
.- You can use the
.add
,.sub
,.mul
,.div
,.neg
methods to perform common vector operations.
Your turn
Your code in executeTurn
will be executed once every second.
Your bot then has 40 ms
to determine the next action.
You can access information from the World
and schedule actions using the Controller
.
You can end your turn by returning from the function.
If your bot takes too long to end its turn, it will be suspended for one turn.
You can find more information in the Controller docs.
A couple of examples:
@Override
public void executeTurn(World world, Controller controller) {
// Places the first tile in your hand at (0,0,0), without checking if the
// coordinate is valid or if the hand has cards.
// Take a look at `world.getHand().len()` to check how many cards are in
// the hand. `world.getBuildArea().contains(coord)` and
// `world.getMap().at(coord)` to check if the cell is empty.
controller.placeTile(world.getHand().get(0), new CubeCoordinate(0, 0, 0));
// The command above is equivalent to:
controller.selectSlot(0);
controller.placeTile(new CubeCoordinate(0, 0, 0));
// You can also place tiles using their type
// (assuming that you have them in your hand)
controller.placeTile(TileType.Wheat, new CubeCoordinate(0, 0, 0));
// If you want to pass data to the tile when placing it,
// you can specify a class directly
controller.placeTile(
new MarketplaceTile().withFoodRatio(0.5),
new CubeCoordinate(0, 0, 0));
// You can also pick up cards:
CubeCoordinate coord = /* ... */ ;
// Make sure to check if the card can be picked up
if (world.getMap().at(coord).takeable()) {
// Pick up the card
controller.takeTile(coord);
}
// You can collect rewards using the following method
controller.collectReward(/* coord */);
// Redraw cards
controller.redraw();
// If you want to configure the marketplace after placing it,
// use the following method
controller.configureMarket(/* coord */, /* food [0.0-1.0] */, /* materials [0.0-1.0] */);
}
You can find necessary information in the World class.
BuildArea
getBuildArea()
- Returns an object with information about the build area.Hand
getHand()
- Returns an object containing all cards in the hand.Map
getMap()
- Returns an object containing all tiles placed in the world.Metrics
getRedrawCosts()
- Returns an object containing the current redraw price.double getRedrawTime()
- Returns the time until the next free redraw, in secondsMetrics
getResources()
- Returns an object containing the amount of resources collected.Metrics
getResourcesRate()
- Returns an object containing the current production rate. (The amount of resources produced per second).Rewards
getRewards()
- Returns an object containing all the rewards that can be collected right now.int getRound()
- Returns the current round starting with 0. (The UI starts with round 1.)double getRoundTime()
- Returns the time left in the current round in seconds.Metrics
getTargetResources()
- Returns an object containing the current resource target.
Bot-Design Ideas
Are you still looking for an idea of how to design your bot?
Use getArea
to iterate over the entire map.
And use getMap
to check if it is possible to place a tile at the position by checking if the cell is empty and has a neighbour.
You can apply a heuristic, which determines how well suited a given card in the hand is for the current position.
Afterwards, choose the card and position with the highest values.
A simple heuristic could be splitting the cards into sets by how they interact with each other and checking how many types in the set are adjacent to the current position.