Homework 2b |
Modified: |
Download
Completed iPhone homework example (without source code) and TTTServer (with source code).
Extra
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:
- Download Completed iPhone homework example.
- Navigate to TTTServer folder at the command line.
- 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|8For example, the game state above would be represented and sent to the server running on your computer by:
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:
- Play O.
- Make the first move.
- As long as the game is not over, send the TTT server the game state and update the game state with the received move.
- 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
- Go to the library and locate the iMacs.
- Check out one iTouch devices from the Reserves Desk.
- Follow the instructions for Installing to an iPhone, your provisioning profile needs to be downloaded and installed on the iMac.
- On an iMac, open Setting | Network and determine the IP address,
- Edit http://localhost:1490 in the app, replacing localhost with the IP address.
- Start the TTTServer as described above.
- For the iTouch.
- Open Settings and set WiFi to IU Secure.
- Connect an iTouch.
- In Xcode, open the HW2b project.
- Set Active SDK to Device
- Build and run HW2b on the iTouch.
TURN IN
Upload files to OnCourse as:
- a single compressed directory named HW2b containing the complete project for the HW2b application.
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:
- In .h view controller define : UIViewController <UITextFieldDelegate>
- In .m view controller override method:
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
textField resignFirstResponder;
return YES;
}- In .m file, in viewDidLoad: set the delegate for the text field:
[ myTextField setDelegate: self];
Buttons
- 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.
- 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;
- 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]; }
- Connect the IBOutlets (b0, b1, ..., b8) to the UIButtons in IB as usual.
- 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];