How to Develop an iPad Board Game App: Part 1/2

In this tutorial, you’ll learn how to create a more laid-back kind of game: the classic board game. Specifically, you will create the time-honoured classic Reversi for the iPad, using plain UIKit. By Colin Eberhardt.

Leave a rating/review
Save for later
Share
You are currently viewing page 2 of 5 of this article. Click here to view the first page.

Additional Game State

Now that you have a class representing the state of each square, you’ll create a class to hold the rest of the game state, such as the score for each side.

Highlight the ‘Model’ group in the project and create a new file using the iOS\Cocoa Touch\Objective-C class template. Name this new class SHCReversiBoard and make it a subclass of SHCBoard.

Open up SHCReversiBoard.h, and add the following code after the @interface line:

// the white player's score
@property (readonly) NSInteger whiteScore;

// the black payer's score
@property (readonly) NSInteger blackScore;

// sets the board to the opening positions for Reversi
- (void) setToInitialState;

You can let Xcode automatically synthesize those two properties. Open up SHCReversiBoard.m add the following method implementation (just beneath the @implementation line):

- (void)setToInitialState
{
    // clear the board
    [super clearBoard];
    
    // add initial play counters
    [super setCellState:BoardCellStateWhitePiece forColumn:3 andRow:3];
    [super setCellState:BoardCellStateBlackPiece forColumn:4 andRow:3];
    [super setCellState:BoardCellStateBlackPiece forColumn:3 andRow:4];
    [super setCellState:BoardCellStateWhitePiece forColumn:4 andRow:4];
    
    _whiteScore = 2;
    _blackScore = 2;
}

The above code sets the initial starting point of a game of Reversi: two black playing pieces and two white, occupying the centre four squares of the board.

Would you like to practice your unit testing skills? Try adding a unit test for the above method!

Now that the board is set to its initial state, you’ll need to create a View so that the players can see the gameboard on screen.

Visualizing the Board

The starter app has a background image for the entire playing field. However, you need to create a view to place on top of each board square, that will contain the appropriate image for that square (white piece, black piece, or empty).

To do this, highlight the ‘View’ group in the project and create a new file with the iOS\Cocoa Touch\Objective-C class template. Name the class SHCBoardSquare and make it a subclass of UIView.

Open up the newly created header file SHCBoardSquare.h. The board square needs to know about the board as a whole, so add one more #import as below:

#import "SHCReversiBoard.h"

Then add the following method declaration after the @interface line:

- (id) initWithFrame:(CGRect)frame column:(NSInteger)column row:(NSInteger)row board:(SHCReversiBoard*)board;

Each square will be initialized with its row and column position, and each square will also know which board it belongs to.

“Wait”, you may be saying. “I thought we only had one board here? What’s going on?”

Later on in the tutorial, you’ll be using multiple boards to implement computer opponents — but for now just leave the declaration as-is so that you don’t need to rework everything later on.

Open up SHCBoardSquare.m. Replace the implementation with the following code:

@implementation SHCBoardSquare
{
    int _row;
    int _column;
    SHCReversiBoard* _board;
    UIImageView* _blackView;
    UIImageView* _whiteView;
}

- (id)initWithFrame:(CGRect)frame column:(NSInteger)column row:(NSInteger)row board:(SHCReversiBoard *)board
{
    self = [super initWithFrame:frame];
    if (self) {
        
        _row = row;
        _column = column;
        _board = board;
        
        // create the views for the playing piece graphics
        UIImage* blackImage = [UIImage imageNamed: @"ReversiBlackPiece.png"];
        _blackView = [[UIImageView alloc] initWithImage: blackImage];
        _blackView.alpha = 0.0;
        [self addSubview:_blackView];
        
        UIImage* whiteImage = [UIImage imageNamed: @"ReversiWhitePiece.png"];
        _whiteView = [[UIImageView alloc] initWithImage: whiteImage];
        _whiteView.alpha = 0.0;
        [self addSubview:_whiteView];
        
        self.backgroundColor = [UIColor clearColor];
        
        [self update];
    }
    return self;
}

// updates the UI state
- (void)update
{
    // show / hide the images based on the cell state
    BoardCellState state = [_board cellStateAtColumn:_column andRow:_row];
    _whiteView.alpha = state == BoardCellStateWhitePiece ? 1.0 : 0.0;
    _blackView.alpha = state == BoardCellStateBlackPiece ? 1.0 : 0.0;
}

@end

The initWithFrame:column:row:board: method stores the various arguments that are passed to it as instance variables. It also creates two UIImageView instances: one to display a black playing piece and the other to display a white playing piece.

The update method shows or hides the black or white images depending on the state of the cell that it represents. If there is no playing piece in the square, both image views are hidden.

Okay, so that takes care of a single cell on the board. The next section shows you how to arrange these single cells into a full gameboard!

Views^2 – Views in Views

In order to render the board, you’ll need 8×8 or 64 instances of SHCBoardSquare properly positioned on screen. To keep things organized, you will set up another view that will hold the 64 squares.

Highlight the ‘View’ group in the project and create a new file with the iOS\Cocoa Touch\Objective-C class template. Name the class SHCReversiBoardView and make it a subclass of UIView.

Open up SHCReversiBoardView.h. Add the following import to the top of the file so your board view will know about boards:

#import "SHCReversiBoard.h"

Then you can add the declaration for the designated initializer underneath the @interface line, as such:

- (id)initWithFrame:(CGRect)frame andBoard:(SHCReversiBoard*) board;

Okay, now it’s time to flesh out the implementation of this method. Open up SHCReversiBoardView.m and replace the current contents with the code below:

#import "SHCReversiBoardView.h"
#import "SHCBoardSquare.h"

@implementation SHCReversiBoardView

- (id)initWithFrame:(CGRect)frame andBoard:(SHCReversiBoard *)board
{
    if (self = [super initWithFrame:frame])
    {
        float rowHeight = frame.size.height / 8.0;
        float columnWidth = frame.size.width / 8.0;
        
        // create the 8x8 cells for this board
        for (int row = 0; row < 8; row++)
        {
            for (int col = 0; col < 8; col++)
            {
                SHCBoardSquare* square = [[SHCBoardSquare alloc] initWithFrame:CGRectMake(col*columnWidth, row*rowHeight, columnWidth, rowHeight) column:col row:row board:board];
                [self addSubview:square];
            }
        }
        
        self.backgroundColor = [UIColor clearColor];
    }
    return self;
}

@end

In the code above, the rowHeight and columnWidth sizes are first calculated. You'll hold on to these values to set the size and positioning of the 64 squares on the board.

Next up is a double for loop to set up the 8x8 grid. For each turn of the inner loop, a new instance of SHCBoardSquare is allocated and positioned.

Now that the view is set up, it's time to glue everything together to create the Reversi Board and View within the application’s view controller!

Open up SHCViewController.m and add the following imports at the top of the file:

#import "SHCReversiBoard.h"
#import "SHCReversiBoardView.h"

Then, just beneath the @implementation, add the following instance variables:

@implementation SHCViewController
{
    SHCReversiBoard* _board;
}

Next, add the lines below at the end of viewDidLoad:

// create our game board
_board = [[SHCReversiBoard alloc] init];
[_board setToInitialState];
    
// create a view
SHCReversiBoardView* reversiBoard = [[SHCReversiBoardView alloc] initWithFrame:CGRectMake(88,151,600,585) andBoard:_board];
[self.view addSubview:reversiBoard];

Here you create your game board model class, as well as the view for the model.

The CGRect used as the frame for the SHCReversiBoardView has been carefully measured to align with the PNG image that is the background for this application.

Build and run to see the fruits of your labour:

Cool - your app is starting to look like a real game now!

Well, a pretty board is fun to look at, but your prospetcive players will be itching to put some pieces on the board. Fortunately, the next section lets you do just that.

Colin Eberhardt

Contributors

Colin Eberhardt

Author

Over 300 content creators. Join our team.