views:

28

answers:

2

I'm creating a simple app which has a list of characters and a list of (4) players, the players is simply a reference to a playable character.

I'm stuck on how to do the following:

  1. Make a reference to the current player on turn
  2. Find out who the next player on turn is
  3. Handling the last player so that it will return to the first player on turn.

Ideally, I would like to be able to do AFTER, FIRST, LAST BEFORE commands on a NSMutableArray, of these I'm able to do lastObject, but there is no firstObject, afterObject, etc.

I believe you can fake BEFORE,AFTER,FIRST commands with objectAtIndex; but ideally I do not want to rely on numeric references because it could be incorrect -- also if its mutable, the size will always change.

Typically, I would be able to do the following in Pseudocode.

Global player_on_turn.player = Null //player_on_turn is a pointer to the player object

; Handle next player on turn
If (player_on_turn.player = Null) Then Error("No player on turn assigned")
If (sizeOf[playerList]==0) Then Error("There are no players in the game")
If After player_on_turn = null Then
  ; We reset it
  player_on_turn.player = First player
Else
  ; Move to the next player on turn
  player_on_turn.player = After player_on_turn.player
End If

With this in mind, what is the best strategy to help handle a player on turn concept as described in the 1-2-3 example above.

Thanks

A: 

Use a State Pattern for the main runloop of the software. Draw it out as a diagram and create variables to control which state the system is in.

You should use a circular list of the players to return current, next, and previous players.

This is also a great question for GameDev on the Stack Exchange.


PS

CocoaHeads puts out a relatively nice set of data objects, including a circular buffer.

Stephen Furlani
Okay, I'll take a look at this. Thanks.
zardon
+1  A: 

It probably doesn’t matter what data structure you’re using - at some level you will have to rely on a numerical index (except if you are using linked lists). And this is alright. If you don’t want to use it in your main game implementation that is alright, too. Just create a class that encapsulates those things. First think of the operations you need it to support. My guess here would be those:

- (PlayerObject *) currentPlayer;
- (void) startNextTurn;

If you have this you can write your game using those primitives and worry about how to best implement that later. You can change those at any time without breaking your actual game.

My recommendation would be something like this:

- (PlayerObject *) currentPlayer; { 
    return [players objectAtIndex: currentPlayerIndex]; 
}

- (void) startNextTurn; {
    ++currentPlayerIndex;
    if (currentPlayerIndex >= [players count]) {
         currentPlayerIndex = 0;
    }
 }

Using the index there is OK, even if the array is mutable. If you have methods that change the player array they also can take care of the necessary changes to the currentPlayerIndex.

Having this object makes it easy to write unit tests. The global variable you suggest in your pseudo-code makes it impossible to write meaningful unit tests.

Sven
Yes, I think this would be a much better way to do it -- I really don't want to go down the road of learning state patterns or more complex things for something that appears to be straight-forward.
zardon