BoardBuilder is a factory class used for creating Board model for the Farout game. In following I will briefly go through the design of the BoardBuilder and give you reasoning behind my decisions. In my next post I will go in more detail by showing you some source code and hopefully I have a working example as well.
By creating dedicated builder class we separate construction role from the model role that the Board class represents. It also keeps Board class simpler and makes it possible to change construction process without a need to touch Board’s implementation.
During the construction we have to allocate memory blocks which are no longer needed when construction has finished. By keeping those allocations in builder only it is easier for us to control how memory is used and when it is freed.
Construction process is divided into small simple steps to make source code easier to understand and maintain. As a rule of thumb every function has only one purpose and if I see copy paste code anywhere I will move that code into own function. I prefer a lot of small methods to few monolithic ones, therefore my classes usually have quite long definition.
Below is the static model of the BoardBuilder and after that you can find description of each class and their purpose.
Vertex represents single point in 2-dimensional world. It has x and y value defined as floating point numbers.
Segment represents one line segment that is constructed of two or more Vertices. Vertices are referenced by the Segments. Therefore same Vertex can be used in several Segments.
Hexagon represents one hexagon and is constructed of exactly six Segments. Neigbouring Hexagons share one segment with each other. Segments are referenced by the Hexagon instances, that way we can modify Segment and modifications are instantly visible in every Hexagon referencing the modified Segment.
Region is a tile that is constructed from one or more Hexagons. Region is defined as generic class and the unqualified type parameter is used for referencing the actual region data. Regions own instance of java.awt.Polygon that defines their shape. Polygon class is created because it can be used as a tool for several tasks. E.g.
- To check if certain point is located inside Region (e.g. region.shape().contains(x, y)).
- To mask (clip) textured blitting (e.g. graphics.setClip(region.shape())).
- To draw region borders (e.g. graphics.drawPolygon(region.shape())).
- To get maximum bounds of the Region (e.g. region.shape().getBounds()).
Board construction is handled by the BoardBuilder class. Construction parameters are given in a BoardBuilderParameters class. Construction happens in following order.
- Hexagonal Vertices are constructed
- Segments are constructed by connecting proper Vertices
- Hexagons are constructed by collecting proper Segments from all Segments
- Hexagons are dehexified as described in earlier post
- Regions are constructed from Hexagons by combining selected neighbour Hexagons, adjacency is validated when new Hexagon is added to a Region and if the added Hexagon is valid all, except the connecting Segment, are added to the Region
- Shape is constructed for each Region
- Board is created and ownership of the created Regions is transferred to the Board
- Created Board instance is returned to the caller and is ready to be used