Homework 2b

Modified

Download

Completed iPhone homework example (without source code) and TTTServer (with source code).

iPhone SDK Text source code

Extra

Installing application to the iPhone/iTouch.

Overview

Homework 1 implemented an Android TicTacToe game using the MVC pattern.

Homework 2 refactored Homework 1 to implement a iOS GUI TicTacToe game.

Homework 2b refactors Homework 2 to to implement a TicTacToe game with an iOS user playing against a computer somewhere on the Internet.

TicTacToe Server

The TTT server is implemented in Java and should run on most computers. The server is stateless.

Start the server by:

  1. Download Completed iPhone homework example.
  2. Navigate to TTTServer folder at the command line.
  3. At the command prompt enter:

    java TTTServer

The server receives the state of the game and returns a move between 0-8 or 9 (if there is no move possible).

The server plays X and expects O to move first.

O|O|2
-|-|-
X|4|5
-|-|-
6|7|8

For example, the game state above would be represented and sent to the server running on your computer by:

http://localhost:1490/?OO2X45678

sending to the server:

GET /?OO2X45678 HTTP/1.1

which returns the server move of: 2

The server listens on port 1490, accepting a connection, receiving the HTTP message, determining a move, and sending back to the client.

Note that O and X (capitalized) denote occupied board positions. Also that the server does not cheat.

// TTTServer - One connection on Port 1490

import java.net.*;
import java.io.*;

public class TTTServer
{
   public static void main(String args[]) throws Exception
   {
        ServerSocket connection = new ServerSocket( 1490 ); // Port 1490

        while(true) {
            Socket s = connection.accept();                     // Wait for connection

            BufferedReader in = new BufferedReader(             // Socket input and output
                                new InputStreamReader(
                                        s.getInputStream() ) );
            PrintStream out = new PrintStream(s.getOutputStream());

            String str;
            str=in.readLine();                                  // Read one line to \n or \r
            if (str != null) System.out.println( str );         // Echo input. Example:
        										// GET /?0X23XOOO8 HTTP/1.1
            int move = (new Computer()).move(str);              // Generate computer move
            System.out.println("Move " + move);
        
            out.print(move);                                    // Send computer move
                                                                 
            in.close();
            out.close();                                        // Close file
            s.close();                                          // Close connection
            System.out.println("Connection closed");
        }
   }
}

TicTacToe Client

A working client is in the HW2/TTTClient folder.

Start by opening the Xcode project, then Run. The TTTServer needs to be running before making any moves.

The TTT client should:

  1. Play O.
  2. Make the first move.
  3. As long as the game is not over, send the TTT server the game state and update the game state with the received move.
  4. Change button titles from 0-8 to O or X as legal moves are made.

Testing on an iPhone/iTouch - After your's works in the Simulator

  1. Go to the library and locate the iMacs.
  2. Check out one iTouch devices from the Reserves Desk.
  3. Follow the instructions for Installing to an iPhone, your provisioning profile needs to be downloaded and installed on the iMac.
  4. On an iMac, open Setting | Network and determine the IP address,
  5. Edit http://localhost:1490 in the app, replacing localhost with the IP address.
  6. Start the TTTServer as described above.
  7. For the iTouch.
    1. Open Settings and set WiFi to IU Secure.
    2. Connect an iTouch.
    3. In Xcode, open the HW2b project.
    4. Set Active SDK to Device
    5. Build and run HW2b on the iTouch.

TURN IN

Upload files to OnCourse as:

Hints

Client HTTP

Look over the example discussed in class.

Place the NSURL methods in the ViewController, its not good design but simplifies the NSURLConnection callbacks.

Since the server only returns a single character, you can expect that any -didReceiveData callback has data. This is a good place to update the game state (Model) and buttons (View).

 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;

Keyboard - dismissing

For the URL text field, to dismiss the keyboard:

  1. In .h view controller define : UIViewController <UITextFieldDelegate>
  2. In .m view controller override method:

    -(BOOL)textFieldShouldReturn:(UITextField *)textField{
        textField resignFirstResponder;
        return YES;
    }

  3. In .m file, in viewDidLoad: set the delegate for the text field:

    [ myTextField setDelegate: self];

Buttons

  1. The MyModel (HW1 Java) method getBoard returns a reference to an array. To do similar in Objective C define the MyModel method:
    -(char *) getBoard { return board; }
    

    The array elements can then be accessed by:

    char * b = [myModel getBoard];
    char c = b[3];
    

    which sets c to board[3] value.
     

  2. To change the button titles for the server response, a simple approach is to define IBOutlets for each button:
    IBOutlet UIButton *b0, *b1, *b2, *b3, *b4, *b5, *b6, *b7, *b8; 
    NSMutableArray *buttons;
    

     

  3. And initialize to an array of buttons with aliases to b0, b1,... in ViewController:
    - (void)viewDidLoad {
        [super viewDidLoad];
        buttons = [[NSMutableArray alloc] initWithObjects: b0, b1, b2, b3, b4, b5, b6, b7, b8, nil];
    }
    

     

  4. Connect the IBOutlets (b0, b1, ..., b8) to the UIButtons in IB as usual.
     
  5. Change the title of the button from the button array using the server move as an index.

    The following would change the title of button 4 to an 'X'.

    [[buttons objectAtIndex: 4] setTitle: @"X" forState: UIControlStateNormal];