TerraTactician Expandoria Logo

TerraTactician Expandoria

Getting started

Last updated: April 1, 2025

Task

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:

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:

  1. launch the game
  2. select Challenge Mode as the gamemode
  3. check the box next to Activate Bot
  4. 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:

You can place a card at a given position if

You can get new cards by redrawing:

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:

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 CuebCoordinates to be able to develop a bot. We have implemented a CubeCoordiante class, which does most of the work for you.

Useful methods include:

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.

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.