Homework 2

Modified

Download

Completed homework example (without source code).

Download

Open HW4.xcodeproj (it really is HW2).

In Xcode, open Run | Run

 

Overview

Homework 1/1B implemented an Android TicTacToe game based on the Model-View-Controller design pattern.

Now the TicTacToe game will be implement on an iOS device.

You will see that while an MVC pattern is used, it requires some modification to fit into iOS organization.

Assignment

Implement an iOS TicTacToe game based on the Model-View-Controller design.

Change the Model from Homework 1 only to accommodate Objective C.

The ViewController should contain the logic of the HW1 and HW1B Controller. The View of the MVC is created by Interface Builder.

The Model-View-Controller design pattern consists of the three components.

In the above design, the Controller sends messages to the View and the Model; the Model and View do not communicate directly.

For example:

The Controller calls a Model method to update the model state and get model state.

The Controller calls View methods to set (display) the data.

For the TicTacToe game the responsibilities of each are:

Model

Maintain the game state (i.e. instance variables)
    board
    current player
Get game state
    board
    current player
    win - whether the board has a winning state
    game over - whether a win or no move possible
Set game state
    move
        Accept a valid move, changing board and player state
        Reject an invalid move

View

Interface Builder should be used to implement the View.

Controller

Construct a Model object.

Receive a button event (e.g. move)
Update a label (e.g. player)
Update a button title (e.g. the move button)

Send result of View's input to Model as move.
Continue as long as the game is not over.

MyModel - To get started, below is a translation of the Java version to Objective C.

#import <Foundation/Foundation.h>

@interface Model : NSObject
{
  char board[9];
  char player;
}
-(id) init;
-(char *) getBoard;
-(Boolean) setMove: (char) c;
-(char) getPlayer;
-(Boolean) getGameOver;
-(Boolean) getWin;
@end
 
#import "Model.h"
@implementation Model

-(id) init {
	self = [super init];
	player = 'X';
	board[0] = '0';
	board[1] = '1';
	board[2] = '2';
	board[3] = '3';
	board[4] = '4';
	board[5] = '5';
	board[6] = '6';
	board[7] = '7';
	board[8] = '8';
	return self;
}

-(char *) getBoard { return board; }

-(Boolean) setMove: (char) c {
    int at = c - '0';
	if(at < 0  || at > 8 || board[at]=='X' || board[at]=='O') 
		return NO;
	board[at] = player;
	if(player =='X')
		player = 'O';
	else
		player = 'X';
	return YES;
}

-(char) getPlayer { return player; }

-(Boolean) getGameOver {
    if([self getWin]) return YES;
    for(int i=0; i<9; i++)
        if(board[i] != 'X' && board[i] != 'O') return NO;
    return YES;
}
-(Boolean) getWin {
    return
    (board[0]==board[3] && board[3]==board[6]) ||
    (board[1]==board[4] && board[4]==board[7]) ||
    (board[2]==board[5] && board[5]==board[8]) ||
    (board[0]==board[1] && board[1]==board[2]) ||
    (board[3]==board[4] && board[4]==board[5]) ||
    (board[6]==board[7] && board[7]==board[8]) ||
    (board[0]==board[4] && board[4]==board[8]) ||
    (board[2]==board[4] && board[4]==board[6]);
}
@end

HINTS

  1. To perform initialization, such as creating objects, over-ride:

    - (void)viewDidLoad {
        [super viewDidLoad];
        // do initialization
        myModel = [MyModel new];
    }

  2. Set the title of each button to a digit 0-8.
  3. UIButton objects can call IBAction methods for specific events.
  4. The following casts the sender object that called the method to a UIButton.

    -(IBAction) buttonClick: (id) sender {
           UIButton *button = (UIButton *) sender;
     
  5. Connect all the buttons to a single IBAction method which converts the button title from a NSString to an integer.
  6. In Interface Builder, when connecting a button to the IBAction method, use Touch Up Inside.
  7. A button title can be changed to 'X' by:

      [button setTitle: @"X" forState: UIControlStateNormal];
     

TURN IN

Upload files to OnCourse as: