import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Vector;
import javax.swing.*;
/**
* This class functions as the controller for my Tic Tac Toe game.
* @author Zosden
* Date Due: 2/22/2008
* @version 1.0 (22 February 2008)
* Input: playersFile.txt is a text file to hold players information.
* String playerXName is a temp String for input of player x's name.
* String playerOName is a temp String for input of player O's name.
* Output: playersFile.txt
*/
public class GameController
{
///////////////////
// Properties //
///////////////////
private GameView myView;
private GameModel myModel;
private Player myPlayerX;
private Player myPlayerO;
private File playersFile;
private FileReader fileReader;
private BufferedReader bufReader;
private FileOutputStream outFileStream;
private PrintStream p;
private boolean myPlayerXNewPlayer = true;
private boolean myPlayerONewPlayer = true;
private int myPlayerXPosition;
private int myPlayerOPosition;
private Vector myPlayerVector = new Vector(10);
private ServerSocket serverSocket;
private Socket clientSocket;
private PrintWriter out;
private String inputLine;
private String outputLine;
private boolean isClient;
private BufferedReader in;
private String fromServer;
/**
* Default controller constructor.
*/
public GameController(Player aPlayerX, Player aPlayerO, boolean isClient)
{
myPlayerX = aPlayerX;
myPlayerO = aPlayerO;
this.isClient = isClient;
this.readPlayers();
myModel = new GameModel(this);
myView = new GameView(this);
if(isClient)
{
this.setUpClient();
this.waitForTurn(-1 , -1);
}
else
{
this.setUpServer();
}
}
private void waitForTurn(int aRow, int aCol)
{
if(isClient)
{
if(!(aRow == -1 || aCol == -1))
{
out.println(aRow + " " + aCol + " ");
System.out.println("Made Move");
}
while(true)
{
try
{
fromServer = in.readLine();
}
catch (IOException e)
{
e.printStackTrace();
}
if(fromServer != null)
{
int row = fromServer.indexOf(" ");
int col = fromServer.indexOf(" ");
System.out.println(row + " " + col);
myModel.move(row, col);
break;
}
}
}
else
{
out.println(aRow + " " + aCol + " ");
while(true)
{
try
{
fromServer = in.readLine();
}
catch (IOException e)
{
e.printStackTrace();
}
int row = fromServer.indexOf(" ");
int col = fromServer.indexOf(" ");
System.out.println(row + " " + col);
myModel.move(row, col);
break;
}
}
}
private void setUpServer()
{
serverSocket = null;
try
{
serverSocket = new ServerSocket(4444);
}
catch (IOException e)
{
System.err.println("Could not listen on port: 4444.");
System.exit(1);
}
clientSocket = null;
try
{
clientSocket = serverSocket.accept();
}
catch (IOException e)
{
System.err.println("Accept failed.");
System.exit(1);
}
try
{
out = new PrintWriter(clientSocket.getOutputStream(), true);
}
catch (IOException e)
{
e.printStackTrace();
}
}
private void setUpClient()
{
try
{
clientSocket = new Socket(myPlayerO.getName(), 4444);
out = new PrintWriter(clientSocket.getOutputStream(), true);
}
catch (UnknownHostException e)
{
System.err.println("Don't know about host.");
System.exit(1);
}
catch (IOException e)
{
System.err.println("Couldn't get I/O for the connection to.");
System.exit(1);
}
}
/**
* Tells the model that something has been selected then
* passes the row and col of the event.
*
* pre: a valid view, model and controller have been designated
* post: sends aRow and aCol to move in the model class.
* @param aRow
* @param aCol
*/
public void choiceMade(Integer aRow, Integer aCol)
{
myModel.move(aRow, aCol);
this.waitForTurn(aRow, aCol);
}
public void changePlayersName()
{
this.writePlayers();
myPlayerVector.clear();
String playerXName = JOptionPane.showInputDialog(
"Please enter player X's name.");
String playerOName = JOptionPane.showInputDialog(
"Please enter player O's name.");
this.setPlayerXName(playerXName);
this.setPlayerOName(playerOName);
this.readPlayers();
myView.changeNames();
myView.setWins();
}
public void changeMusic()
{
myView.displayDialog();
}
public void pauseMusic()
{
myModel.pauseMusic();
}
public void startMusic()
{
myModel.startMusic();
}
public void quitGame()
{
this.writePlayers();
System.exit(0);
}
/**
* Increments the number of wins a certain player has,
* which is determined by the argument.
*
* @param aPlayerType
*/
public void changeImage(int aRow, int aCol, int aPlayerType)
{
myView.setMyImagePieces(aRow, aCol, aPlayerType);
}
public void updateScore()
{
myView.setWins();
}
public void changeMessage(String aString)
{
myView.changeMyMessage(aString);
}
/**
*
* This method writes the players name and wins into a text file in
* order to save that information
*
* <pre>
* pre: The myPlayerX and myPlayerO must be initiated.
* The text file "playersFile.txt"
* must exist and be written correctly. If it isn't just
* delete all info in it and
* start anew.
*
* post: This method will rewrite the entire text file
* with all the players names.
* </pre>
*/
public void writePlayers()
{
if(!myPlayerXNewPlayer)
{
myPlayerVector.remove(myPlayerXPosition + 1);
myPlayerVector.insertElementAt(getPlayerXWins(),
myPlayerXPosition + 1);
}
else
{
myPlayerVector.add(getPlayerXName());
myPlayerVector.add(getPlayerXWins());
}
if(!myPlayerONewPlayer)
{
myPlayerVector.remove(myPlayerOPosition + 1);
myPlayerVector.insertElementAt(getPlayerOWins(),
myPlayerOPosition + 1);
}
else
{
myPlayerVector.add(getPlayerOName());
myPlayerVector.add(getPlayerOWins());
}
try
{
outFileStream = new FileOutputStream(playersFile);
p = new PrintStream(outFileStream);
}
catch (IOException e)
{
e.printStackTrace();
}
for(int i = 0; i < myPlayerVector.size(); i++)
{
p.println(myPlayerVector.elementAt(i));
}
p.close();
}
/**
*
* This method reads the players name and wins in a text file in
* order to find out their information
*
* <pre>
* pre: The myPlayerX and myPlayerO must be initiated.
* The text file "playersFile.txt"
* must exist and be written correctly. If it isn't just
* delete all info in it and
* start anew.
*
* post: This method will read the entire text file
* with all the players names.
* </pre>
*/
public void readPlayers()
{
String tempName = null;
int tempPosition = 0;
int tempWins = 0;
playersFile = new File("playersText.txt");
try
{
fileReader = new FileReader(playersFile);
bufReader = new BufferedReader(fileReader);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
while(true)
{
tempName = null;
try
{
tempName = bufReader.readLine();
if(tempName == null)
{
break;
}
myPlayerVector.insertElementAt(tempName, tempPosition);
if(getPlayerXName().equalsIgnoreCase(tempName))
{
myPlayerXPosition = tempPosition;
}
if(getPlayerOName().equalsIgnoreCase(tempName))
{
myPlayerOPosition = tempPosition;
}
tempPosition++;
try
{
tempWins = Integer.parseInt(bufReader.readLine());
}
catch(NumberFormatException e)
{
e.printStackTrace();
}
myPlayerVector.insertElementAt(tempWins, tempPosition);
tempPosition++;
}
catch (IOException e)
{
e.printStackTrace();
}
if(getPlayerXName().equalsIgnoreCase(tempName))
{
setPlayerXWins(tempWins);
myPlayerXNewPlayer = false;
}
if(getPlayerOName().equalsIgnoreCase(tempName))
{
setPlayerOWins(tempWins);
myPlayerONewPlayer = false;
}
}
}
public void incrementWin(int aPlayerType)
{
if(aPlayerType == getPlayerOType())
{
myPlayerO.incrementWins();
}
if(aPlayerType == getPlayerXType())
{
myPlayerX.incrementWins();
}
updateScore();
}
public void changePlayersNames()
{
this.writePlayers();
myPlayerVector.clear();
String playerXName = JOptionPane.showInputDialog(
"Please enter player X's name.");
String playerOName = JOptionPane.showInputDialog(
"Please enter player O's name.");
this.setPlayerXName(playerXName);
this.setPlayerOName(playerOName);
this.readPlayers();
myView.changeNames();
myView.setWins();
}
////////////////////////////
// Accessor Methods //
////////////////////////////
public int getNumDraws()
{
return myModel.getNumberDraws();
}
public String getMessages()
{
return myModel.getMessages();
}
public void setMusic(Integer aSong)
{
myModel.setMusic(aSong);
}
public String getPlayerXName()
{
return myPlayerX.getName();
}
public String getPlayerOName()
{
return myPlayerO.getName();
}
public int getPlayerXWins()
{
return myPlayerX.getNumWins();
}
public int getPlayerOWins()
{
return myPlayerO.getNumWins();
}
public int getPlayerXType()
{
return myPlayerX.getType();
}
public int getPlayerOType()
{
return myPlayerO.getType();
}
public int getNoPlayerType()
{
return myPlayerO.NO_PLAYER;
}
private void setPlayerXWins(int aNumWins)
{
myPlayerX.setNumWins(aNumWins);
}
private void setPlayerOWins(int aNumWins)
{
myPlayerO.setNumWins(aNumWins);
}
private void setPlayerXName(String aName)
{
myPlayerX.setName(aName);
}
private void setPlayerOName(String aName)
{
myPlayerO.setName(aName);
}
}