Settlers of Catan is one of my all-time favourite board games. Players build towns and cities, collect and trade resources to expand their settlements and race to be be the first to get 10 victory points. The board is made of hexagonal shapes representing different resources, which are randomised before each game so that the game is different every time you play it. Now, like all programmers, I am inherently lazy, so I would like to create a simple simulation in R that does this randomisation for us.





With any project, before writing any code, I like to try and figure out manually what the data that I am looking at means, and how best to represent it as simple as possible, while maintaining the necessary information.





So, let's start with some parameters: For this exercise, we'll use the standard game, no expansions. In addition to the hexagons themselves, the sides and corners of the hexagons should also be defined, as that is where most of the action happens. So let's start from the idea that three different types of elements that together make up the board, each of which has a number of properties, the value of which can be altered depending on the game state. Let's add some properties and values as well, just to get an idea of what our data structure will look like, without trying to make it an exhaustive list right now - we are only concerned with generating the starting board for now after all.





A Catan board will consist of:

-19 hexagons, arranged in a 3-4-5-4-3 pattern.

-72 edges, on each of the 6 sides of every hexagon.

-54 corners, on each of the 6 corners of each hexagon.





Let's dive into R and create a tibble for each of the board elements. We'll add the columns that we will definitely need for the board randomisation, but we'll also go ahead and add some of the other bits of data that we will need later down the line, without necessarily trying to be exhaustive right now:

We can now start generating the terrain. This can be done by generating a vector with with the appropriate number of strings for each terrain type, then randomly drawing from it and assigning the values to the appropriate column in our hexagon tibble:

The tiles are laid out! But they don't have numerical values assigned to them yet. Even though the numerical values are always laid down in the same order in an anticlockwise motion starting from the top left (tile 1) going inwards, we'll need to do some reordering. After all, we need to skip the desert tile which does not get a number (or rather, will get the number 0). Our hexagon tiles are currently numbered in 5 rows going from top left to bottom right, so it is straightforward to write an index that simply takes the numbers 1 to 19 and puts them in the order that they will receive their numerical value. Then we just need to insert a 0 at the appropriate index coinciding with the desert tile, revert the rearrangement of the terrain tiles, and assign the numerical values to the appropriate column of our hexagon tibble:

Now we have a board with terrain types and numbers generated in accordance with the basic rules! We're almost done with the board generating, but we're missing an important part: the harbours. Even though harbours are represented traditionally on the board as their own hexagonal tiles, it is much simpler to represent them as properties of certain corner tiles. We can randomise the harbours in a similar way as we did with the terrain types, but we have to keep in mind that each of the harbours connects to two adjacent corner tiles. The corner tiles are numbered in a similar fashion to the hexagons, starting in the top left going down to the bottom right in 6 rows. We'll make a vector with each of the corner tiles in it that will get a harbour, making sure that we always keep the pairs belonging to the same harbour next to each other in the vector as well. Then we can simply create another random draw function, make a new vector that repeats each element twice, and assign the random harbours:

All done! We have our completely randomised board for Settlers of Catan. As a cherry on top, let's add the robber to the desert tile and inspect our hexagon and corner tibbles:

The board is completely generated! We can't see it visually yet, we still have to manually read our tables, but you can join me next time to see how to make a visual representation so we can see what's happening on something resembling a real Catan board!