2

I'm putting together a program to try and recreate a board game. My goal was to keep the rules and actually actions of the game separate from its presentation, so I am creating a library that contains the objects and methods that define what you can do as you play the game. Besides the classes that define the games objects, I was planning to create two classes to "front" the game. The first class GameRunner was the class that the presentation layer would use to call actions on the game such as AddPlayer, TakeGems, BuildCard etc. Then I wanted a second class to handle the game state, aptly named GameState, that would keep track of the players and their field, as well as the market for the game. In GameState I created the methods that would affect the game state to define how players are added and cards are purchased.

What I have noticed is that all of the game logic is being defined in GameState and GameRunner now is essentially just turning into a pass through class, in other words, all it does is call the appropriate method in GameState and return the state object:

public GameState AddPlayer(string name)
{
    gameState.AddPlayer(name);
    return gameState;
}

This just seems repetitive to me. Does this make sense as a design? A separation of concerns between actions and what they do? Or should I just make GameState a class that has the objects that make the state of the game, and just have GameRunner manipulate those state fields from it's methods instead. Example:

public GameState AddPlayer(string name)
{
    if(Players.Count < 4)
    {
        gameState.Players.Add(new Player(name))
        gameState.Success = true;
    }
    else
    {
        gameState.Success = false;
    }

    return gameState;
}
  • 1
    Why does AddPlayer return the gameState object to the caller?? This seems to break encapsulation. – Doc Brown May 30 '15 at 6:42
  • @DocBrown The idea was that something would return the whole state of the game to the UI (whatever it ends up being) that would always describe the whole state of the game instead of just the change made. It didn't necessarily need to be GameState but for now I do that to remind myself that the whole state is being returned. – Evan Frisch May 30 '15 at 13:28
2

By returning GameState from your GameRunner functions, you are making the client of GameRunner dependent on GameState as well. IE the GameRunner client knows the details of GameRunner's implementation.

I think the delegation of tasks to the GameState (as in the first example) is the better of the two options, thus when the logic of (in this instance) adding a player to a Game changes, it's only required to be updated in one place: the GameState itself.

The GameRunner acts as an Anti Corruption Layer translating between the concerns of the Presentation Layer and that of the game's engine. As such it should contain presentation logic, and delegate changes to the game to GameState. If the GameRunner were to be concerned with the logic of the game as well, it would violate the Single Responsibility Principle. (There should be only one reason for a module, class, or function to change). It would now have to change if the presentation logic needed an update, or if the game logic needed to change.

  • Thanks. That makes more sense of it that I could have. Since I'm thinking of having multiple ways of presenting the game, potentially a WPF app then possibly trying to host it online, does it make sense to have GameRunner focus on only one of those implementations and then later create a transformation layer to convert it to what the other presentation would need? – Evan Frisch May 30 '15 at 13:26
  • 1
    @Walker: you might transform this into a MVVM architecture (see en.wikipedia.org/wiki/Model_View_ViewModel). Model=GameState, View = your WPF classes, ViewModel=GameRunner, or an MVP architecture (Presenter=GameRunner). That way, your GameRunner depends only of an interface to the Presentation layer, which makes it easier to exchange the Presentation layer later. – Doc Brown May 30 '15 at 18:03
  • 1
    @DocBrown I'll have to take a look more into MVVM and MVP to pick one but that seems like exactly the kind of structure I'm looking for. Thanks a lot! – Evan Frisch May 30 '15 at 18:20

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.