Compare commits

..

15 Commits

9 changed files with 154 additions and 46 deletions

View File

@ -1,27 +1,86 @@
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.PrintWriter; import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
public class AsyncSocket { public class AsyncSocket {
private Socket socket; private Socket socket;
private Thread checkerThread; private Thread checkerThread;
private Thread connectorThread;
private AsyncSocketListener handler; private AsyncSocketListener handler;
private boolean shouldStop = false; private boolean shouldStop = false;
private String sendBuffer = "";
private BufferedReader in; private BufferedReader in;
private PrintWriter out; private BufferedWriter out;
public AsyncSocket(int port, AsyncSocketListener handler) {
this.setHandler(handler);
// start server in new thread
this.connectorThread = new Thread(() -> {
try {
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("Waiting for client connection on port " + port);
Socket socket = serverSocket.accept();
System.out.println("Socket connected.");
serverSocket.close();
this.initSocket(socket);
} catch (IOException e) {
e.printStackTrace();
// TODO: proper error handling
}
});
this.connectorThread.start();
}
public AsyncSocket(InetSocketAddress address, AsyncSocketListener handler) {
this.setHandler(handler);
// start client in new thread
this.connectorThread = new Thread(() -> {
System.out.println("Connecting to " + address.toString());
Socket socket = new Socket();
try {
socket.connect(address, 10);
System.out.println("Socket connected.");
this.initSocket(socket);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Connection timed out");
}
});
this.connectorThread.start();
}
public AsyncSocket(Socket socket, AsyncSocketListener handler) throws IOException { public AsyncSocket(Socket socket, AsyncSocketListener handler) throws IOException {
this.setHandler(handler);
this.initSocket(socket);
}
private void initSocket(Socket socket) throws IOException {
System.out.println("Initialising sockets");
this.socket = socket; this.socket = socket;
this.in = new BufferedReader(new InputStreamReader(this.socket.getInputStream())); this.in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
this.out = new PrintWriter(new OutputStreamWriter(this.socket.getOutputStream())); this.out = new BufferedWriter(new OutputStreamWriter(this.socket.getOutputStream()));
this.handler = handler;
this.shouldStop = false;
this.checkerThread = new Thread(() -> { this.checkerThread = new Thread(() -> {
while (!this.shouldStop) { while (!this.shouldStop) {
try { try {
@ -29,21 +88,38 @@ public class AsyncSocket {
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
if (!this.connectorThread.isAlive()) {
try {
this.connectorThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try { try {
if (!this.in.ready()) continue; if (!this.in.ready()) {
if (this.handler == null) continue; continue;
}
if (this.handler == null) {
continue;
}
String message = this.in.readLine(); String message = this.in.readLine();
if (message.length() <= 0) continue; if (message.length() <= 0) continue;
message = message.strip(); message = message.strip();
System.out.println("RECEIVED - " + message);
this.handler.receive(message); this.handler.receive(message);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
}); });
System.out.println("starting checker thread");
this.checkerThread.start(); this.checkerThread.start();
this.flushBuffer();
} }
public void setHandler(AsyncSocketListener handler) { public void setHandler(AsyncSocketListener handler) {
@ -51,21 +127,36 @@ public class AsyncSocket {
} }
public void send(SocketPackage socketPackage) { public synchronized void send(SocketPackage socketPackage) {
this.sendLine(socketPackage.toString()); this.sendLine(socketPackage.toString());
} }
public void send(String packageName) { public synchronized void send(String packageName) {
this.send(packageName, ""); this.send(packageName, "");
} }
public void send(String packageName, String packageContent) { public synchronized void send(String packageName, String packageContent) {
if (packageContent.length() > 0) { if (packageContent.length() > 0) {
packageContent = " " + packageContent; packageContent = " " + packageContent;
} }
this.sendLine(packageName + packageContent); this.sendLine(packageName + packageContent);
} }
public void sendLine(String message) { public synchronized void sendLine(String message) {
this.out.print(message + "\r\n"); sendBuffer = sendBuffer + message + "\r\n";
this.flushBuffer();
}
private synchronized void flushBuffer() {
if (!this.sendBuffer.isEmpty() && this.out != null) {
try {
this.out.write(sendBuffer);
System.out.println("SENT - " + sendBuffer);
sendBuffer = "";
this.out.flush();
} catch (IOException e) {
e.printStackTrace();
// TODO: handle writing error
}
}
} }
public void close() { public void close() {
@ -73,8 +164,11 @@ public class AsyncSocket {
try { try {
this.socket.close(); this.socket.close();
this.checkerThread.join();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} }
} }
} }

View File

@ -1,4 +1,5 @@
import java.util.ArrayList;
import java.util.List; import java.util.List;
public class Board { public class Board {
@ -10,6 +11,8 @@ public class Board {
public Board(int size) { public Board(int size) {
this.size = size; this.size = size;
this.ships = new ArrayList<>();
this.hits = new ArrayList<>();
this.createShip(size - 13); this.createShip(size - 13);
} }

View File

@ -22,6 +22,7 @@ public class BoardDisplay extends JPanel {
public BoardDisplay(int gridSize, Player player) { public BoardDisplay(int gridSize, Player player) {
super(new GridLayout(gridSize + 1, gridSize + 1)); // +1 wegen extra Zeile/Splate super(new GridLayout(gridSize + 1, gridSize + 1)); // +1 wegen extra Zeile/Splate
this.fields = new JButton[gridSize][gridSize]; this.fields = new JButton[gridSize][gridSize];
this.ships = new ArrayList<>();
// Erstellung von Spielfeld // Erstellung von Spielfeld
for (int i = 0; i <= gridSize; i++) { for (int i = 0; i <= gridSize; i++) {
for (int j = 0; j <= gridSize; j++) { for (int j = 0; j <= gridSize; j++) {
@ -66,6 +67,7 @@ public class BoardDisplay extends JPanel {
@Override @Override
public void mouseClicked(MouseEvent e) { public void mouseClicked(MouseEvent e) {
Point o= new Point(finalI, finalJ); Point o= new Point(finalI, finalJ);
System.out.println(o);
handleFieldClick(field, o,player); handleFieldClick(field, o,player);
} }
}); });
@ -100,6 +102,16 @@ public class BoardDisplay extends JPanel {
} }
} }
/*private boolean placeable(Ship ship,Point o, boolean horizontal) {
if (horizontal && (o.getX() + ship.getSize() > gridSize)) { // Fehler
return false;
}
if (!horizontal && (o.getY() + ship.getSize() > gridSize)) {
return false;
}
return true;
}*/
/** /**
* TODO Funktion beschreiben etc. * TODO Funktion beschreiben etc.
* @param ship * @param ship
@ -107,16 +119,29 @@ public class BoardDisplay extends JPanel {
* @param horizontal * @param horizontal
* @return * @return
*/ */
private boolean placeable(Ship ship,Point o, boolean horizontal) { private boolean placeable(Ship ship, Point o, boolean horizontal) {
if (horizontal && (o.getX() + ship.getSize() > gridSize)) { if (horizontal && (o.getX() + ship.getSize() > gridSize)) {
return false; return false;
} }
if (!horizontal && (o.getY() + ship.getSize() > gridSize)) { if (!horizontal && (o.getY() + ship.getSize() > gridSize)) {
return false; return false;
} }
// Prüfen auf Kollision mit bestehenden Schiffen
for (Ship other : ships) {
for (Point p : other.getOccupiedPoints()) {
for (Point newP : ship.getOccupiedPoints()) {
if (p.equals(newP)) {
return false; // Überschneidung gefunden
}
}
}
}
return true; return true;
} }
private void selectShip(MouseEvent e) { private void selectShip(MouseEvent e) {
Ship current = (Ship) e.getSource(); Ship current = (Ship) e.getSource();
} }

View File

@ -1,4 +1,4 @@
//import javafx.scene.control.ToggleGroup; // import javafx.scene.control.ToggleGroup;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;

View File

@ -1,8 +1,5 @@
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -25,6 +22,9 @@ public class GameController {
public static int semesterToBoardSize(int semester) { public static int semesterToBoardSize(int semester) {
return semester + 13; return semester + 13;
} }
public static int boardSizeToSemester(int size) {
return size - 13;
}
public static HashMap<String, Class<? extends OnlinePlayer>> supportedVersions = new HashMap<>(Map.of( public static HashMap<String, Class<? extends OnlinePlayer>> supportedVersions = new HashMap<>(Map.of(
"1.1.0", OnlinePlayer_1_1_0.class "1.1.0", OnlinePlayer_1_1_0.class
@ -33,34 +33,15 @@ public class GameController {
public static void startOnlineGame(Class<? extends LocalPlayer> localPlayerClass, String localPlayerName, InetSocketAddress address, int size) throws IOException { public static void startOnlineGame(Class<? extends LocalPlayer> localPlayerClass, String localPlayerName, InetSocketAddress address, int size) throws IOException {
AsyncSocket clientSocket; AsyncSocket clientSocket;
boolean localPlayerIsServer = address.getHostName() == null; boolean localPlayerIsServer = address.getHostName() == null || address.getHostName().isEmpty() || address.getHostName().equals("0.0.0.0");
if (localPlayerIsServer) { if (localPlayerIsServer) {
// SERVER MODE // SERVER MODE
clientSocket = new AsyncSocket(address.getPort(), null);
ServerSocket serverSocket = new ServerSocket(address.getPort());
System.out.println("Waiting for client connection...");
clientSocket = new AsyncSocket(serverSocket.accept(), null);
serverSocket.close();
} else { } else {
// CLIENT MODE // CLIENT MODE
clientSocket = new AsyncSocket(address, null);
Socket socket = new Socket();
try {
socket.connect(address, CONNECTION_TIMEOUT);
clientSocket = new AsyncSocket(socket, null);
} catch (SocketTimeoutException e) {
e.printStackTrace();
throw new RuntimeException("Connection timed out");
} finally {
socket.close();
}
} }
clientSocket.send("VERSION", "Gruppe03 " + String.join(" ", supportedVersions.keySet())); clientSocket.send("VERSION", "Gruppe03 " + String.join(" ", supportedVersions.keySet()));
@ -84,7 +65,7 @@ public class GameController {
OnlinePlayer onlinePlayer; OnlinePlayer onlinePlayer;
try { try {
localPlayer = localPlayerClass.getDeclaredConstructor().newInstance(); localPlayer = localPlayerClass.getDeclaredConstructor().newInstance();
onlinePlayer = onlinePlayerClass.getDeclaredConstructor().newInstance((Integer)size, clientSocket); onlinePlayer = onlinePlayerClass.getDeclaredConstructor(Integer.class, AsyncSocket.class).newInstance((Integer)size, clientSocket);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
throw new RuntimeException("Unable to instantiate players"); throw new RuntimeException("Unable to instantiate players");
@ -93,7 +74,7 @@ public class GameController {
localPlayer.isServer = localPlayerIsServer; localPlayer.isServer = localPlayerIsServer;
onlinePlayer.isServer = !localPlayerIsServer; onlinePlayer.isServer = !localPlayerIsServer;
startGameWithInstancedPlayers(localPlayer, onlinePlayer); startGameWithInstancedPlayers(localPlayer, onlinePlayer, size);
} else { } else {
throw new RuntimeException("Unexpected Package received before game initialisation"); throw new RuntimeException("Unexpected Package received before game initialisation");
@ -178,13 +159,15 @@ public class GameController {
localPlayer.createBoard(size); localPlayer.createBoard(size);
aiPlayer.createBoard(size); aiPlayer.createBoard(size);
startGameWithInstancedPlayers(localPlayer, aiPlayer); startGameWithInstancedPlayers(localPlayer, aiPlayer, size);
} }
private static void startGameWithInstancedPlayers(LocalPlayer p1, Player p2) { private static void startGameWithInstancedPlayers(LocalPlayer p1, Player p2, int boardSize) {
p1.setEnemy(p2); p1.setEnemy(p2);
p2.setEnemy(p1); p2.setEnemy(p1);
mainFrame.showPanelSLG("GameBoard", boardSizeToSemester(boardSize), p1, p2);
// TODO: frontend configuration // TODO: frontend configuration
} }

View File

@ -25,6 +25,9 @@ public class MainFrame extends JFrame {
* Ermöglicht es Panel anzuzeigen. * Ermöglicht es Panel anzuzeigen.
*/ */
public MainFrame() { public MainFrame() {
GameController.setMainFrame(this);
setTitle("Studium Versenken"); setTitle("Studium Versenken");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(1500, 1000); setSize(1500, 1000);

View File

@ -4,7 +4,7 @@ public abstract class OnlinePlayer extends Player implements AsyncSocketListener
protected boolean hasReceivedCoinPackage; protected boolean hasReceivedCoinPackage;
public OnlinePlayer(int size, AsyncSocket socket) { public OnlinePlayer(Integer size, AsyncSocket socket) {
this.socket = socket; this.socket = socket;
this.wantedBoardSize = size; this.wantedBoardSize = size;
socket.setHandler(this); socket.setHandler(this);

View File

@ -1,7 +1,7 @@
import java.util.List; import java.util.List;
public class OnlinePlayer_1_1_0 extends OnlinePlayer { public class OnlinePlayer_1_1_0 extends OnlinePlayer {
public OnlinePlayer_1_1_0(int size, AsyncSocket socket) { public OnlinePlayer_1_1_0(Integer size, AsyncSocket socket) {
super(size, socket); super(size, socket);
} }

View File

@ -28,7 +28,7 @@ public class SoundHandler {
} }
} }
}).start(); }).start();
// TODO: kill zombies
} }
} }