I am trying to make a C++ implementation of the board game Carcassonne. I am trying to make a tile object which has four sides and one of three basic terrains(field, road, city).
The best interface for tile creation I could think of was of the form:
City city;
city_city_city_city = new Tile(city, city, city, city);
Where a Tile class is defined somewhat as follows...
class Tile
{
public:
Tile(Terrain& top_terrain,
Terrain& right_terrain,
Terrain& bottom_terrain,
Terrain& left_terrain)
{
top_side_.reset(top_terrain.Decorate(new TopSide()));
right_side_.reset(right_terrain.Decorate(new RightSide());
bottom_side_.reset(bottom_terrain.Decorate(new BottomSide()));
left_side_.reset(left_terrain.Decorate(new LeftSide()));
}
private:
boost::scoped_ptr<TopSide> top_side_;
boost::scoped_ptr<RightSide> right_side_;
boost::scoped_ptr<BottomSide> bottom_side_;
boost::scoped_ptr<LeftSide> left_side_;
};
I wanted the constructor to initialize each specific Side(TopSide, RightSide, BottomSide, LeftSide) that inherits from the base class Side. The idea was to define a virtual Decorate method in the Terrain class that would return an instance of a SideDecorator for the specific type of Terrain.
Depending on the Type of terrain the side has, it will have a different number/type of TerrainSegments. For example: A Side with a Field has the need for only one FieldSegment, whereas a Side with a Road needs three Segments: a RoadSegment and two FieldSegments. Thus the adding of a tile to the board will need Sides with different implementations and members.
I could make concrete classes like TopFieldSide, BottomRoadSide, etc, but I figured the decorator pattern would be cleaner. The thing I am not sure about however is whether or not the polymorphic use of the Decorate() method is a misuse.
Certainly I could create Tiles of the form:
Tile(CityDecorator(new TopSide),
CityDecorator(new RightSide),
FieldDecorator(new BottomSide),
RoadDecorator(new LeftSide));
But the previous version seems much cleaner.
My question being... Is this an acceptable approach or is there a simplier/cleaner way that I am missing?
My use of this approach is running me into coupling problems because I have to include the path to SideDecorator in Terrain and Terrain is used in SideDecorator and in derived classes. The simple directive #include "side_decorator.h" in the terrain.h causes many compile errors making it hard to tell if it is a forward declaration problem or what something else unoticed in my code...