Homework 1B

Internet

Modified

Overview

The purpose of the assignment is to gain Android Internet and threads development experience. The assignment is to extend the Homework 1 implementation of a TicTacToe game to where a human and computer compete. The computer player is already implemented as a TCP Internet server.

Here is a video of play.

The server expects to receive the current board state with X, O or 0-8. Sending the server:

GET /?X123456OO

which has an X in position 0 and O's in 7 and 8, the response move should be 6.

Read the Android notes on the Internet.
 

ASSIGNMENT

Refactor the Android TicTacToe game of Homework 1 to play the computer server listed below.

Suggested start:

  1. copy and paste the following TTTServer example,
  2. compile and execute in terminal window by:

    javac TTTServer.java
    java TTTServer

  3. determine the IP number of the computer you're using:

    Windows command prompt: ipconfig /all

    Mac: open System Preferences | Networking
     

  4. test that the TTTServer is working by entering in a browser (not Safari) with a computer running TTTServer (using the discovered IP on your computer of 192.168.1.75)

    http://192.168.1.75:1490?X123456OO

    which has an X in position 0 and O's in 7 and 8. The response move by TTTServer should be 6.
     

  5. now the hard part, implement your Android client. From HW1, should need to change only MyController.
TTTServer.java
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
            System.out.println( str );                               // Echo input, ex. 012345678 or oo2x45678
        
            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 stream
            s.close();                                                      // Close connection
            System.out.println("Connection closed");
        }
   }
}
Computer.java
/**
 * Computer class - Plays an unbeatable game of TicTacToe.
 * 
 * @author Ray Wisman 
 * @version 1.0
 */
public class Computer
{
    public Computer(){}

/**
 * get - Converts char at String offset to int.
 */
    private int Get (String Str, int Off) {  
        return Convert.asInt(Str.charAt(Off));
    }

/**
 * move - Determines computer move.
 * 
 * Originally written by Stephen Wassell in JavaScript
 * swassell@sv.span.com
 */
    public int move (String inputBoard)          // Computer plays 'X'
    {
        char [] board=new char[9];
		boolean empty = true;
        
        int n = inputBoard.indexOf('?');
		for(int i=0; i<9; i++) { 
			board[i] = inputBoard.charAt(i+n+1); 
			if(board[i] != '0'+i) empty = false;
			System.out.print(board[i]); 
		}
		if(empty) return 4;					// If board empty, move to 4
        
        String PosLines, Order = "2613", PosCorns = "013215637857";
        int j, i, a, b, c;                           
        int [] Dat = new int[9];
        
        for(i=0; i<9; i++) {
            Dat[i]=0;
            if (board[i]=='X') Dat[i]=1;
            if (board[i]=='O') Dat[i]=3;
        }

        if (board[4] == 'X')    //if computer's in center
            PosLines = "021687063285435417408426";
        else            
            PosLines = "408426021687063285435417";
            
        for (j = 0; j < 4; j++) {
            for (i = 0; i < 24; i += 3) {
                a = Get (PosLines, i);
                b = Get (PosLines, i + 1);
                c = Get (PosLines, i + 2);
                if (Dat[a]+Dat[b]+Dat[c] == Get (Order, j)) {
                    if (board[a] == Convert.asChar(a)) return a; 
                    if (board[b] == Convert.asChar(b)) return b;
                    if (board[c] == Convert.asChar(c)) return c;
                }
            }
            
            if (j == 1) {       //only between 2nd and 3rd passes
                for (i = 0; i < 12; i += 3) {

                    a = Get (PosCorns, i);
                    b = Get (PosCorns, i + 1);
                    c = Get (PosCorns, i + 2);
                    if (Dat[a]+Dat[b]+Dat[c] == 6)
                        if (board[a] == Convert.asChar(a)) return a;
                }
            }
        }
        return 9;              //no place to go
    }
}
Convert.java
/**
 * Convert class - Converts i2a and a2i.
 * 
 * @author Ray Wisman 
 * @version 1.0
 */
public class Convert
{
    public Convert(){}
    
/**
 * asChar - Returns an int 0-9 as char '0'-'9'.
 */
    public static char asChar( int n ) {
        return (char)(48+n);
    }
    
/**
 * asInt - Returns a char '0'-'9' as int 0-9 .
 */
    public static int asInt( char ch ) {
        return (int)(ch-48);
    }
}

TURN IN

HINTS

int buttons[] = {R.id.button0, R.id.button1, R.id.button2, R.id.button3, R.id.button4, R.id.button5,R.id.button6, R.id.button7, R.id.button8};

the following would then change the 5 button to an 'X':

move = '5';
final Button b = (Button) view.findViewById(buttons[move-'0']);
b.setText("X");

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="edu.ius.rwisman.Echo"
    android:versionCode="1"
    android:versionName="1.0">
  <uses-sdk android:minSdkVersion="13" />
  <uses-permission android:name="android.permission.INTERNET"></uses-permission>
  <application android:icon="@drawable/icon" android:label="@string/app_name">
   <activity android:name=".EchoActivity"  android:label="@string/app_name">
    <intent-filter>
      <action android:name="android.intent.action.MAIN" />
      <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
   </activity>
  </application>
</manifest>