3

I am currently attempting to make a Trading Card Game and I have got a whole array of features working already, yet I am stuck now at the portion where one player can attacker another player (more strictly: the monster cards of another player on the field). The game is designed primarely to be played with two players in mind, though having it open for future extensions is never a bad idea.

This is the design I have so far, shown as a minimalistic example in pseudo-code:

class Game
 private final Player self
 private final Player opponent
class Player
 private final String name
 ...

The game loops over all players and lets them do their turn, which may involve attacking another player. That method has the following structure:

class AttackMonsterAction
 private final int monsterIndex
 private final int targetMonsterIndex
 private final Player targetPlayer
 public void performAction(final Player player)

If it is of any relevance, I am coding this in Java.

My concrete question is the following: How do I create my class design such that AttackMonsterAction called from a certain Player object, can reference "the other player"?

asked May 19, 2014 at 9:34
6
  • A nice and clean way for me would be to be able to access the owner of a monster from the monster's data. If you have some map where you use the monster id (or index) for key and the player that owns it, or even a monster object that has the owning player as a property, then you would not even pass the player in the action. Commented May 19, 2014 at 10:17
  • Why would you like to refer to "the other player"? Don't! Imagine, you want somewhat later to implement that the monster of a player can attack another monster of the same player. Refering to the other player is useless in this case. So the monster needs some kind of controller. It then tells to its controller "I got attacked and took 2000 damage points" or something like that. The controller then knows both players and knows what monster belongs to which player so it can handle all the stuff that has to be done next. Commented May 19, 2014 at 15:43
  • @valenterry The concrete action does not depend on "the other player", it only needs two players and two monster indices as input and will do whatever you ask it to do. I do however, from within the GUI for example, need to determine whom is the opponent in regular play. Commented May 19, 2014 at 15:44
  • I also see some drawbacks with the GameState solution from @GrahamA. It seems nice first, but it makes it for example harder to test, because an AttackMonsterAction does not have to know for example how many turns have been made - so you should not bother it with information from a GameState that it does not need or care of. Commented May 19, 2014 at 15:45
  • @valenterry I see where the confusion came from on AttackMonsterAction, I updated it to reflect my current version where it does include the targetPlayer. Commented May 19, 2014 at 15:46

1 Answer 1

4

A couple of options come to mind:

  • Pass a GameState object to performAction, the GameState represents the current environment including the other palyer(s) and game board. This would allow you to move performAction into an interface and use it for your other actions such as move and hide

  • Use a Mediator Object 2 to manage the interaction between the two players.

Regarding adding more players in the future; sounds like a big redesign so apply the XP principal of "You aren't gonna need it " and dont add it yet. Write tests to prove that the game works and then when you want to add more players use you tests to make sure that the two player game still works.

answered May 19, 2014 at 10:16
1
  • 1
    +1 for the GameState-object. I would also consider making the GameState-object immutable, which may sound counterintuitive at first but could lead to the simplest and most efficient design. If the performAction-method actually mutates the state instead of just returning a new object representing the state after the action, you'll soon need to make a copy of the state before each performAction-call for backtracking purposes. (Think about an undo feature or a backtracking AI or a complex action that could fail halfway through, leaving behind an undefined game state...) Commented May 19, 2014 at 13:14

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.