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 int player = 0;
|
||||
private JLabel statusLabel;
|
||||
|
||||
private int currentPlayer = -1;
|
||||
|
@ -60,6 +59,10 @@ public class ConnectFour extends JFrame implements ActionListener {
|
|||
Idle, Waiting, Running, Over
|
||||
}
|
||||
|
||||
enum GameOverReason {
|
||||
Winner, Draw, OpponentDisconnected, Error
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
|
@ -135,7 +138,8 @@ public class ConnectFour extends JFrame implements ActionListener {
|
|||
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);
|
||||
|
||||
break;
|
||||
|
@ -164,20 +168,33 @@ public class ConnectFour extends JFrame implements ActionListener {
|
|||
this.setGameState(GameState.Running);
|
||||
}
|
||||
|
||||
private void gameOver(String gameOverType) {
|
||||
private void gameOver(GameOverReason reason, String attributes) {
|
||||
if (!this.gameState.equals(GameState.Running))
|
||||
return;
|
||||
|
||||
if (gameOverType.equals("draw")) {
|
||||
if (this.gameType.equals(GameType.RemoteServer))
|
||||
((RemotePlayerServer) this.players[1]).notifyGameOver(reason.toString() + " " + attributes);
|
||||
|
||||
switch (reason) {
|
||||
case Draw:
|
||||
this.winnerPlayer = -1;
|
||||
this.statusLabel.setText("Game over. This was a draw!");
|
||||
} else {
|
||||
PlateType winnerPlateType = PlateType.valueOf(gameOverType);
|
||||
break;
|
||||
|
||||
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!");
|
||||
this.statusLabel
|
||||
.setText("Game over. " + this.players[this.winnerPlayer].getName() + " won the game!");
|
||||
|
||||
case OpponentDisconnected:
|
||||
break;
|
||||
|
||||
case Error:
|
||||
break;
|
||||
}
|
||||
|
||||
this.setGameState(GameState.Over);
|
||||
|
@ -187,6 +204,9 @@ public class ConnectFour extends JFrame implements ActionListener {
|
|||
if (!this.gameState.equals(GameState.Over))
|
||||
return;
|
||||
|
||||
if(this.gameType.equals(GameType.RemoteServer))
|
||||
((RemotePlayerServer) this.players[1]).notifyGameReset();
|
||||
|
||||
this.players[0] = null;
|
||||
this.players[1] = null;
|
||||
this.currentPlayer = -1;
|
||||
|
@ -217,6 +237,7 @@ public class ConnectFour extends JFrame implements ActionListener {
|
|||
if (e.getSource() instanceof Player) {
|
||||
Player src = (Player) e.getSource();
|
||||
if (e.getActionCommand().startsWith("doMove")
|
||||
// handle moves
|
||||
&& (this.gameType == GameType.RemoteClient || this.players[this.currentPlayer].equals(src))) {
|
||||
|
||||
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))
|
||||
switchPlayer();
|
||||
|
||||
} else if (e.getActionCommand().startsWith("isMyTurnChanged")) {
|
||||
// handle a turn change
|
||||
|
||||
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!'");
|
||||
}
|
||||
|
||||
} else if (e.getActionCommand().startsWith("gameReset")) {
|
||||
if(!this.gameState.equals(GameState.Over))
|
||||
this.gameOver(GameOverReason.OpponentDisconnected, "");
|
||||
else
|
||||
this.resetGame();
|
||||
}
|
||||
}
|
||||
|
||||
// catch board events
|
||||
if (e.getSource() instanceof GameBoard) {
|
||||
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)
|
||||
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) {
|
||||
if (this.isMyTurn) {
|
||||
this.fireActionListeners("doMove " + column);
|
||||
this.fireActionListeners(this, "doMove " + column);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,8 +108,8 @@ public abstract class Player {
|
|||
* @return player name
|
||||
*/
|
||||
public String getName() {
|
||||
Color winnerColor = Plate.getColor(this.usingPlateType);
|
||||
return winnerColor.equals(Color.BLACK) ? "Black":"Red";
|
||||
Color thisColor = Plate.getColor(this.usingPlateType);
|
||||
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
|
||||
*/
|
||||
protected void fireActionListeners(String actionCommand) {
|
||||
protected void fireActionListeners(Object source, String command) {
|
||||
for (ActionListener playerActionListener : playerActionListeners) {
|
||||
ActionEvent e = new ActionEvent(this, this.currentActionId, actionCommand);
|
||||
playerActionListener.actionPerformed(e);
|
||||
playerActionListener.actionPerformed(new ActionEvent(source, this.currentActionId, command));
|
||||
this.currentActionId++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ 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;
|
||||
|
@ -73,20 +72,7 @@ public abstract class RemotePlayer extends Player implements ActionListener {
|
|||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
}
|
||||
public abstract void actionPerformed(ActionEvent e);
|
||||
|
||||
private class SocketListener implements Runnable {
|
||||
RemotePlayer parent;
|
||||
|
|
|
@ -22,8 +22,7 @@ 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 java.awt.event.*;
|
||||
|
||||
import de.itsblue.ConnectFour.Plate.*;
|
||||
import de.itsblue.ConnectFour.*;
|
||||
|
@ -52,21 +51,47 @@ public class RemotePlayerClient extends RemotePlayer {
|
|||
System.out.println("Connected to Connect4 server");
|
||||
|
||||
this.startListening();
|
||||
|
||||
}
|
||||
|
||||
public void handleResponse(String response) {
|
||||
System.out.println("[SOCKET] Got: " + response);
|
||||
|
||||
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;
|
||||
this.opponent.usingPlateType = PlateType.valueOf(response.split(" ")[1]);
|
||||
this.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"));
|
||||
PlateType targetPlateType = PlateType.valueOf(response.split(" ")[1]);
|
||||
Player target = this.getUsedPlateType().equals(targetPlateType) ? this:this.opponent;
|
||||
target.setIsMyTurn(response.split(" ")[2].equals("true"));
|
||||
|
||||
} else if (response.startsWith("movePerformed")) {
|
||||
// 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;
|
||||
|
||||
import java.awt.event.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.Arrays;
|
||||
import java.util.Scanner;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import de.itsblue.ConnectFour.Plate.*;
|
||||
import de.itsblue.ConnectFour.*;
|
||||
|
@ -52,6 +47,9 @@ public class RemotePlayerServer extends RemotePlayer {
|
|||
throws Exception {
|
||||
super(gameControllingButtonRow, usingPlateType, opponent);
|
||||
|
||||
// also catch own actions
|
||||
this.addActionListener(this);
|
||||
|
||||
this.serverSocket = new ServerSocket(4444);
|
||||
System.out.println("Connect4 Server is Running...");
|
||||
|
||||
|
@ -61,15 +59,31 @@ public class RemotePlayerServer extends RemotePlayer {
|
|||
|
||||
System.out.println("Client connected");
|
||||
|
||||
out.println("setUsingPlateType " + this.opponent.usingPlateType.name());
|
||||
out.println("setIsMyTurn " + (this.opponent.isMyTurn ? "true" : "false"));
|
||||
out.println("setUsingPlateType " + this.usingPlateType.name());
|
||||
|
||||
this.startListening();
|
||||
}
|
||||
|
||||
public void handleResponse(String response) {
|
||||
if (response.startsWith("movePerformed")) {
|
||||
if (response.startsWith("doMove")) {
|
||||
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
|
||||
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")) {
|
||||
out.println("setIsMyTurn " + (e.getActionCommand().split(" ")[1]));
|
||||
out.println("setIsMyTurn " + src.getUsedPlateType().toString() + " " + (e.getActionCommand().split(" ")[1]));
|
||||
}
|
||||
}
|
||||
}
|
Reference in a new issue