I am trying to create a C ++ version of the Carcassonne board game. I am trying to make a tile object that has four sides and one of the three main landscapes (field, road, city).
The best tile creation interface I could think of is of the form:
City city; city_city_city_city = new Tile(city, city, city, city);
If the 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), which inherits from the base side of Side. The idea was to define a virtual Decorate method in the Terrain class that would return a SideDecorator instance for a specific Terrain type.
Depending on the type of terrain that has a side, it will have a different amount / type of TerrainSegments. For example: A side with a field requires only one FieldSegment, while a side with a road needs three segments: RoadSegment and two FieldSegments. Thus, adding tiles to a board will require parties with different implementations and members.
I could create specific classes like TopFieldSide, BottomRoadSide, etc., but I decided that the decorator pattern would be cleaner. However, I am not sure if the polymorphic use of the Decorate () method is a misnomer.
Of course, I could create Tiles forms:
Tile(CityDecorator(new TopSide), CityDecorator(new RightSide), FieldDecorator(new BottomSide), RoadDecorator(new LeftSide));
But the previous version looks a lot cleaner.
My question is: ... Is this an acceptable approach or is there a simpler / cleaner way that I am missing?
My use of this approach leads me to communication problems, because I have to include the path to SideDecorator in Terrain, and Terrain is used in SideDecorator and in derived classes. The simple #include directive "side_decorator.h" in terrain.h causes a lot of compilation errors, making it difficult to determine if this is a direct declaration problem or something else invisible in my code ...