- cleaned up networking stuff
- added a state machine to the game - added a status label
This commit is contained in:
parent
8ae82e9f9a
commit
16a6d49c77
7 changed files with 420 additions and 248 deletions
|
@ -19,7 +19,9 @@
|
|||
package de.itsblue.ConnectFour;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.Serializable;
|
||||
import java.awt.event.*;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
|
@ -27,7 +29,7 @@ import de.itsblue.ConnectFour.Plate.PlateType;
|
|||
import de.itsblue.ConnectFour.player.Player;
|
||||
import de.itsblue.ConnectFour.player.*;
|
||||
|
||||
public class ConnectFour extends JFrame implements PlayerMoveListener {
|
||||
public class ConnectFour extends JFrame implements ActionListener {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -40,6 +42,10 @@ public class ConnectFour extends JFrame implements PlayerMoveListener {
|
|||
private ControllRow controllRow;
|
||||
|
||||
private int player = 0;
|
||||
private JLabel statusLabel;
|
||||
|
||||
private int currentPlayer = -1;
|
||||
private int winnerPlayer = -1;
|
||||
|
||||
private Player players[] = new Player[2];
|
||||
|
||||
|
@ -49,6 +55,12 @@ public class ConnectFour extends JFrame implements PlayerMoveListener {
|
|||
Local, RemoteServer, RemoteClient
|
||||
}
|
||||
|
||||
private GameState gameState = GameState.Idle;
|
||||
|
||||
enum GameState {
|
||||
Idle, Waiting, Running, Over
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
|
@ -65,12 +77,14 @@ public class ConnectFour extends JFrame implements PlayerMoveListener {
|
|||
|
||||
// initialize GameBoard
|
||||
this.gameBoard = new GameBoard();
|
||||
this.gameBoard.addActionListener(this);
|
||||
|
||||
// initialize ButtonRow
|
||||
this.buttonRow = new ButtonRow(this.gameBoard.getColumns());
|
||||
|
||||
// initialize ContollRow
|
||||
this.controllRow = new ControllRow(this.gameBoard.getColumns());
|
||||
this.statusLabel = new JLabel();
|
||||
|
||||
// add components to window
|
||||
c.gridx = 0;
|
||||
|
@ -85,64 +99,165 @@ public class ConnectFour extends JFrame implements PlayerMoveListener {
|
|||
c.gridy = 1;
|
||||
this.add(gameBoard, c);
|
||||
|
||||
c.gridy = 2;
|
||||
this.add(this.statusLabel, c);
|
||||
|
||||
// finish up
|
||||
this.pack();
|
||||
this.setVisible(true);
|
||||
}
|
||||
|
||||
public void startNewGame(GameType type) {
|
||||
if (this.gameState != GameState.Idle)
|
||||
return;
|
||||
|
||||
this.gameType = type;
|
||||
|
||||
this.setGameState(GameState.Waiting);
|
||||
switch (type) {
|
||||
case Local: {
|
||||
this.players[0] = new LocalPlayer(this.buttonRow, PlateType.O);
|
||||
this.players[0].addMoveListener(this);
|
||||
this.players[1] = new LocalPlayer(this.buttonRow, PlateType.X);
|
||||
this.players[1].addMoveListener(this);
|
||||
|
||||
this.player = 0;
|
||||
this.players[player].setIsMyTurn(true);
|
||||
this.players[0].addActionListener(this);
|
||||
this.players[1].addActionListener(this);
|
||||
|
||||
this.currentPlayer = 0;
|
||||
this.players[this.currentPlayer].setIsMyTurn(true);
|
||||
break;
|
||||
}
|
||||
|
||||
case RemoteClient: {
|
||||
this.players[0] = new LocalPlayer(this.buttonRow, null);
|
||||
this.players[1] = new RemotePlayerClient(this.buttonRow, "localhost", this.players[0]);
|
||||
|
||||
this.players[0].addMoveListener(this);
|
||||
this.players[1].addMoveListener(this);
|
||||
try {
|
||||
this.players[1] = new RemotePlayerClient(this.buttonRow, "localhost", this.players[0]);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
this.players[0].addActionListener(this);
|
||||
this.players[1].addActionListener(this);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case RemoteServer: {
|
||||
this.players[0] = new LocalPlayer(this.buttonRow, PlateType.O);
|
||||
|
||||
try {
|
||||
this.players[1] = new RemotePlayerServer(this.buttonRow, PlateType.X, this.players[0]);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
this.players[0].addMoveListener(this);
|
||||
this.players[1].addMoveListener(this);
|
||||
this.players[0].addActionListener(this);
|
||||
this.players[1].addActionListener(this);
|
||||
|
||||
this.player = 0;
|
||||
this.players[player].setIsMyTurn(true);
|
||||
this.currentPlayer = 0;
|
||||
this.players[0].setIsMyTurn(true);
|
||||
this.players[1].setIsMyTurn(false);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.setGameState(GameState.Running);
|
||||
}
|
||||
|
||||
private void gameOver(String gameOverType) {
|
||||
if (gameOverType.equals("draw")) {
|
||||
this.winnerPlayer = -1;
|
||||
this.statusLabel.setText("Game over. This was a draw!");
|
||||
} else {
|
||||
PlateType winnerPlateType = PlateType.valueOf(gameOverType);
|
||||
this.winnerPlayer = this.players[0].getUsedPlateType().equals(winnerPlateType) ? 0 : 1;
|
||||
if(!this.gameType.equals(GameType.Local) && this.players[this.winnerPlayer] instanceof LocalPlayer)
|
||||
this.statusLabel.setText("Game over. You won the game!");
|
||||
else
|
||||
this.statusLabel.setText("Game over. " + this.players[this.winnerPlayer].getName() + " won the game!");
|
||||
}
|
||||
|
||||
this.setGameState(GameState.Over);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to switch the player
|
||||
* Function to switch the current player
|
||||
*/
|
||||
private void switchPlayer() {
|
||||
this.players[player].setIsMyTurn(false);
|
||||
this.players[this.currentPlayer].setIsMyTurn(false);
|
||||
|
||||
if (player == 0) {
|
||||
player = 1;
|
||||
if (this.currentPlayer == 0) {
|
||||
this.currentPlayer = 1;
|
||||
} else {
|
||||
player = 0;
|
||||
this.currentPlayer = 0;
|
||||
}
|
||||
|
||||
this.players[player].setIsMyTurn(true);
|
||||
this.players[this.currentPlayer].setIsMyTurn(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
// catch player moves
|
||||
if (e.getSource() instanceof Player) {
|
||||
Player src = (Player) e.getSource();
|
||||
if (e.getActionCommand().startsWith("doMove")
|
||||
&& (this.gameType == GameType.RemoteClient || this.players[this.currentPlayer].equals(src))) {
|
||||
|
||||
boolean res = this.gameBoard.insertPlate(new Plate(src.getUsedPlateType()),
|
||||
Integer.parseInt(e.getActionCommand().split(" ")[1]));
|
||||
|
||||
if (!res) {
|
||||
// beep in case of error
|
||||
Toolkit.getDefaultToolkit().beep();
|
||||
}
|
||||
|
||||
if (this.gameType != GameType.RemoteClient && this.gameState.equals(GameState.Running))
|
||||
switchPlayer();
|
||||
} else if (e.getActionCommand().startsWith("isMyTurnChanged")) {
|
||||
if(e.getActionCommand().split(" ")[1].equals("true")) {
|
||||
if(!this.gameType.equals(GameType.Local) && src instanceof LocalPlayer)
|
||||
this.statusLabel.setText("Running, it's your turn!'");
|
||||
else
|
||||
this.statusLabel.setText("Running, it's " + src.getName() + "'s turn!'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// catch board events
|
||||
if (e.getSource() instanceof GameBoard) {
|
||||
if (e.getActionCommand().startsWith("gameOver")) {
|
||||
this.gameOver(e.getActionCommand().split(" ")[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setGameState(GameState newState) {
|
||||
this.gameState = newState;
|
||||
|
||||
switch (this.gameState) {
|
||||
case Idle:
|
||||
this.statusLabel.setText("IDLE");
|
||||
this.buttonRow.setEnabled(false);
|
||||
break;
|
||||
|
||||
case Waiting:
|
||||
this.statusLabel.setText("Waiting for opponent to connect");
|
||||
this.buttonRow.setEnabled(false);
|
||||
break;
|
||||
|
||||
case Running:
|
||||
this.buttonRow.setEnabled(true);
|
||||
break;
|
||||
|
||||
case Over:
|
||||
this.buttonRow.setEnabled(false);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -155,29 +270,6 @@ public class ConnectFour extends JFrame implements PlayerMoveListener {
|
|||
return this.getSize().height < this.getSize().width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Catch player moves
|
||||
*/
|
||||
@Override
|
||||
public void movePerformed(int column, Player src) {
|
||||
if (this.players[this.player].equals(src) || this.gameType == GameType.RemoteClient) {
|
||||
String res;
|
||||
|
||||
res = this.gameBoard.insertPlate(new Plate(src.usingPlateType), column);
|
||||
|
||||
if (res == "err") {
|
||||
// beep in case of error
|
||||
Toolkit.getDefaultToolkit().beep();
|
||||
} else if (res != "ok" && res != "err") {
|
||||
PlateType winnerType = PlateType.valueOf(res);
|
||||
System.out.println("A player won: " + winnerType);
|
||||
}
|
||||
|
||||
if (this.gameType != GameType.RemoteClient)
|
||||
switchPlayer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override validate in order to resacle the components when the window is
|
||||
* rescaled
|
||||
|
@ -206,9 +298,6 @@ public class ConnectFour extends JFrame implements PlayerMoveListener {
|
|||
ConnectFour game;
|
||||
System.out.println(game = new ConnectFour());
|
||||
|
||||
System.out.println("argc: " + args.length);
|
||||
System.out.println("args[0]: " + args[0]);
|
||||
|
||||
if (args.length <= 0)
|
||||
game.startNewGame(GameType.Local);
|
||||
else if (args[0].equals("server"))
|
||||
|
|
|
@ -20,6 +20,8 @@ package de.itsblue.ConnectFour;
|
|||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import de.itsblue.ConnectFour.Plate.PlateType;
|
||||
|
||||
|
@ -58,6 +60,16 @@ public class GameBoard extends JPanel {
|
|||
*/
|
||||
private boolean boardLocked = false;
|
||||
|
||||
/**
|
||||
* An array containing all action listeners
|
||||
*/
|
||||
private ArrayList<ActionListener> playerActionListeners = new ArrayList<ActionListener>();
|
||||
|
||||
/**
|
||||
* The current action id
|
||||
*/
|
||||
private int currentActionId = 0;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
|
@ -85,11 +97,11 @@ public class GameBoard extends JPanel {
|
|||
* @return "ok" if the inserton was successfull, "err" if the column is full,
|
||||
* PlateType as string if a plate type has won
|
||||
*/
|
||||
public String insertPlate(Plate plate, int column) {
|
||||
public boolean insertPlate(Plate plate, int column) {
|
||||
|
||||
// check if the column is out of range
|
||||
if (column > boardColumns - 1 || this.boardLocked)
|
||||
return "err";
|
||||
return false;
|
||||
|
||||
// search for an empty row
|
||||
for (int i = boardRows - 1; i >= 0; i--) {
|
||||
|
@ -97,16 +109,13 @@ public class GameBoard extends JPanel {
|
|||
// if the container is empty -> add the plate
|
||||
this.BoardContainers[column][i].insertPlate(plate);
|
||||
|
||||
PlateType winCheckResult = this.checkForWin();
|
||||
this.checkForResult();
|
||||
|
||||
if (winCheckResult == null)
|
||||
return "ok";
|
||||
|
||||
return winCheckResult.toString();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return "err";
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -169,18 +178,40 @@ public class GameBoard extends JPanel {
|
|||
* @return <code>null</code> if there was no matching chain; otherwise the
|
||||
* PlateType of the chain that was found
|
||||
*/
|
||||
public PlateType checkForWin() {
|
||||
public PlateType checkForResult() {
|
||||
for (int c = 0; c < this.boardColumns; c++) {
|
||||
for (int r = 0; r < this.boardRows; r++) {
|
||||
PlateType res = this.checkContainerForWin(c, r);
|
||||
if (res != null)
|
||||
if (res != null) {
|
||||
this.fireActionListeners("gameOver " + res.toString());
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(this.isFull()) {
|
||||
this.boardLocked = true;
|
||||
this.fireActionListeners("gameOver draw");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isFull() {
|
||||
boolean allContainersOccupied = true;
|
||||
|
||||
for (int c = 0; c < this.boardColumns; c++) {
|
||||
for (int r = 0; r < this.boardRows; r++) {
|
||||
if(!this.getPlateContainer(c, r).containsPlate()) {
|
||||
allContainersOccupied = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allContainersOccupied;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to check if a certain container is the beginning of a four plate log
|
||||
* chain of plates of the same type what would indicate the end of the game. If
|
||||
|
@ -325,6 +356,38 @@ public class GameBoard extends JPanel {
|
|||
return this.boardRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to fire all actionListeners with a given action command
|
||||
*
|
||||
* @param actionCommand The action command to fire the listeners with
|
||||
*/
|
||||
protected void fireActionListeners(String actionCommand) {
|
||||
for (ActionListener playerActionListener : playerActionListeners) {
|
||||
ActionEvent e = new ActionEvent(this, this.currentActionId, actionCommand);
|
||||
playerActionListener.actionPerformed(e);
|
||||
this.currentActionId++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to add an ActionListener
|
||||
*
|
||||
* @param listener the listener to add
|
||||
*/
|
||||
public void addActionListener(ActionListener listener) {
|
||||
this.playerActionListeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to remove an ActionListener
|
||||
*
|
||||
* @param listener the listener to remove
|
||||
*/
|
||||
public void removeMoveListener(ActionListener listener) {
|
||||
if (this.playerActionListeners.contains(listener))
|
||||
this.playerActionListeners.remove(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override paint function to rescale all containers on every repaint
|
||||
*/
|
||||
|
|
|
@ -21,6 +21,8 @@ package de.itsblue.ConnectFour.player;
|
|||
import de.itsblue.ConnectFour.Plate.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.awt.event.*;
|
||||
import java.awt.*;
|
||||
|
||||
import de.itsblue.ConnectFour.*;
|
||||
|
||||
|
@ -35,22 +37,27 @@ public abstract class Player {
|
|||
/**
|
||||
* The button row used to control the game.
|
||||
*/
|
||||
public ButtonRow gameControllingButtonRow;
|
||||
protected ButtonRow gameControllingButtonRow;
|
||||
|
||||
/**
|
||||
* The type of plate the player is using.
|
||||
*/
|
||||
public PlateType usingPlateType;
|
||||
protected PlateType usingPlateType;
|
||||
|
||||
/**
|
||||
* An array containing all move listeners
|
||||
* An array containing all action listeners
|
||||
*/
|
||||
ArrayList<PlayerMoveListener> playerMoveListeners = new ArrayList<PlayerMoveListener>();
|
||||
private ArrayList<ActionListener> playerActionListeners = new ArrayList<ActionListener>();
|
||||
|
||||
/**
|
||||
* The current action id
|
||||
*/
|
||||
private int currentActionId = 0;
|
||||
|
||||
/**
|
||||
* Whether it is this player's turn
|
||||
*/
|
||||
public boolean isMyTurn = false;
|
||||
protected boolean isMyTurn = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -72,6 +79,7 @@ public abstract class Player {
|
|||
if (isMyTurn)
|
||||
this.gameControllingButtonRow.setColor(Plate.getColor(this.usingPlateType));
|
||||
|
||||
this.fireActionListeners("isMyTurnChanged " + (isMyTurn ? "true" : "false"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -79,31 +87,60 @@ public abstract class Player {
|
|||
*
|
||||
* @param column the column to insert the plate into
|
||||
*/
|
||||
public void doMove(int column) {
|
||||
protected void doMove(int column) {
|
||||
if (this.isMyTurn) {
|
||||
System.out.println("[LOG] " + Plate.getColor(this.usingPlateType) + " is doing a move in col: " + column);
|
||||
for (PlayerMoveListener playerMoveListener : playerMoveListeners) {
|
||||
playerMoveListener.movePerformed(column, this);
|
||||
}
|
||||
this.fireActionListeners("doMove " + column);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to add a move listener
|
||||
* Function to get the plate type used by the player
|
||||
*
|
||||
* @return used plate type
|
||||
*/
|
||||
public PlateType getUsedPlateType() {
|
||||
return this.usingPlateType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get the name of the player
|
||||
*
|
||||
* @return player name
|
||||
*/
|
||||
public String getName() {
|
||||
Color winnerColor = Plate.getColor(this.usingPlateType);
|
||||
return winnerColor.equals(Color.BLACK) ? "Black":"Red";
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to fire all actionListeners with a given action command
|
||||
*
|
||||
* @param actionCommand The action command to fire the listeners with
|
||||
*/
|
||||
protected void fireActionListeners(String actionCommand) {
|
||||
for (ActionListener playerActionListener : playerActionListeners) {
|
||||
ActionEvent e = new ActionEvent(this, this.currentActionId, actionCommand);
|
||||
playerActionListener.actionPerformed(e);
|
||||
this.currentActionId++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to add an ActionListener
|
||||
*
|
||||
* @param listener the listener to add
|
||||
*/
|
||||
public void addMoveListener(PlayerMoveListener listener) {
|
||||
this.playerMoveListeners.add(listener);
|
||||
public void addActionListener(ActionListener listener) {
|
||||
this.playerActionListeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to remove a move listener
|
||||
* Function to remove an ActionListener
|
||||
*
|
||||
* @param listener the listener to remove
|
||||
*/
|
||||
public void removeMoveListener(PlayerMoveListener listener) {
|
||||
if(this.playerMoveListeners.contains(listener))
|
||||
this.playerMoveListeners.remove(listener);
|
||||
public void removeMoveListener(ActionListener listener) {
|
||||
if (this.playerActionListeners.contains(listener))
|
||||
this.playerActionListeners.remove(listener);
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
package de.itsblue.ConnectFour.player;
|
||||
|
||||
public abstract interface PlayerMoveListener {
|
||||
public abstract void movePerformed(int column, Player src);
|
||||
}
|
116
src/de/itsblue/ConnectFour/player/RemotePlayer.java
Normal file
116
src/de/itsblue/ConnectFour/player/RemotePlayer.java
Normal file
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
Connect four - written in java
|
||||
Copyright (C) 2020 Oliver Schappacher and Dorian Zedler
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.itsblue.ConnectFour.player;
|
||||
|
||||
import de.itsblue.ConnectFour.Plate.*;
|
||||
|
||||
import java.awt.event.*;
|
||||
import java.util.Scanner;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.Socket;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import de.itsblue.ConnectFour.*;
|
||||
|
||||
/**
|
||||
* Player is an abstract class meant for usage with de.itsblue.ConnectFour. It
|
||||
* is a template for a connect four player.
|
||||
*
|
||||
* @author Dorian Zedler
|
||||
*/
|
||||
public abstract class RemotePlayer extends Player implements ActionListener {
|
||||
|
||||
protected Socket socket;
|
||||
protected Scanner in;
|
||||
protected PrintWriter out;
|
||||
|
||||
protected Player opponent;
|
||||
|
||||
public RemotePlayer(ButtonRow gameControllingButtonRow, PlateType usingPlateType, Player opponent) {
|
||||
super(gameControllingButtonRow, usingPlateType);
|
||||
this.opponent = opponent;
|
||||
opponent.addActionListener(this);
|
||||
}
|
||||
|
||||
protected void startListening() {
|
||||
// listen to the socket
|
||||
ExecutorService pool = Executors.newFixedThreadPool(200);
|
||||
pool.execute(this.new SocketListener(this.in, this));
|
||||
}
|
||||
|
||||
protected abstract void handleResponse(String response);
|
||||
|
||||
/**
|
||||
* Function to set wether it is this player's turn
|
||||
*/
|
||||
@Override
|
||||
public void setIsMyTurn(boolean isMyTurn) {
|
||||
super.setIsMyTurn(isMyTurn);
|
||||
|
||||
if (isMyTurn)
|
||||
this.gameControllingButtonRow.setEnabled(false);
|
||||
else
|
||||
this.gameControllingButtonRow.setEnabled(true);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
if(!(e.getSource() instanceof Player))
|
||||
return;
|
||||
|
||||
if (e.getActionCommand().startsWith("doMove")) {
|
||||
int column = Integer.parseInt(e.getActionCommand().split(" ")[1]);
|
||||
try {
|
||||
this.out.println("movePerformed " + column);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SocketListener implements Runnable {
|
||||
RemotePlayer parent;
|
||||
Scanner in;
|
||||
|
||||
public SocketListener(Scanner in, RemotePlayer parent) {
|
||||
this.parent = parent;
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// listen to the socket
|
||||
try {
|
||||
while (in.hasNextLine()) {
|
||||
String response = in.nextLine();
|
||||
|
||||
this.parent.handleResponse(response);
|
||||
|
||||
}
|
||||
out.println("QUIT");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
package de.itsblue.ConnectFour.player;
|
||||
|
||||
import java.awt.event.*;
|
||||
import java.util.Scanner;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
@ -35,114 +34,39 @@ import de.itsblue.ConnectFour.*;
|
|||
*
|
||||
* @author Dorian Zedler
|
||||
*/
|
||||
public class RemotePlayerClient extends Player implements PlayerMoveListener {
|
||||
|
||||
private Socket socket;
|
||||
private Scanner in;
|
||||
private PrintWriter out;
|
||||
|
||||
private Player opponent;
|
||||
public class RemotePlayerClient extends RemotePlayer {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param controlledByButtonRow The button row used to control the player.
|
||||
*/
|
||||
public RemotePlayerClient(ButtonRow gameControllingButtonRow, String serverAddress, Player opponent) {
|
||||
super(gameControllingButtonRow, null);
|
||||
public RemotePlayerClient(ButtonRow gameControllingButtonRow, String serverAddress, Player opponent)
|
||||
throws IOException {
|
||||
super(gameControllingButtonRow, null, opponent);
|
||||
|
||||
this.opponent = opponent;
|
||||
opponent.addMoveListener(this);
|
||||
|
||||
try {
|
||||
// initialize the socket
|
||||
socket = new Socket(serverAddress, 4444);
|
||||
in = new Scanner(socket.getInputStream());
|
||||
out = new PrintWriter(socket.getOutputStream(), true);
|
||||
System.out.println("Connected to Connect4 server");
|
||||
|
||||
// get our plate type
|
||||
String response = in.nextLine();
|
||||
if (response.split(" ")[0].equals("setUsingPlateType")) {
|
||||
this.usingPlateType = PlateType.valueOf(response.split(" ")[1]);
|
||||
this.opponent.usingPlateType = this.usingPlateType.equals(PlateType.O) ? PlateType.X : PlateType.O;
|
||||
}
|
||||
|
||||
// check if it is out turn
|
||||
response = in.nextLine();
|
||||
if (response.split(" ")[0].equals("setIsMyTurn")) {
|
||||
this.setIsMyTurn(response.split(" ")[1].equals("true"));
|
||||
opponent.setIsMyTurn(response.split(" ")[1].equals("false"));
|
||||
}
|
||||
|
||||
// listen to the socket
|
||||
ExecutorService pool = Executors.newFixedThreadPool(200);
|
||||
pool.execute(this.new ClientListener(in, this));
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.startListening();
|
||||
|
||||
}
|
||||
|
||||
public void handleResponse(String response) {
|
||||
System.out.println("[CLIENT]GOT: " + response);
|
||||
|
||||
if(response.startsWith("setIsMyTurn")) {
|
||||
if (response.startsWith("setUsingPlateType")) {
|
||||
// handle PlateType change
|
||||
this.usingPlateType = PlateType.valueOf(response.split(" ")[1]);
|
||||
this.opponent.usingPlateType = this.usingPlateType == PlateType.O ? PlateType.X : PlateType.O;
|
||||
} else if (response.startsWith("setIsMyTurn")) {
|
||||
// handle turn change
|
||||
this.setIsMyTurn(response.split(" ")[1].equals("true"));
|
||||
opponent.setIsMyTurn(response.split(" ")[1].equals("false"));
|
||||
} else if (response.startsWith("movePerformed")) {
|
||||
// handle move performed
|
||||
this.doMove(Integer.parseInt(response.split(" ")[1]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to set wether it is this player's turn
|
||||
*/
|
||||
@Override
|
||||
public void setIsMyTurn(boolean isMyTurn) {
|
||||
super.setIsMyTurn(isMyTurn);
|
||||
|
||||
if (isMyTurn)
|
||||
this.gameControllingButtonRow.setEnabled(false);
|
||||
else
|
||||
this.gameControllingButtonRow.setEnabled(true);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void movePerformed(int column, Player src) {
|
||||
try {
|
||||
this.out.println("movePerformed " + column);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
class ClientListener implements Runnable {
|
||||
|
||||
RemotePlayerClient parent;
|
||||
Scanner in;
|
||||
|
||||
public ClientListener(Scanner in, RemotePlayerClient parent) {
|
||||
this.parent = parent;
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// listen to the socket
|
||||
try {
|
||||
while (in.hasNextLine()) {
|
||||
String response = in.nextLine();
|
||||
|
||||
this.parent.handleResponse(response);
|
||||
|
||||
}
|
||||
out.println("QUIT");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
package de.itsblue.ConnectFour.player;
|
||||
|
||||
import java.awt.event.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.ServerSocket;
|
||||
|
@ -36,14 +38,9 @@ import de.itsblue.ConnectFour.*;
|
|||
*
|
||||
* @author Dorian Zedler
|
||||
*/
|
||||
public class RemotePlayerServer extends Player implements PlayerMoveListener {
|
||||
public class RemotePlayerServer extends RemotePlayer {
|
||||
|
||||
private ServerSocket listener;
|
||||
private Socket clientSocket;
|
||||
private Scanner in;
|
||||
private PrintWriter out;
|
||||
|
||||
private Player opponent;
|
||||
private ServerSocket serverSocket;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -51,90 +48,41 @@ public class RemotePlayerServer extends Player implements PlayerMoveListener {
|
|||
* @param controlledByButtonRow The button row used to control the player.
|
||||
* @param usingPlateType The type of plate the player is using.
|
||||
*/
|
||||
public RemotePlayerServer(ButtonRow gameControllingButtonRow, PlateType usingPlateType, Player opponent) {
|
||||
super(gameControllingButtonRow, usingPlateType);
|
||||
public RemotePlayerServer(ButtonRow gameControllingButtonRow, PlateType usingPlateType, Player opponent)
|
||||
throws Exception {
|
||||
super(gameControllingButtonRow, usingPlateType, opponent);
|
||||
|
||||
this.opponent = opponent;
|
||||
opponent.addMoveListener(this);
|
||||
|
||||
try {
|
||||
this.listener = new ServerSocket(4444);
|
||||
this.serverSocket = new ServerSocket(4444);
|
||||
System.out.println("Connect4 Server is Running...");
|
||||
|
||||
this.clientSocket = listener.accept();
|
||||
this.in = new Scanner(this.clientSocket.getInputStream());
|
||||
this.out = new PrintWriter(this.clientSocket.getOutputStream(), true);
|
||||
this.socket = serverSocket.accept(); // gets stuck here until someone connects
|
||||
this.in = new Scanner(this.socket.getInputStream());
|
||||
this.out = new PrintWriter(this.socket.getOutputStream(), true);
|
||||
|
||||
System.out.println("Client connected");
|
||||
|
||||
out.println("setUsingPlateType " + this.opponent.usingPlateType.name());
|
||||
out.println("setIsMyTurn " + (this.opponent.isMyTurn ? "true" : "false"));
|
||||
|
||||
ExecutorService pool = Executors.newFixedThreadPool(200);
|
||||
pool.execute(this.new ServerListener(in, this));
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.startListening();
|
||||
}
|
||||
|
||||
public void handleResponse(String response) {
|
||||
System.out.println("GOT: " + response);
|
||||
if (response.startsWith("movePerformed")) {
|
||||
this.doMove(Integer.parseInt(response.split(" ")[1]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to set wether it is this player's turn
|
||||
* Catch actions of opponent and forward them to client
|
||||
*/
|
||||
@Override
|
||||
public void setIsMyTurn(boolean isMyTurn) {
|
||||
super.setIsMyTurn(isMyTurn);
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
if(isMyTurn)
|
||||
this.gameControllingButtonRow.setEnabled(false);
|
||||
else
|
||||
this.gameControllingButtonRow.setEnabled(true);
|
||||
super.actionPerformed(e);
|
||||
|
||||
out.println("setIsMyTurn " + (this.isMyTurn ? "false":"true"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void movePerformed(int column, Player src) {
|
||||
System.out.println("movePerformed");
|
||||
try {
|
||||
this.out.println("movePerformed " + column);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (e.getActionCommand().startsWith("isMyTurnChanged")) {
|
||||
out.println("setIsMyTurn " + (e.getActionCommand().split(" ")[1]));
|
||||
}
|
||||
}
|
||||
|
||||
class ServerListener implements Runnable {
|
||||
|
||||
RemotePlayerServer parent;
|
||||
Scanner in;
|
||||
|
||||
public ServerListener(Scanner in, RemotePlayerServer parent) {
|
||||
this.parent = parent;
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// listen to the socket
|
||||
try {
|
||||
while (in.hasNextLine()) {
|
||||
String response = in.nextLine();
|
||||
|
||||
this.parent.handleResponse(response);
|
||||
|
||||
}
|
||||
out.println("QUIT");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Reference in a new issue