2

I am writing an object oriented game for fun where players from two teams fight. I need to implement move function for players on a maze. Maze sohuld have location information with some features like height or type(hill, water etc.). So in order to implement location I have two ideas. First is that I need a Board class where I store location information in this class and also Location class which have x and y coordinates. Player class has reference to Board class.

class Board{
public:
    std::vector<Location> map;
};

class Location{
public:
    int x_coordinate;
    int y_coordinate;
    int height;
    Feature ground_feature;
};

Second idea is that instead of having Board class I will have Location class which has x and y coordinate and a static list of all coordinates in game. This location class will be a member of Player class.

class Location{
public:
    int x_coordinate;
    int y_coordinate;
    int height;
    Feature ground_feature;
    static std::vector<Location> map;
};

Could you please tell me which of these implementation ideas more solid and testable and why? Or What would be better idea to implement such a requirement.

2

First solution sounds a lot cleaner. The second gives each piece on the board knowledge about the complete board, which "feels" wrong.

Far better to have the board know about all the pieces on it by including a reference to each piece on the board. To do that, add a reference to the piece (if any) to your Location class. The pieces themselves then don't need any knowledge of where they are, the board will keep track of that for them.

0

I know this might be kind-of boring, but the first thing is to get into the right mindset. In object-orientation the data is of secondary concern. The important things are:

  1. What (business-)functionality do I want to support?
  2. What knowledge (not data!) do I have to have, and how do I localize them, so exactly one thing owns any given piece of knowledge?

So, because there is only one single functionality that we know of, there is obviously only 1 class needed. Let's call that the Board. The Board knows where things are, as well as the terrain, and it has a single public method called move.

I know, you are probably saying, that wouldn't support my other use-cases. That is probably right. The design needs to change with each new use-case. The biggest mistake usually made in object oriented design is to try to make things generic, thinking it will support any use-case in the future. This is usually done by just publishing its data, which is a huge mistake.

So don't publish data, publish (business!) functionality, and consider all (currently known) use-cases when designing, not more, not less.

0

This is just, possibly, off the wall, but I have been messing around in RDBMS code too much lately. Why not more classes. In particular, make the Feature location independent, and Location a first class concept by itself (no feature info):

// Prefer Immutable
class Feature {
  public:
   // Stuff
};

// Prefer Immutable
class Location{
  public:
    int x_coordinate;
    int y_coordinate;
    int height;
};

class PlayingArea{ // Board
  public:
    std::vector<Location> map;
};

// Immutable? 
class FeatureLocation { 
   public:
      Location location; // should be const
      Feature ground_feature; // Design decision: can change or make 
                              // immutable and replace with new
                              // FeatureLocation that has same Location
                              // or maybe make location a Decorator 
                              // (composable features) 
};

class Features{
  public:
    std::vector<FeatureLocation> map;
};

This slices the data differently, but looks like it will handle the data in more coherent chunks, and possibly more amenable to partitioning the business rules related to game setup, execution and, (if using some computer run algos) evaluation.

The master class (Game? Scenario? Instance?) would have to create and manage the Features, Board and FeaturesLocation, but the other are more amenable to static initialization OR dynamic plugins.

Anyway, not knowing more about the game rules and engine, this is how I'd begin.

0

First of all...

The two options you have are not necessarily mutually exclusive. You could, for example, make your Location an immutable value type that is generated by your Board. The Board still decides the location (option 1), but a Location can be passed around or stored as a value (option 2).

The important thing to consider here is that there is only one true source of information (the Board). If the Board is the one who creates all Locations, the Board should never adjust itself based on a Location it receives (because that creates a source of potential misinformation). The Board's knowledge is considered to be correct. Other sources either contain an equally correct value or are considered wrong (and in either case, you should use the Board's value).


However...

If you're choosing only one option, option 1 is the cleanest.

Option 2 only works if all classes that use locations and communicate with one another are on the same page. This violates DRY (multiple classes have the same Location handling), is prone to error (what if one class handles it differently?), and unintuitive (a location is a shorthand name for a "board location"; a location is meaningless if it's not in scope of a board).

Taking inspiration from server-client architecture, the Player class' interaction with the Board should consist of the actions a player can take (MoveUp, MoveDown,MoveLeft,MoveRight). The Board then translates that action into a movement change.

This ensures that your player doesn't need tile checking logic. For example, let's say that if the next tile is ice, the player therefore slides across it and has moved 2 tiles even though they intended to only move 1 tile.
You don't want the Board to blindly rely on the Player making the correct move; what if the Player is unaware of the board state? (e.g. the ice tiles have only formed recently)?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.