Building a Catan Game in Angular
But... why?
I have been playing the board game Catan quite a bit recently, and noticed that your starting strategy almost always dictates the rest of your game. To practice the initial placements of settlements, the options were setting up a board, making initial placements, then sweeping it up and resetting, or playing lots of online games. With games taking between 30 minutes to an hour and only practising one position one time, I wanted a more efficient way of practising making the initial settlements, from each position.
How Initial Placements Work
- Each player in turn places a settlement and a road.
- After the last player places their first settlement, each player goes again with the order reversed (last player first, first player last).
- You can collect the resources your second settlement is on into your starting hand.
- When play begins, the dice are rolled and each player collects a resource their settlement is on if that resource's number matches the dice roll.
Normally, you would have one attempt at making initial settlements each full game. But what if you could make four attempts, simulate a game (to some degree), and then try again?

Creating the board
The first step was to create the board. A Catan board consists of 19 hexagonal tiles, with ports around the edges. As hexagons are the bestagons, they also have many different methods of being created, each with unique advantages and disadvantages.
I could have used SVG, images or canvas, but in the end I went for a straight HTML/CSS approach. Most solutions I could think of involved using borders to create triangles on the sides of an element, but it would mean I couldn't use a background image. I decided to go for three identical rectangles each rotated 60%, and have an image on pseudo-elements which are rotated back to match the original rectangle. Hiding the overflow is all that is left to have a seamless* background image.
* - The background is not actually seamless due to rendering issues with transformed elements and anti-aliasing. As such, you can see a very thin 'border' between the rectangles at certain scales.

After having the hexagons working nicely, we set up the board object in Angular and use an *ngFor in the template to create a hex for each tile. Each hex takes its classes from the board object, which are randomised with each new board. As the hexagons are regular shapes, centering them and adding a small margin (offset with the rotated elements) is all that is needed to line them up properly.
To keep the board interesting, we make sure not to have two adjacent hexes that both have the most common rolled numbers (6 and 8 [if you haven't played Catan <you should!>, 7 is reserved for the robber!]).
Where can I practice initial Catan placements?
You can practice placing your initial Catan settlements at Games Playbook. Games Playbook also has strategy guides for Catan, and other games.
What about the settlements and roads?
This is perhaps the most interesting part of the project! Each corner has a position for a settlement to go, and Catan rules state that settlements cannot be placed less than two places from each other.
You can place an element in almost every area required by adding only two elements to each hex and positioning them properly. The image below shows a different colour for each element.

When a player clicks a place for a settlement, the board object is updated to remove the available positions left on that hex, and the .taken class is added to the position, along with the player's colour class. The resource types that the settlement is touching are added to the player object's 'collected' property, which are later used when simulating dice rolls.
Here is the code for removing possible settlement positions from the board.
removePositions(positions:number[], row:number, col:number) {
this.board[row][col]["available"] = this.board[row][col]["available"].filter((item: number) => !positions.includes(item));
}
Typescript
Afterthoughts
If I were to build it again (and I might), I would likely use SVG to render the hexes, as they allow for greater flexibility (perhaps at the cost of an inflated DOM size - but the app is small as it is and wouldn't need to scale too much, even if built into a full game).
One thing I might still add is the option to place against an AI. Designing game AIs is always fun, and it might help practice certain positions more. The current state of the tool might make some people prioritise their earlier choices by making bad placements for later positions.
Building this app did help me get to better grips with Angular templating and bidirectional binding as well as help my Catan game. Who could ask for more?