package client;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.concurrent.Semaphore;

public class ClientReceive implements Runnable {

	private int receivePort;
	public static ArrayList<ArrayList<Character>> tileMap;

	public ClientReceive(int port) {
		receivePort = port + 1;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		byte[] receiveData = new byte[1024];
		DatagramPacket receivePacket = null;
		MulticastSocket multicastSocket = null;
		InetAddress group = null;
		Semaphore semaphore = new Semaphore(0);

		startLobbyLogic(String.valueOf(Client.playerNum).trim());

		// Create multicasting socket for receiving gameview updates
		try {
			group = InetAddress.getByName("224.224.224.224");
			multicastSocket = new MulticastSocket(receivePort);
			multicastSocket.joinGroup(group);
			multicastSocket.setReuseAddress(true);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			multicastSocket.close();
			e.printStackTrace();
		}
		
		// Start menu, waiting for a client to connect
		while (Client.startLobby) {
			receiveData = new byte[1024];
			
			try {
				receivePacket = new DatagramPacket(receiveData,
						receiveData.length, group, receivePort);
				multicastSocket.receive(receivePacket);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				multicastSocket.close();
				e.printStackTrace();
			}
			String received = new String(receivePacket.getData()).trim();
			startLobbyLogic(received);

		}
		
		
		//Create first instance of game board
		receiveData = new byte[1024];
		try {
			multicastSocket.receive(receivePacket);
			String tileMapString = new String(receivePacket.getData());
			
			// update the tileMap 
			tileMap = stringToArray(tileMapString);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			multicastSocket.close();
			e.printStackTrace();	
		}
		Thread gameThread = new Thread(new GameView(tileMap, Client.playerNum, semaphore));
		gameThread.start();
		
		
		
		// continuously receives and prints game board
		while(true){
			receiveData = new byte[1024];
			
			try {
				multicastSocket.receive(receivePacket);
				String tileMapString = new String(receivePacket.getData());
				
				// update the tileMap 
				tileMap = stringToArray(tileMapString);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				multicastSocket.close();
				e.printStackTrace();	
			}
			semaphore.release();
		}
	}
	
	
	public void startLobbyLogic(String received){
		if (received.equals("1") || received.equals("2") || received.equals("3")) {
			//System.out.println("You are player " + Client.playerNum);
			Client.playerNum = received.toCharArray()[0];
			//System.out.println("You are player );
			Client.keyInputPort = Integer.valueOf(received)+3333;
		}
		else if (received.equals("4")) {
			System.out.println("You are player 4, game is now starting");
			Client.keyInputPort = 3338;
		}
		else if(received.equals("no players")){
			System.out.println("Not enough players to start");
		}
		else if(received.equals("starting")){
			Client.startLobby = false;
			System.out.println("Game now starting");
		}
		else {
			//Thread gameThread = new Thread(new GameView(tileMap, Client.playerNum));
		}
	}
	
	// this method converts our array to a CSV string format where each level of
	// the array is delimited by "|"
	public ArrayList<ArrayList<Character>> stringToArray(String s) {
		ArrayList<ArrayList<Character>> tileMapInternal = new ArrayList<ArrayList<Character>>();
		ArrayList<String> tempMap = new ArrayList<String>();
		
		StringTokenizer st1 = new StringTokenizer(s, "|");
		while (st1.hasMoreElements()) {
			tempMap.add((String) st1.nextElement());
		}
		for(int i=0; i<tempMap.size(); i++){
			ArrayList<Character> row = new ArrayList<Character>();
			StringTokenizer st2 = new StringTokenizer((String) tempMap.get(i), ",");
			
			while (st2.hasMoreElements()){
				row.add(((String) st2.nextElement()).charAt(0));
			}
			tileMapInternal.add(row);
		}
		return tileMapInternal;
	}
}

@@ -321,16 +321,41 @@
 ePort;%0D%0A
+%09Semaphore semStarting;%0D%0A
 %09public 
@@ -435,16 +435,37 @@
 int port
+, Semaphore semaphore
 ) %7B%0D%0A%09%09r
@@ -488,16 +488,44 @@
 t + 1;%0D%0A
+%09%09semStarting = semaphore;%0D%0A
 %09%7D%0D%0A%0D%0A%09@
@@ -3293,16 +3293,43 @@
 rs%22))%7B%0D%0A
+%09%09%09semStarting.release();%0D%0A
 %09%09%09Syste
@@ -3421,16 +3421,43 @@
 ng%22))%7B%0D%0A
+%09%09%09semStarting.release();%0D%0A
 %09%09%09Clien

Update ClientReceive.java