Added some checks to the server to enshure that moves of the client are legal
This commit is contained in:
parent
cc65762f95
commit
0c972d335c
5 changed files with 124 additions and 55 deletions
|
@ -40,7 +40,6 @@ public class ConnectFour extends JFrame implements ActionListener {
|
||||||
|
|
||||||
private ControllRow controllRow;
|
private ControllRow controllRow;
|
||||||
|
|
||||||
private int player = 0;
|
|
||||||
private JLabel statusLabel;
|
private JLabel statusLabel;
|
||||||
|
|
||||||
private int currentPlayer = -1;
|
private int currentPlayer = -1;
|
||||||
|
@ -60,6 +59,10 @@ public class ConnectFour extends JFrame implements ActionListener {
|
||||||
Idle, Waiting, Running, Over
|
Idle, Waiting, Running, Over
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum GameOverReason {
|
||||||
|
Winner, Draw, OpponentDisconnected, Error
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
|
@ -135,7 +138,8 @@ public class ConnectFour extends JFrame implements ActionListener {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.players[0].addActionListener(this);
|
// do not add the listener of the local player here, as the client player will
|
||||||
|
// handle its moves in order to make shure they are legal
|
||||||
this.players[1].addActionListener(this);
|
this.players[1].addActionListener(this);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -164,20 +168,33 @@ public class ConnectFour extends JFrame implements ActionListener {
|
||||||
this.setGameState(GameState.Running);
|
this.setGameState(GameState.Running);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void gameOver(String gameOverType) {
|
private void gameOver(GameOverReason reason, String attributes) {
|
||||||
if (!this.gameState.equals(GameState.Running))
|
if (!this.gameState.equals(GameState.Running))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (gameOverType.equals("draw")) {
|
if (this.gameType.equals(GameType.RemoteServer))
|
||||||
this.winnerPlayer = -1;
|
((RemotePlayerServer) this.players[1]).notifyGameOver(reason.toString() + " " + attributes);
|
||||||
this.statusLabel.setText("Game over. This was a draw!");
|
|
||||||
} else {
|
switch (reason) {
|
||||||
PlateType winnerPlateType = PlateType.valueOf(gameOverType);
|
case Draw:
|
||||||
this.winnerPlayer = this.players[0].getUsedPlateType().equals(winnerPlateType) ? 0 : 1;
|
this.winnerPlayer = -1;
|
||||||
if (!this.gameType.equals(GameType.Local) && this.players[this.winnerPlayer] instanceof LocalPlayer)
|
this.statusLabel.setText("Game over. This was a draw!");
|
||||||
this.statusLabel.setText("Game over. You won the game!");
|
break;
|
||||||
else
|
|
||||||
this.statusLabel.setText("Game over. " + this.players[this.winnerPlayer].getName() + " won the game!");
|
case Winner:
|
||||||
|
PlateType winnerPlateType = PlateType.valueOf(attributes);
|
||||||
|
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!");
|
||||||
|
|
||||||
|
case OpponentDisconnected:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Error:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setGameState(GameState.Over);
|
this.setGameState(GameState.Over);
|
||||||
|
@ -187,6 +204,9 @@ public class ConnectFour extends JFrame implements ActionListener {
|
||||||
if (!this.gameState.equals(GameState.Over))
|
if (!this.gameState.equals(GameState.Over))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if(this.gameType.equals(GameType.RemoteServer))
|
||||||
|
((RemotePlayerServer) this.players[1]).notifyGameReset();
|
||||||
|
|
||||||
this.players[0] = null;
|
this.players[0] = null;
|
||||||
this.players[1] = null;
|
this.players[1] = null;
|
||||||
this.currentPlayer = -1;
|
this.currentPlayer = -1;
|
||||||
|
@ -217,6 +237,7 @@ public class ConnectFour extends JFrame implements ActionListener {
|
||||||
if (e.getSource() instanceof Player) {
|
if (e.getSource() instanceof Player) {
|
||||||
Player src = (Player) e.getSource();
|
Player src = (Player) e.getSource();
|
||||||
if (e.getActionCommand().startsWith("doMove")
|
if (e.getActionCommand().startsWith("doMove")
|
||||||
|
// handle moves
|
||||||
&& (this.gameType == GameType.RemoteClient || this.players[this.currentPlayer].equals(src))) {
|
&& (this.gameType == GameType.RemoteClient || this.players[this.currentPlayer].equals(src))) {
|
||||||
|
|
||||||
boolean res = this.gameBoard.insertPlate(new Plate(src.getUsedPlateType()),
|
boolean res = this.gameBoard.insertPlate(new Plate(src.getUsedPlateType()),
|
||||||
|
@ -229,20 +250,32 @@ public class ConnectFour extends JFrame implements ActionListener {
|
||||||
|
|
||||||
if (this.gameType != GameType.RemoteClient && this.gameState.equals(GameState.Running))
|
if (this.gameType != GameType.RemoteClient && this.gameState.equals(GameState.Running))
|
||||||
switchPlayer();
|
switchPlayer();
|
||||||
|
|
||||||
} else if (e.getActionCommand().startsWith("isMyTurnChanged")) {
|
} else if (e.getActionCommand().startsWith("isMyTurnChanged")) {
|
||||||
|
// handle a turn change
|
||||||
|
|
||||||
if (e.getActionCommand().split(" ")[1].equals("true")) {
|
if (e.getActionCommand().split(" ")[1].equals("true")) {
|
||||||
if (!this.gameType.equals(GameType.Local) && src instanceof LocalPlayer)
|
if (!this.gameType.equals(GameType.Local) && src instanceof LocalPlayer)
|
||||||
this.statusLabel.setText("Running, it's your turn!'");
|
this.statusLabel.setText("Running, it's your turn!'");
|
||||||
else
|
else
|
||||||
this.statusLabel.setText("Running, it's " + src.getName() + "'s turn!'");
|
this.statusLabel.setText("Running, it's " + src.getName() + "'s turn!'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (e.getActionCommand().startsWith("gameReset")) {
|
||||||
|
if(!this.gameState.equals(GameState.Over))
|
||||||
|
this.gameOver(GameOverReason.OpponentDisconnected, "");
|
||||||
|
else
|
||||||
|
this.resetGame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// catch board events
|
// catch board events
|
||||||
if (e.getSource() instanceof GameBoard) {
|
if (e.getSource() instanceof GameBoard) {
|
||||||
if (e.getActionCommand().startsWith("gameOver")) {
|
if (e.getActionCommand().startsWith("gameOver")) {
|
||||||
this.gameOver(e.getActionCommand().split(" ")[1]);
|
if(e.getActionCommand().split(" ")[1].equals("draw"))
|
||||||
|
this.gameOver(GameOverReason.Draw, "");
|
||||||
|
else
|
||||||
|
this.gameOver(GameOverReason.Winner, e.getActionCommand().split(" ")[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ public abstract class Player {
|
||||||
if (isMyTurn)
|
if (isMyTurn)
|
||||||
this.gameControllingButtonRow.setColor(Plate.getColor(this.usingPlateType));
|
this.gameControllingButtonRow.setColor(Plate.getColor(this.usingPlateType));
|
||||||
|
|
||||||
this.fireActionListeners("isMyTurnChanged " + (isMyTurn ? "true" : "false"));
|
this.fireActionListeners(this,"isMyTurnChanged " + (isMyTurn ? "true" : "false"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -89,7 +89,7 @@ public abstract class Player {
|
||||||
*/
|
*/
|
||||||
protected void doMove(int column) {
|
protected void doMove(int column) {
|
||||||
if (this.isMyTurn) {
|
if (this.isMyTurn) {
|
||||||
this.fireActionListeners("doMove " + column);
|
this.fireActionListeners(this, "doMove " + column);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,8 +108,8 @@ public abstract class Player {
|
||||||
* @return player name
|
* @return player name
|
||||||
*/
|
*/
|
||||||
public String getName() {
|
public String getName() {
|
||||||
Color winnerColor = Plate.getColor(this.usingPlateType);
|
Color thisColor = Plate.getColor(this.usingPlateType);
|
||||||
return winnerColor.equals(Color.BLACK) ? "Black":"Red";
|
return thisColor.equals(Color.BLACK) ? "Black":"Red";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -117,10 +117,9 @@ public abstract class Player {
|
||||||
*
|
*
|
||||||
* @param actionCommand The action command to fire the listeners with
|
* @param actionCommand The action command to fire the listeners with
|
||||||
*/
|
*/
|
||||||
protected void fireActionListeners(String actionCommand) {
|
protected void fireActionListeners(Object source, String command) {
|
||||||
for (ActionListener playerActionListener : playerActionListeners) {
|
for (ActionListener playerActionListener : playerActionListeners) {
|
||||||
ActionEvent e = new ActionEvent(this, this.currentActionId, actionCommand);
|
playerActionListener.actionPerformed(new ActionEvent(source, this.currentActionId, command));
|
||||||
playerActionListener.actionPerformed(e);
|
|
||||||
this.currentActionId++;
|
this.currentActionId++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ import de.itsblue.ConnectFour.Plate.*;
|
||||||
|
|
||||||
import java.awt.event.*;
|
import java.awt.event.*;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
@ -73,20 +72,7 @@ public abstract class RemotePlayer extends Player implements ActionListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public abstract 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 {
|
private class SocketListener implements Runnable {
|
||||||
RemotePlayer parent;
|
RemotePlayer parent;
|
||||||
|
|
|
@ -22,8 +22,7 @@ import java.util.Scanner;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.awt.event.*;
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
import de.itsblue.ConnectFour.Plate.*;
|
import de.itsblue.ConnectFour.Plate.*;
|
||||||
import de.itsblue.ConnectFour.*;
|
import de.itsblue.ConnectFour.*;
|
||||||
|
@ -52,21 +51,47 @@ public class RemotePlayerClient extends RemotePlayer {
|
||||||
System.out.println("Connected to Connect4 server");
|
System.out.println("Connected to Connect4 server");
|
||||||
|
|
||||||
this.startListening();
|
this.startListening();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleResponse(String response) {
|
public void handleResponse(String response) {
|
||||||
|
System.out.println("[SOCKET] Got: " + response);
|
||||||
|
|
||||||
if (response.startsWith("setUsingPlateType")) {
|
if (response.startsWith("setUsingPlateType")) {
|
||||||
// handle PlateType change
|
// handle PlateType change
|
||||||
this.usingPlateType = PlateType.valueOf(response.split(" ")[1]);
|
this.opponent.usingPlateType = PlateType.valueOf(response.split(" ")[1]);
|
||||||
this.opponent.usingPlateType = this.usingPlateType == PlateType.O ? PlateType.X : PlateType.O;
|
this.usingPlateType = this.usingPlateType == PlateType.O ? PlateType.X : PlateType.O;
|
||||||
|
|
||||||
} else if (response.startsWith("setIsMyTurn")) {
|
} else if (response.startsWith("setIsMyTurn")) {
|
||||||
// handle turn change
|
// handle turn change
|
||||||
this.setIsMyTurn(response.split(" ")[1].equals("true"));
|
PlateType targetPlateType = PlateType.valueOf(response.split(" ")[1]);
|
||||||
opponent.setIsMyTurn(response.split(" ")[1].equals("false"));
|
Player target = this.getUsedPlateType().equals(targetPlateType) ? this:this.opponent;
|
||||||
|
target.setIsMyTurn(response.split(" ")[2].equals("true"));
|
||||||
|
|
||||||
} else if (response.startsWith("movePerformed")) {
|
} else if (response.startsWith("movePerformed")) {
|
||||||
// handle move performed
|
// handle move performed
|
||||||
this.doMove(Integer.parseInt(response.split(" ")[1]));
|
PlateType targetPlateType = PlateType.valueOf(response.split(" ")[1]);
|
||||||
|
Player target = this.getUsedPlateType().equals(targetPlateType) ? this:this.opponent;
|
||||||
|
this.fireActionListeners(target, "doMove " + Integer.parseInt(response.split(" ")[2]));
|
||||||
|
|
||||||
|
} else if(response.startsWith("gameOver") || response.startsWith("gameReset")) {
|
||||||
|
// handle game over
|
||||||
|
this.fireActionListeners(this, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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("doMove " + column);
|
||||||
|
System.out.println("[SOCKET] SENT: " + "doMove " + column);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,15 +19,10 @@
|
||||||
package de.itsblue.ConnectFour.player;
|
package de.itsblue.ConnectFour.player;
|
||||||
|
|
||||||
import java.awt.event.*;
|
import java.awt.event.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
import java.net.Socket;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
import de.itsblue.ConnectFour.Plate.*;
|
import de.itsblue.ConnectFour.Plate.*;
|
||||||
import de.itsblue.ConnectFour.*;
|
import de.itsblue.ConnectFour.*;
|
||||||
|
@ -52,6 +47,9 @@ public class RemotePlayerServer extends RemotePlayer {
|
||||||
throws Exception {
|
throws Exception {
|
||||||
super(gameControllingButtonRow, usingPlateType, opponent);
|
super(gameControllingButtonRow, usingPlateType, opponent);
|
||||||
|
|
||||||
|
// also catch own actions
|
||||||
|
this.addActionListener(this);
|
||||||
|
|
||||||
this.serverSocket = new ServerSocket(4444);
|
this.serverSocket = new ServerSocket(4444);
|
||||||
System.out.println("Connect4 Server is Running...");
|
System.out.println("Connect4 Server is Running...");
|
||||||
|
|
||||||
|
@ -61,15 +59,31 @@ public class RemotePlayerServer extends RemotePlayer {
|
||||||
|
|
||||||
System.out.println("Client connected");
|
System.out.println("Client connected");
|
||||||
|
|
||||||
out.println("setUsingPlateType " + this.opponent.usingPlateType.name());
|
out.println("setUsingPlateType " + this.usingPlateType.name());
|
||||||
out.println("setIsMyTurn " + (this.opponent.isMyTurn ? "true" : "false"));
|
|
||||||
|
|
||||||
this.startListening();
|
this.startListening();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleResponse(String response) {
|
public void handleResponse(String response) {
|
||||||
if (response.startsWith("movePerformed")) {
|
if (response.startsWith("doMove")) {
|
||||||
this.doMove(Integer.parseInt(response.split(" ")[1]));
|
if (this.isMyTurn)
|
||||||
|
this.doMove(Integer.parseInt(response.split(" ")[1]));
|
||||||
|
else
|
||||||
|
this.out.println("invalidMove " + response.split(" ")[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifyGameOver(String reason) {
|
||||||
|
this.out.println("gameOver " + reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifyGameReset() {
|
||||||
|
this.out.println("gameReset");
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.socket.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,10 +93,22 @@ public class RemotePlayerServer extends RemotePlayer {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
|
||||||
super.actionPerformed(e);
|
if(!(e.getSource() instanceof Player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Player src = (Player)e.getSource();
|
||||||
|
|
||||||
|
if (e.getActionCommand().startsWith("doMove")) {
|
||||||
|
int column = Integer.parseInt(e.getActionCommand().split(" ")[1]);
|
||||||
|
try {
|
||||||
|
this.out.println("movePerformed " + src.getUsedPlateType().toString() + " " + column);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (e.getActionCommand().startsWith("isMyTurnChanged")) {
|
if (e.getActionCommand().startsWith("isMyTurnChanged")) {
|
||||||
out.println("setIsMyTurn " + (e.getActionCommand().split(" ")[1]));
|
out.println("setIsMyTurn " + src.getUsedPlateType().toString() + " " + (e.getActionCommand().split(" ")[1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in a new issue