handling data/state in a board game - composition/coupling

Started by
9 comments, last by Mussi 8 years, 4 months ago

To me this looks like a case of trying to model your objects based on reality, which translates poorly to objects used in programming. Take your board class for example, in real life the board holds all the cards, squares, bank, money pot etc. While this makes sense in real life, it causes these weird relations in programming that are ineffective. Buying a deed, or any other action now requires you have knowledge of the board and bank classes, which is unnecessary and causes these tight couplings.

A very simple alternative I'd start out with:


struct GameData
{
    containers<Squares> board;
    container<Player> players;
    container<Deed> availableDeeds;
    int activePlayer;
};

void buyDeed(Player& player, container<Deed>& deeds, ID deedID)
{
    Deed* deed = deeds.find(deedID);
    if(deed && player.money >= deed->cost)
    {
        player.ownedDeeds.add(deed);
        deeds.remove(deedID);
        player.money -= deed->cost;
    }
}

Buying a deed now only has a notion of a player and available deeds, which is really all it needs. The board and bank classes no longer exist in this example, which doesn't mean you won't need them at all, but for now they're not necessary so I'd avoid designing them before you have a use case. My advice would be to focus on how your data will flow through your program; what data do I need and what do I spit out. Mike Action puts it this way: the transformation of data is the only purpose of any program. So instead of modelling the data first, write procedures that need that data and then decide upon a model that best fits that need.

As for your second question on where buyDeeds should go, there's no harm in having free functions if you feel like it doesn't belong to some class. If you have a group of functions that are related you can always put them in their own namespace.

This topic is closed to new replies.

Advertisement