Chris Pollett >
Old Classes >
PIC20B

   ( Print View )

Enrollment info

Course Info: Homework Assignments: Practice Exams: PIC:
                            












HW5 Solutions Page

Return to homework page.


//
// Interface Name: PongClientServerDefines
//
// Purpose: contains defines used by Pong client and server
//

public interface PongClientServerDefines
{
	//
	// Defines concerning Pong Client Server communication
	//

	static int SERVERPORT=6542;

	static int ENDGAMECODE=7;
	static int ENDGAMELENGTH =0;

	static int ENDPOINTCODE=3;
	static int ENDPOINTLENGTH=30;

	static int STARTGAMECODE=5;
	static int STARTGAMELENGTH=10;

	static int STARTPOINTCODE = 6;
	static int STARTPOINTLENGTH = 0;

	static int PLAYINGCODE = 127;

	static int UPCODE = 0;
	static int DOWNCODE = 255;

	static int LPLAYER = 1;
	static int RPLAYER = 2;

	//
	// Defines for Initially Positioning Elements on
	// Pong Client Screens
	//

	static int PADDLE_WIDTH = 5;
	static int PADDLE_HEIGHT = 30;

	static int PREFERRED_WIDTH = 300;
	static int PREFERRED_HEIGHT = 200;

	static int BALL_RADIUS=5;
	static int BALLX = PREFERRED_WIDTH/2+4*BALL_RADIUS;
	static int BALLY = PREFERRED_HEIGHT/2;
	static int BALLXVEL = 2;
	static int BALLYVEL = 2;
	static int MAXBALLVEL = 5;
	static int MINBALLX = 10;
	static int MAXBALLX = PREFERRED_WIDTH-BALL_RADIUS-MINBALLX;
	static int MINBALLY = 10;
	static int MAXBALLY = PREFERRED_HEIGHT-BALL_RADIUS-MINBALLY;

	static int FUDGE = 10;

	static int LSCORE_X = PREFERRED_WIDTH/6;
	static int RSCORE_X = 5*LSCORE_X, SCORE_Y=25;

	static int TEXT_X = 40;
	static int TEXT_Y = PREFERRED_HEIGHT/2;

	static int LPADDLEX = PADDLE_WIDTH;
	static int RPADDLEX = PREFERRED_WIDTH-2*PADDLE_WIDTH;

	static int PADDLEY = (PREFERRED_HEIGHT-PADDLE_HEIGHT)/2;
	static int MAXPADDLEVEL =5;
	static int MINPADDLE = 10;
	static int MAXPADDLE = PREFERRED_HEIGHT-MINPADDLE-PADDLE_HEIGHT;

	static int MAXSCORE = 10; //score game ends at

}

/**
 * PongServer.java
 *
 * Title:			PongServer
 * Description:		This is the server for our Pong Game
 * @author			cpollett
 * @version
 */

import java.io.*;
import java.net.*;
import java.awt.event.*;
import javax.swing.*;

public class PongServer implements PongClientServerDefines{

	ServerSocket server; // TCP listener
	Socket pConnection[]; // connection for each player
	int pPort[]; // port player will listen to UDP on

	DatagramSocket transmitUDP; // used for sending UDP of positions of ball/players
	DatagramPacket packetUDP[]; // packet for sending; we reuse this a lot
	byte packetData[]; // array of data for packet

	DataInputStream pIn[]; // connection input output stream
	DataOutputStream pOut[];


	int gamePhase;	// gives current state of program
	int phaseCounter; // used to measure how long have been in current
	                  // state (multiple of 100ms)

	int whosePoint=0; // who scored the last point

	boolean ack[]; // in non playing phase we expect each player
	               // to acknowledge our UDP transmissions
	               // this var keeps track of whose done this

	Thread playerThread[];	//thread for managing each players comunication

	Timer timerUDP; // timer for UDP broadcasts

	int paddle[]; // y position for each player's paddle
	int paddleVel[]; // y velocity of each player's paddle

	int ballX; // ball x position
	int ballY; // ball y position
	int ballXVel; // ball X velocity
	int ballYVel; // ball Y velocity

	int lScore; // left player's score
	int rScore; // right player's score

	//
	// Constructor Name: PongServer
	//
	// Purpose: initializes threads, timers, and sockets used by our server
	//
	public PongServer() {

		try
		{
			server = new ServerSocket(SERVERPORT,2);

			transmitUDP = new DatagramSocket();
		}
		catch(Exception se)
		{
			se.printStackTrace();
			System.exit(1);
		}

		packetUDP = new DatagramPacket[2];
		packetData = new byte[8];

		pConnection = new Socket[2];
		pIn = new DataInputStream[2];
		pOut = new DataOutputStream[2];
		pPort = new int[2];

		ack = new boolean[2];

		playerThread = new Thread[2];

		paddle = new int[2];
		paddleVel = new int[2];

		playerThread[0]= new Thread(new Runnable()
				{
					public void run()
					{
						playerTCP(0);
					}
				}
			);

		playerThread[0].start();

		playerThread[1]= new Thread(new Runnable()
				{
					public void run()
					{
						playerTCP(1);
					}
				}
			);

		playerThread[1].start();

		timerUDP = new Timer( 100,
			new ActionListener()
			{
				public void actionPerformed(ActionEvent e)
				{
					broadcastUDP();
				}
			}
		);

	}

	//
	// Method Name: runServer
	//
	// Purpose: gets a connection from each player
	//          sets up streams, finds out UDP port player is listening to,
	//          tells player which paddle he is.
	//
	public void runServer()
	{
		int i;

		while(true)
		{
			System.out.println("Server: Waiting for connections...");

			try
			{
				for (i=0; i<2; i++)
				{
					pConnection[i] = server.accept();
					System.out.println("Server: Player"+i+" connected.");

					pIn[i] = new DataInputStream( pConnection[i].getInputStream());
					pPort[i]=pIn[i].readInt();

					packetUDP[i] = new DatagramPacket(packetData,
						packetData.length,
						pConnection[i].getInetAddress(),
						pPort[i]
					);

					pOut[i] = new DataOutputStream( pConnection[i].getOutputStream());
					pOut[i].flush();

					System.out.println("Server: Player"+i+" streams set up.");

				}

				pOut[0].writeInt(LPLAYER);
				pOut[1].writeInt(RPLAYER);
			}
			catch(Exception e)
			{
				e.printStackTrace();
				System.exit(1);
			}

			startGame();

			//main thread now waits until it's time to play again
			try
			{
				synchronized(this)
				{
					wait();
				}
			}
			catch(Exception e)
			{
				e.printStackTrace();
				System.exit(1);
			}

			stopGame();
		}
	}

	//
	// Method Name: startGame
	//
	// Purpose: sets up scores, ball, paddle locations as at start of game.
	//          starts UDP broadcaster timer, tells player thread to process
	//          to TCP messages.
	//
	public void startGame()
	{

		startPoint();

		lScore = 0;
		rScore = 0;

		gamePhase = STARTGAMECODE;
		phaseCounter = 0;
		timerUDP.start();

		//
		// Notify player threads that we are going to play a game
		//

		try
		{
			synchronized(this)
			{
				notifyAll();
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
			System.exit(1);
		}
	}

	//
	// Method Name: startGame
	//
	// Purpose: sets up ball, paddle locations as at start of round.
	//          ball initial velocity random.
	//
	public void startPoint()
	{
		for(int i=0; i<2; i++)
		{
			paddle[i] = PADDLEY;
			paddleVel[i] = 0;
			ack[i] = false;
		}

		ballX = BALLX;
		ballY = BALLY;
		ballXVel = (Math.random() > .5)? BALLXVEL : -BALLXVEL;
		ballYVel = (Math.random() > .5)? BALLYVEL : -BALLYVEL;
	}

	//
	// Method Name: stopGame
	//
	// Purpose: stops UDP broadcaster thread.
	//
	public void stopGame()
	{
		timerUDP.stop();
	}

	//
	// Method Name: broadcastUDP
	//
	// Purpose: main function for UDP broadcaster timer.
	//          sends packets to client according to game phase.
	//
	public void broadcastUDP()
	{
		switch(gamePhase)
		{

			case STARTGAMECODE:
				phaseHandler(STARTGAMELENGTH, STARTPOINTCODE);
			break;

			case STARTPOINTCODE:
				if(phaseHandler(STARTPOINTLENGTH, PLAYINGCODE))
					startPoint();
			break;

			case ENDPOINTCODE:
				phaseHandler(ENDPOINTLENGTH, STARTPOINTCODE);
			break;

			case ENDGAMECODE:
				if(phaseHandler(ENDGAMELENGTH, STARTGAMECODE))
				{
					try
					{
			  			synchronized(this)
			  			{
							notify(); // notify main thread game's over
							          // main thread will stop game
						}
					}
					catch(Exception e)
					{
						e.printStackTrace();
						System.exit(1);
					}
				}
			break;

			default:
				updateScreen();
		}
	}

	//
	// Method Name: phaseHandler
	//
	// Purpose: for non playing game states write out appropriate
	//          packet if haven't gotten an acknowledgement yet.
	//          if both players have acknowledge than start counting
	//          100ms blocks for how long this phase is supposed to last
	//
	public boolean phaseHandler(int phaseLength, int nextPhase)
	{
		boolean flag =false;

		for(int j=0; j < 8; j++)
				packetData[j] = (new Integer(gamePhase)).byteValue();

		for(int i=0; i < 2; i++)
		{
			if(!ack[i])
			{

				try
				{
					transmitUDP.send(packetUDP[i]);
				}
				catch(Exception e)
				{
					e.printStackTrace();
				}
			}
		}

		if(ack[0] && ack[1])
			{
			if(phaseCounter < phaseLength)
				phaseCounter++;
			else
			{
				ack[0]=false;
				ack[1]=false;
				gamePhase = nextPhase;
				phaseCounter = 0;
				flag =true;
			}
		}

		return flag;
	}

	//
	// Method Name: updateScreen
	//
	// Purpose: games during playing state to update the positions of
	//          ball/paddles on screen. Check to see if anything went of
	//          bounds and does appropriate. If ball goes out of
	//          bound the state is change to either end point or end game.
	//
	public void updateScreen()
	{

		ballX += ballXVel;
		ballY += ballYVel;
		if(ballY < MINBALLY)
		{
			ballYVel = -ballYVel;
			ballY = 10;
		}

		if(ballY > MAXBALLY)
		{
			ballYVel = -ballYVel;
			ballY = MAXBALLY;
		}

		if(ballX < MINBALLX+FUDGE && ballY > paddle[0]
		                    && ballY < paddle[0]+ PADDLE_HEIGHT)
		{
			ballXVel = -(ballXVel-1);
			ballYVel = (ballYVel + paddleVel[0])/2;

		}

		if(ballX > MAXBALLX-FUDGE && ballY > paddle[1]
		                    && ballY < paddle[1]+ PADDLE_HEIGHT)
		{
			ballXVel = -(ballXVel+1);
			ballYVel = (ballYVel + paddleVel[1])/2;

		}

		for(int i=0; i<2; i++)
		{
			paddle[i] += paddleVel[i];

			if(paddle[i] < MINPADDLE)
			{
				paddle[i] = MINPADDLE;
				paddleVel[i] = 0;
			}

			if(paddle[i] > MAXPADDLE)
			{
				paddle[i] = MAXPADDLE;
				paddleVel[i] = 0;
			}
		}

		if(ballX <MINBALLX)
		{
			whosePoint = 2;
			rScore++;
			if(rScore < MAXSCORE)
				gamePhase = ENDPOINTCODE;
			else
				gamePhase = ENDGAMECODE;
		}

		if(ballX > MAXBALLX)
		{
			whosePoint = 1;
			lScore++;
			if(lScore < MAXSCORE)
				gamePhase = ENDPOINTCODE;
			else
				gamePhase = ENDGAMECODE;
		}

		sendCoords();
	}

	//
	// Method Name: sendCoords
	//
	// Purpose: function used by updateScreen to convert
	//          ball/paddle locations into UDP packet data and transmit.
	//
	//
	public void sendCoords()
	{
		// ball X ccord.
		packetData[0]= (new Integer(ballX >> 8)).byteValue();
		packetData[1]= (new Integer(ballX & 255)).byteValue();

		// ball Y coord
		packetData[2]= (new Integer(ballY >> 8)).byteValue();
		packetData[3]= (new Integer(ballY & 255)).byteValue();

		// left paddle Y
		packetData[4]= (new Integer(paddle[0] >> 8)).byteValue();
		packetData[5]= (new Integer(paddle[0] & 255)).byteValue();

		// right paddle Y
		packetData[6]= (new Integer(paddle[1] >> 8)).byteValue();
		packetData[7]= (new Integer(paddle[1] & 255)).byteValue();

		try
		{
			for(int i =0; i<2; i++)
			{
				transmitUDP.send(packetUDP[i]);
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	//
	// Method Name: playerTCP
	//
	// Purpose: function used by player thread used to
	//          manage TCP communication with a player client.
	//          if game not begun this function causes the thread to wait.
	//          Once game started thread tries to read from input stream
	//          In play state this info is used to move the player up or down.
	//          In other states, the signal is compared to the current
	//          game state and the game state is echoed to client so
	//          client know is can ignore last UDP message. If signal
	//          and game state are equal the appropriate action for that state is
	//          taken.
	//
	public void playerTCP(int player)
	{
		int signal;

		while(true)
		{
			signal = STARTGAMECODE;
			try
			{

			  synchronized(this)
			  {
			  	wait();
			  }

			  while(signal != ENDGAMECODE)
			  {

				signal = pIn[player].readInt();

				switch(signal)
				{
					case STARTGAMECODE:
						pOut[player].writeInt(gamePhase);

						if(gamePhase == signal)
						{
							ack[player] =true;
						}
						System.out.println("Player"+player+"acknowledges start game.");
						System.out.println(" Game Phase is "+gamePhase+".");
					break;

					case STARTPOINTCODE:
						pOut[player].writeInt(gamePhase);

						if(gamePhase == signal)
						{
							ack[player] =true;
						}
						System.out.println("Player"+player+"acknowledges start point.");
						System.out.println(" Game Phase is "+gamePhase+".");
					break;

					case ENDPOINTCODE:
						pOut[player].writeInt(gamePhase);

						if(gamePhase == signal)
						{
							pOut[player].writeInt(whosePoint);
							pOut[player].writeInt(lScore);
							pOut[player].writeInt(rScore);

							ack[player] =true;
						}
						System.out.println("Player"+player+"acknowledges end point.");
						System.out.println(" Game Phase is "+gamePhase+".");
					break;

					case ENDGAMECODE:

						pOut[player].writeInt(gamePhase);

						System.out.println("Player"+player+"acknowledges end game.");
						System.out.println(" Game Phase is "+gamePhase+".");

						if(gamePhase == ENDGAMECODE)
						{
							ack[player] =true;

							pOut[player].writeInt(whosePoint);
							pOut[player].writeInt(lScore);
							pOut[player].writeInt(rScore);

							pIn[player].close();
							pOut[player].close();
							pConnection[player].close();

							System.out.println("Player"+player+"connection closed.");
						}
					break;

					case UPCODE:
						if( - MAXPADDLEVEL  < paddleVel[player])
							paddleVel[player]--;
					break;

					case DOWNCODE:
						if( paddleVel[player] < MAXPADDLEVEL)
							paddleVel[player]++;
					break;
				}// end switch
			  }// end while signal
			} // end try
			catch(Exception e)
			{
				e.printStackTrace();
				System.exit(1);
			}
		} // end while true
	}

	// Main entry point
	static public void main(String[] args) {
		PongServer app = new PongServer();

		app.runServer();
	}

}

/**
 * PongClient.java
 *
 * Title:			Client For Pong Game
 *                              (most of work gets done in this classes frame)
 * Description:
 * @author			cpollett
 * @version
 */


import PongFrame;

public class PongClient {
	public PongClient() {
		try {
			PongFrame frame = new PongFrame();
			frame.initComponents();
			frame.setVisible(true);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}

	// Main entry point
	static public void main(String[] args) {
		new PongClient();
	}

}


/**
 * PongFrame.java
 *
 * Title:			Client Frame For Pong Game
 * Description:
 * @author			cpollett
 * @version
 */


import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;


public class PongFrame extends java.awt.Frame implements PongClientServerDefines
{


	boolean connectMode=false; //tells whether a connection has been established
	DatagramSocket listenerUDP; // used to listen for UDP packets
	DatagramPacket receivePacket; // reused to receive packets from listener

	Socket keySocket; //  TCP socket used to send keystroke info to server
	DataInputStream in; // it input/output streams
	DataOutputStream out;

	int player; //holds which player client is.

	String msg; // holds message to be printed in PongScreen.
	int lScore; // left score to be printed in PongScreen
	int rScore; // right score to be printed in PongScreen
	int whosePoint; // who scored the last point

	int xBall; //ball position
	int yBall;

	int yL; //left paddle y
	int yR; //right paddle y

	Thread threadUDP; //thread for handling UDP packets
	Thread threadConnect; // auxiliary thread used by connect button
	                      // to do the actual connecting
	byte data[];

// IMPORTANT: Source code between BEGIN/END comment pair will be regenerated
// every time the form is saved. All manual changes will be overwritten.
// BEGIN GENERATED CODE
	// member declarations
	javax.swing.JButton connectButton = new javax.swing.JButton();
	javax.swing.JTextField serverURLField = new javax.swing.JTextField();
	javax.swing.JLabel serverLabel = new javax.swing.JLabel();
	PongPanel pongPanel1 = new PongPanel();
// END GENERATED CODE

	//
	// Constructor Name: PongFrame
	//
	// Purpose: initializes threads, and sockets used by our client
	//
	public PongFrame() {
		try
		{
			listenerUDP = new DatagramSocket();
		}
		catch(SocketException se)
		{
			se.printStackTrace();
			System.exit(1);
		}

		data = new byte[ 8 ];
		receivePacket = new DatagramPacket(data, data.length);

		threadUDP = new Thread(new Runnable()
			{
				public void run()
				{
					listenUDP();
				}
			}
		);

		threadUDP.start();

		threadConnect = new Thread(new Runnable()
			{
				public void run()
				{
					listenConnect();
				}
			}
		);

		threadConnect.start();
	}

	//
	// Method Name: initComponents
	//
	// Purpose: automatically generated function from CodeWarrior
	//          It sets up all the GUI components of our client.
	//
	public void initComponents() throws Exception {
// IMPORTANT: Source code between BEGIN/END comment pair will be regenerated
// every time the form is saved. All manual changes will be overwritten.
// BEGIN GENERATED CODE
		// the following code sets the frame's initial state

		connectButton.setSize(new java.awt.Dimension(100, 28));
		connectButton.setLocation(new java.awt.Point(360, 40));
		connectButton.setVisible(true);
		connectButton.setText("Connect");

		serverURLField.setSize(new java.awt.Dimension(220, 30));
		serverURLField.setLocation(new java.awt.Point(130, 40));
		serverURLField.setVisible(true);

		serverLabel.setSize(new java.awt.Dimension(100, 30));
		serverLabel.setLocation(new java.awt.Point(10, 40));
		serverLabel.setVisible(true);
		serverLabel.setText("Server URL:");

		pongPanel1.setSize(new java.awt.Dimension(300, 200));
		pongPanel1.setLocation(new java.awt.Point(90, 90));
		pongPanel1.setVisible(true);
		pongPanel1.setText("PongClient");
		pongPanel1.setLayout(null);

		setLocation(new java.awt.Point(0, 0));
		setSize(new java.awt.Dimension(511, 335));
		setBackground(java.awt.Color.white);
		setLayout(null);
		setTitle("PongFrame");
		add(connectButton);
		add(serverURLField);
		add(serverLabel);
		add(pongPanel1);


		connectButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent e) {
				connectButtonActionPerformed(e);
			}
		});
		addWindowListener(new java.awt.event.WindowAdapter() {
			public void windowClosing(java.awt.event.WindowEvent e) {
				thisWindowClosing(e);
			}
		});
		addKeyListener(new java.awt.event.KeyAdapter() {
			public void keyTyped(java.awt.event.KeyEvent e) {
				thisKeyTyped(e);
			}
		});

// END GENERATED CODE
	}

  	private boolean mShown = false;

	public void addNotify() {
		super.addNotify();

		if (mShown)
			return;

		// move components to account for insets
		Insets insets = getInsets();
		Component[] components = getComponents();
		for (int i = 0; i < components.length; i++) {
			Point location = components[i].getLocation();
			location.move(location.x, location.y + insets.top);
			components[i].setLocation(location);
		}

		mShown = true;
	}

	// Close the window when the close box is clicked
	void thisWindowClosing(java.awt.event.WindowEvent e) {
		setVisible(false);
		dispose();
		System.exit(0);
	}

	//
	// Method Name: thisKeyTyped
	//
	// Purpose: called by our KeyListener. If in connected
	//          writes to server either up or down if the appropriate key pressed
	//
	public void thisKeyTyped(java.awt.event.KeyEvent e) {
		if(connectMode==false) return;

		char key = e.getKeyChar();
		int output = PLAYINGCODE;


		switch(player)
		{
			case LPLAYER:
				if( key == '1') output = UPCODE;
				if( key == '2') output = DOWNCODE;
			break;
			case RPLAYER:
				if( key == '9') output = UPCODE;
				if( key == '0') output = DOWNCODE;
			break;
		}

		try
		{
			out.writeInt(output);
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
		}
	}

	//
	// Method Name: connectButtonActionPerformed
	//
	// Purpose: called when connect button pressed to
	//          try to establish a connection with a given
	//          server. It works by notifying the auxiliary thread
	//          threadConnect. Which continues executing listenConnect()
	//          below.
	//
	public void connectButtonActionPerformed(java.awt.event.ActionEvent e) {
		if(connectMode==true) return;

		pongPanel1.setText("Connecting...");
		pongPanel1.repaint();

		try
		{
			synchronized(this)
			{
				notify();
			}
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
		}
	}

	//
	// Method Name: listenUDP
	//
	// Purpose: main function executed by of UDP thread.
	//          It mainly waits for packets. Then processes
	//          the information contained in them
	//
	private void listenUDP()
	{

		while(true)
		{
			try
			{
				listenerUDP.receive(receivePacket);
			}
			catch(IOException io)
			{
				System.err.println(io.toString());
			}

			if(connectMode == true)
			{
				if(!checkChangeMode())
					getCoords();
				updateScreen();
				pongPanel1.repaint();
			}
		}
	}

	//
	// Method Name: listenConnect
	//
	// Purpose: main function executed by our connect thread.
	//          It excecutes if the mode is not connect mode
	//          and the connect button has notified it.
	//          It tries to establish a TCP connection
	//          with the server in question and sends info
	//          to server about which port to send packets to.
	//
	private void listenConnect()
	{

		while(true)
		{
			try
			{
				synchronized(this)
				{
					wait(); //for connect button
				}
			}
			catch(Exception io)
			{
				System.err.println(io.toString());
			}

			if(connectMode == false)
			{
				String text = serverURLField.getText();

				try
				{
					keySocket= new Socket(InetAddress.getByName(text),SERVERPORT);

					in = new DataInputStream(keySocket.getInputStream());
					out = new DataOutputStream(keySocket.getOutputStream());

					pongPanel1.setText("Connected.");
					pongPanel1.repaint();

					out.flush();

					out.writeInt(listenerUDP.getLocalPort());

					pongPanel1.setText("Waiting for opponent.");
					pongPanel1.repaint();

					player = in.readInt();

					pongPanel1.setText("You are Player"+player+".");
					pongPanel1.repaint();

					connectMode = true;
				}
				catch(Exception ex)
				{
					ex.printStackTrace();
				}
			}
		}
	}

	//
	// Method Name: checkChangeMode
	//
	// Purpose: checks if the packets just received contains
	//          data that would cause a change of mode
	//          if so acknowledge to server mode change.
	//          and get any additional data from server.
	//
	private boolean checkChangeMode()
	{
		boolean endGame = true;
		boolean endPoint = true;

		boolean startGame = true;
		boolean startPoint = true;

		for(int i=0; i<7; i++)
		{
			if(data[i] != ENDGAMECODE) endGame = false;
			if(data[i] != ENDPOINTCODE) endPoint = false;

			if(data[i] != STARTGAMECODE) startGame = false;
			if(data[i] != STARTPOINTCODE) startPoint = false;
		}

		if(endGame) endGameHandler();
		if(endPoint) endPointHandler();

		if(startGame) startGameHandler();
		if(startPoint) startPointHandler();


		return endGame && endPoint && startGame && startPoint;
	}

	//
	// Method Name: getCoords
	//
	// Purpose: converts packets data to coordinates for each screen object
	//
	private void getCoords()
	{
		xBall = (data[0]<<8) + (data[1] & 255); //the & 255 is since byte is
		                                        //otherwised signed.
		yBall = (data[2]<<8) + (data[3] & 255);

		yL = (data[4]<<8) + (data[5] & 255);
		yR = (data[6]<<8) + (data[7] & 255);


	}

	//
	// Method Name: updateScreen
	//
	// Purpose: used current data about object to update Pong Screen
	//
	private void updateScreen()
	{
		pongPanel1.setBallX(xBall);
		pongPanel1.setBallY(yBall);

		pongPanel1.setLPaddleY(yL);
		pongPanel1.setRPaddleY(yR);

		pongPanel1.setLScore(lScore);
		pongPanel1.setRScore(rScore);

		pongPanel1.setText(msg);

		pongPanel1.repaint();
	}

	//
	// Switch phase handlers called by checkChangedMode
	// each handle the end of given named phase.
	//

	private void endGameHandler()
	{
		int signal;

		try
		{
			out.writeInt(ENDGAMECODE);
			signal = in.readInt();

			if(signal == ENDGAMECODE)
			{
				whosePoint = in.readInt();
				lScore = in.readInt();
				rScore = in.readInt();

				msg= "Player"+whosePoint+" wins!";

				out.close();
				in.close();
				keySocket.close();

				connectMode = false;
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}


	}

	private void endPointHandler()
	{
		int signal;

		try
		{
			out.writeInt(ENDPOINTCODE);
			signal = in.readInt();

			if(signal == ENDPOINTCODE)
			{
				whosePoint = in.readInt();
				lScore = in.readInt();
				rScore = in.readInt();

				msg="Player"+whosePoint+" scores!";
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}

	}

	private void startGameHandler()
	{

		int signal;

		try
		{
			out.writeInt(STARTGAMECODE);
			signal = in.readInt();


			if(signal == STARTGAMECODE)
			{
				msg="Start Game";
				lScore = 0;
				rScore = 0;
			}

		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	private void startPointHandler()
	{
		int signal;

		try
		{
			out.writeInt(STARTPOINTCODE);

			signal = in.readInt();

			if(signal == STARTPOINTCODE)
			{
				msg = "";
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
}

/**
 * PongPanel.java
 *
 * Description: panel used to draw the current screen of the pong game in the
 *              client. At home this was a Java Bean
 * @author			cpollett
 * @version
 */

import java.awt.*;
import javax.swing.*;
import PongClientServerDefines;

public class PongPanel extends javax.swing.JPanel
                       implements PongClientServerDefines
{

	int lPaddleX, lPaddleY, lScore;
	int rPaddleX, rPaddleY, rScore;
	int ballX, ballY;
	String text;

	public PongPanel()
	{
		setBackground(Color.black);

		lPaddleX = LPADDLEX;
		lPaddleY = PADDLEY;
		lScore=0;

		rPaddleX = RPADDLEX;
		rPaddleY = PADDLEY;
		rScore=0;

		ballX = BALLX;
		ballY = BALLY;

		setText("PongClient");
	}

	public void setText(String t)
	{
		text = t;
	}

	public String getText()
	{
		return text;
	}

	public void setLScore(int lS)
	{
		lScore = lS;
	}

	public int getLScore()
	{
		return lScore;
	}

	public void setRScore(int rS)
	{
		rScore = rS;
	}

	public int getRScore()
	{
		return rScore;
	}

	public void setLPaddleX(int x)
	{
		lPaddleX=x;
	}

	public int getLPaddleX()
	{
		return lPaddleX;
	}

	public void setLPaddleY(int y)
	{
		lPaddleY=y;
	}

	public int getLPaddleY()
	{
		return lPaddleY;
	}

	public void setRPaddleX(int x)
	{
		rPaddleX=x;
	}

	public int getRPaddleX()
	{
		return rPaddleX;
	}

	public void setRPaddleY(int y)
	{
		rPaddleY=y;
	}

	public int getRPaddleY()
	{
		return rPaddleY;
	}

	public void setBallX(int x)
	{
		ballX=x;
	}

	public int getBallX()
	{
		return ballX;
	}

	public void setBallY(int y)
	{
		ballY=y;
	}

	public int getBallY()
	{
		return ballY;
	}

	public void paintComponent( Graphics g)
	{
		int spacing = PREFERRED_HEIGHT/10, dash = 3*spacing/4;
		int center = (PREFERRED_WIDTH-PADDLE_WIDTH)/2;

		super.paintComponent(g);

		g.setColor(Color.white);

		g.setFont(new Font("Monospaced", Font.PLAIN, 24));
		g.drawString(""+lScore, LSCORE_X, SCORE_Y);
		g.drawString(""+rScore, RSCORE_X, SCORE_Y);
		g.drawString(text, TEXT_X, TEXT_Y);

		g.fillRect(lPaddleX,lPaddleY, PADDLE_WIDTH, PADDLE_HEIGHT);
		g.fillRect(rPaddleX,rPaddleY, PADDLE_WIDTH, PADDLE_HEIGHT);

		g.fillOval(ballX, ballY, BALL_RADIUS, BALL_RADIUS);

		for( int i=0; i< 10;i++)
		{
			g.fillRect(center, i*spacing, PADDLE_WIDTH,dash);
		}
	}

	public Dimension getPreferredSize()
	{
		return new Dimension(PREFERRED_WIDTH, PREFERRED_HEIGHT);
	}

	public Dimension getMinimumSize()
	{
		return getPreferredSize();
	}
}


/* @(#)PongPanel.java */