+1  A: 

Since Objective-C doesn't have class variables per-se (they're merely simulated using static variables), child classes can only directly access the static globals if you define the method in the same source file/compilation unit. This breaks other best practices (one class definition per compilation unit). The usual approach to access class fields is to use accessors.

In this case, be careful you don't couple the classes too tightly. Passing the board (as an object, not an array) to the Player (Person might be a better name, as a computer is also a player) and Computer, whether as a method parameter or a property, is more flexible than referring to a global or to a static member of another class. The player objects decide where to place, then tell the board where to place the piece. Alternatively, the game passes a read-only version of the board to a player; the player's placement method returns where to place a piece. For one thing, decoupling and using a board object can prevent cheating. Imagine someone injects their own Player class which lets them place multiple pieces on their turn. For another, the indirection it makes it easier to add network support (messages between objects become network messages in a process that is transparent to the local objects).

Think also about where the players are created. It might make more sense to have something else create the players and pass them to the startGame method. This would make sense if the players were competing in a tournament, for example, and the player objects thus needed to exist for longer than a single game.

Class composition refers to one object having another as a member. C, for example, didn't support inheritance, but let you nest structs. Another way of saying this is that class composition is about "has-a" relationships, while inheritance is about "is-a" relationships. The player classes, for example, could have a pointer to the board, which each uses to place pieces.

Objective-C also doesn't have pass-by-reference. Instead, it uses pointers.

Also, make sure your game handles ties. You might want to simplify the game loop to accomplish this. In pseudocode,

// nextPlayer returns 'nil' if game is over (win or tie)
while currPlayer := [game nextPlayer]:
    // player will tell board where to place piece
    [currPlayer move]

Or:

// nextPlayer always returns a valid player
while currPlayer := [game nextPlayer]:
    // player's method returns what and where to place
    [self place:[currPlayer move] for:currPlayer]
    // explicitly test for game end, which includes wins & ties
    if [game isOver]:
        break
outis
+3  A: 

As you have probably already figured out, Objective-C doesn't really have "class variables" that you can inherit from a super class.

One way to construct this such that you don't have to have global variable would be something like this:

You have a Game object that holds references to each of the Players, and to the Board. The Players are either each initialized with a reference to the Board. Your startGame method (in Game) would have code like this:

board = [[Board alloc] init];
player = [[Player alloc] initWithBoard: board];
computer = [[ComputerPlayer alloc] initWithBoard: board];

in the Board class, you'd have methods to query the state of the board, make a move, determine whether a move is legal, and maybe whether or not a player has won (though the game-rule-related logic might go in Game).

In the initWithBoard methods in Player and ComputerPlayer, you'd just retain the board instance, and use it to communicate the moves each player decides to make. The Game would establish the order of moves, and keep track of any global state. When the Player and ComputerPlayer are released at the end of the game, they'd release their reference to the board in their dealloc method.

Mark Bessey