Reputation: 118
This is a design question and I'm going to frame it as clearly as possible, but I'm not really sure what to call the problem I'm facing.
I'm working on a video game, and setting up and playing the game involves multiple steps. I wanted to wrap each of these steps in some sort of object, to keep everything clean.
I chose to split up the flow of the game into sessions, rounds and spawns. A session of the game is the highest scope level, you configure which players are active (through a join screen) then proceed to start a round. You can play multiple rounds within a single session, and each of those rounds will inherit the global session data. Likewise, you can die and respawn multiple times in each round, inheriting data from both the round and the session.
So imagine somesort of free.
Spawn 1 will have access to data from Round B and Session 2.
This seems like a pretty clean design. I can keep the session-wide data in one place and keep that object alive through the entire session, with each round branching off and inheriting this data.
Now the interesting issue. Like I said before, the session contains a collection of players (the ones that joined the game and are active during the whole session). The round ALSO needs to keep some additional data about each player, but that data only exists inside a round (the last spawn point for instance, or the current score). I wanted to follow the same pattern and create another class, which would hold this round-specific data.
Where this breaks down is when maintaining the collections. Because the session contains the authoritative list on players, and each round provides additional add-on data, should the round just update a member of the SessionPlayer? Should the round have its own list of players, each with the round-level data and a pointer up to the session-level data? Should they contain separate collections with matching ids?
This seems like something that could be solved with a clever design pattern, but I haven't been able to find one.
To summarize: How to temporarily wrap an object containing a collection, while wrapping all the elements of that collection as well?
I hope I explained that properly. Thanks for the help!
Upvotes: 3
Views: 118
Reputation: 10357
To answer your final question first:
To summarize: How to temporarily wrap an object containing a collection, while wrapping all the elements of that collection as well?
This can be achieved with a Composite Design pattern, where a class contains elements of itself and the class can be stand-alone, or a container. Operations on this class will work on itself and on each of the elements it contains.
Regarding your previous questions about where to store the Players, this is a bit more difficult, but you should consider the following when deciding:
If its absolutely necessary to have these bi-directional references, then possibly the best way to implement it would be with Dependency Injection. This will simplify the typical headaches involved with maintaining bi-directional references. Try to only inject the most specific entities needed, and not just the entire root-level object, like the Session.
Upvotes: 2
Reputation: 1973
So there are SessionPlayer and RoundPlayer classes. How about making RoundPlayer a nonstatic member class of SessionPlayer? This way, you can maintain 2 different collections, 1 for Session and 1 for Round with RoundPlayer implicitly having a reference to SessionPlayer.
Upvotes: 0