The Problem
I would like to create a managing "overseer" class that connects several related object groups together where any particular group is able to be easily swapped for another using C++11 syntax.
A secondary goal of finding a good approach to code structure is to make the underlying code run quickly (since it will be used for conducting many simulations).
For context, this particular problem is something I have encountered in several other programming languages, but have not been able to find a great solution for in a compiled language.
Minimal Example
Classes
- Arcade
- ArcadeGame
- ArcadeScreen
- ArcadeMove
- ArcadePlayer
Problem Definition
- Suppose there exists an
Arcade
which sets up anArcadeGame
every day for tournaments. - Each
ArcadeGame
displays anArcadeScreen
as its output and accepts anArcadeMove
as its input. - Each
ArcadeMove
andArcadeScreen
is unique to theArcadeGame
(e.g.: aGalaxySpacewarGame
has different attributes in itsArcadeMove
than aCombatFighterGame
). - An
ArcadePlayer
for any particular game must be able to take theArcadeScreen
as input and output a validArcadeMove
for that game. - The role of
Arcade
is to setup theArcadeGame
, ensure theArcadePlayer
is one that can actually play the game, and monitor the in-progress game to record the score of the player to a scoreboard.
Pseudocode of the listed classes
The following classes share these functions:
ArcadeGame
Restart()
ArcadeScreen GetScreen()
InputMove(ArcadeMove a)
int GetScore()
bool IsOver()
ArcadePlayer
ArcadeMove GetInput(ArcadeScreen a)
Arcade
Arcade(ArcadeGame g) // constructor
int PlayTournamentGame(ArcadePlayer p):
g.Restart()
while NOT activeTournamentGame.IsOver():
ArcadeMove m = p.GetInput(g.GetScreen())
g.InputMove(m)
return g.GetScore()
The classes will then be used like so:
GalaxySpacewarGame spaceGame = new GalaxySpacewarGame(someConfigParams1);
GalaxySpacewarPlayer john = new GalaxySpacewarPlayer(someConfigParams2);
Arcade someArcade = new Arcade(spaceGame)
for(int i = 0; i < 100; i++):
std::cout << PlayTournamentGame(john) << std::endl;
Attempted Approaches
- I was taking a look at type erasure specifically as a way of ensuring the
Arcade
class does would not require knowledge of theArcadeScreen
s for any of its games but do not see an easy way to enforce compile-time validation to ensure theArcadePlayer
is able to play that specific game. I am also unfamiliar with this specific design approach and would like to ask for a second opinion on whether it applies in this case. - I have also taken a look at the visitor and double dispatch patterns, but it does not look like any of those alone would be useful for this kind of architecture.