Network and Frontend #10
|
@ -8,14 +8,14 @@ public abstract class AiPlayer extends Player {
|
||||||
}
|
}
|
||||||
public Point RandomPoint() {
|
public Point RandomPoint() {
|
||||||
Random random = new Random(); // Pseudo Random für zufallszahlen
|
Random random = new Random(); // Pseudo Random für zufallszahlen
|
||||||
int posx = random.nextInt(super.board.size); // Generiert 0 - 13
|
int posx = random.nextInt(super.board.getSize()); // Generiert 0 - 13
|
||||||
int posy = random.nextInt(super.board.size); //
|
int posy = random.nextInt(super.board.getSize()); //
|
||||||
return new Point(posx,posy);
|
return new Point(posx,posy);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AiSetShips() {
|
public void AiSetShips() {
|
||||||
for(int i = 0; i < super.board.ships.size(); i++) { // Interiert durch alle Shiffe
|
for(int i = 0; i < super.board.getShips().size(); i++) { // Interiert durch alle Shiffe
|
||||||
while(!super.board.ships.get(i).setPosition(RandomPoint()))
|
while(!super.board.getShips().get(i).setPosition(RandomPoint(), super.board.getShips(), super.board.getSize())) {}
|
||||||
} // Versucht das Aktuelle Shiff zu setzten und wiederholt solange bis es funktioniert
|
} // Versucht das Aktuelle Shiff zu setzten und wiederholt solange bis es funktioniert
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
public class AsyncSocket {
|
||||||
|
private Socket socket;
|
||||||
|
private Thread checkerThread;
|
||||||
|
private AsyncSocketListener handler;
|
||||||
|
private boolean shouldStop = false;
|
||||||
|
|
||||||
|
private BufferedReader in;
|
||||||
|
private PrintWriter out;
|
||||||
|
|
||||||
|
public AsyncSocket(Socket socket, AsyncSocketListener handler) throws IOException {
|
||||||
|
this.socket = socket;
|
||||||
|
|
||||||
|
this.in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
|
||||||
|
this.out = new PrintWriter(new OutputStreamWriter(this.socket.getOutputStream()));
|
||||||
|
|
||||||
|
this.handler = handler;
|
||||||
|
|
||||||
|
this.checkerThread = new Thread(() -> {
|
||||||
|
while (!this.shouldStop) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (!this.in.ready()) continue;
|
||||||
|
if (this.handler == null) continue;
|
||||||
|
|
||||||
|
String message = this.in.readLine();
|
||||||
|
if (message.length() <= 0) continue;
|
||||||
|
|
||||||
|
// TODO: remove \r\n
|
||||||
|
this.handler.receive(message);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.checkerThread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHandler(AsyncSocketListener handler) {
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void send(SocketPackage socketPackage) {
|
||||||
|
this.sendLine(socketPackage.toString());
|
||||||
|
}
|
||||||
|
public void send(String packageName) {
|
||||||
|
this.send(packageName, "");
|
||||||
|
}
|
||||||
|
public void send(String packageName, String packageContent) {
|
||||||
|
if (packageContent.length() > 0) {
|
||||||
|
packageContent = " " + packageContent;
|
||||||
|
}
|
||||||
|
this.sendLine(packageName + packageContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendLine(String message) {
|
||||||
|
this.out.print(message + "\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
this.shouldStop = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.socket.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
public interface AsyncSocketListener {
|
||||||
|
public void receive(String message);
|
||||||
|
}
|
|
@ -68,7 +68,7 @@ public class Board {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSize() {
|
public int getSize() {
|
||||||
return size;
|
return this.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,59 @@
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class GameController {
|
public class GameController {
|
||||||
|
|
||||||
|
public HashMap<String, Class<? extends OnlinePlayer>> supportedVersions = new HashMap<>(Map.of(
|
||||||
|
"1.1.0", OnlinePlayer_1_1_0.class
|
||||||
|
));
|
||||||
|
|
||||||
public void startOnlineGame() {
|
public void startOnlineGame(Class<? extends LocalPlayer> localPlayerClass, InetSocketAddress address) throws IOException {
|
||||||
// fuck you Luca and Ole von Florian und nicht von Florian
|
AsyncSocket clientSocket;
|
||||||
}
|
if (address.getHostName() == null) {
|
||||||
|
// SERVER MODE
|
||||||
|
ServerSocket serverSocket = new ServerSocket(address.getPort());
|
||||||
|
|
||||||
public void startLocalGame(Class<? extends LocalPlayer> localPlayerClass, Class<? extends AiPlayer> enemyClass, int size) throws InstantiationException, IllegalAccessException {
|
System.out.println("Waiting for client connection...");
|
||||||
|
|
||||||
|
clientSocket = new AsyncSocket(serverSocket.accept(), null);
|
||||||
|
|
||||||
LocalPlayer localPlayer = localPlayerClass.newInstance();
|
serverSocket.close();
|
||||||
AiPlayer aiPlayer = enemyClass.newInstance();
|
} else {
|
||||||
|
Socket socket = new Socket();
|
||||||
|
socket.connect(address);
|
||||||
|
|
||||||
|
clientSocket = new AsyncSocket(socket, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
clientSocket.send("VERSION", "Gruppe03 " + String.join(" ", supportedVersions.keySet()));
|
||||||
|
clientSocket.setHandler((message) -> {
|
||||||
|
|
||||||
|
SocketPackage socketPackage = new SocketPackage(message);
|
||||||
|
if (socketPackage.getName().equals("VERSION")) {
|
||||||
|
// TODO: check version matches - instantiate online player
|
||||||
|
} else {
|
||||||
|
// TODO: received invalid package / package out of order
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// TODO: instantiate local player, set server / client roles
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startLocalGame(Class<? extends LocalPlayer> localPlayerClass, Class<? extends AiPlayer> enemyClass, int size) {
|
||||||
|
|
||||||
|
LocalPlayer localPlayer;
|
||||||
|
AiPlayer aiPlayer;
|
||||||
|
try {
|
||||||
|
localPlayer = localPlayerClass.getDeclaredConstructor().newInstance();
|
||||||
|
aiPlayer = enemyClass.getDeclaredConstructor().newInstance();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
localPlayer.setEnemy(aiPlayer);
|
localPlayer.setEnemy(aiPlayer);
|
||||||
aiPlayer.setEnemy(localPlayer);
|
aiPlayer.setEnemy(localPlayer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
import java.net.Socket;
|
public abstract class OnlinePlayer extends Player implements AsyncSocketListener{
|
||||||
|
private AsyncSocket socket;
|
||||||
|
|
||||||
|
public OnlinePlayer(int size, AsyncSocket socket) {
|
||||||
|
super(size);
|
||||||
|
this.socket = socket;
|
||||||
|
//TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void receive(String message);
|
||||||
|
|
||||||
public abstract class OnlinePlayer extends Player{
|
|
||||||
private Socket socket;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
public class OnlinePlayer_1_1_0 extends OnlinePlayer {
|
||||||
|
public OnlinePlayer_1_1_0(int size, AsyncSocket socket) {
|
||||||
|
super(size, socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void receive(String message) {
|
||||||
|
SocketPackage p = new SocketPackage(message);
|
||||||
|
|
||||||
|
// TODO: parse package
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,10 +1,11 @@
|
||||||
|
|
||||||
|
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
record ShipData (int size, String name){
|
record ShipData (int size, String name){}
|
||||||
}
|
|
||||||
|
|
||||||
public class Ship {
|
public class Ship {
|
||||||
static List<List<ShipData>> semeterList = Arrays.asList(Arrays.asList(
|
static List<List<ShipData>> semeterList = Arrays.asList(Arrays.asList(
|
||||||
|
@ -56,16 +57,79 @@ public class Ship {
|
||||||
public Ship (int size, String name) {
|
public Ship (int size, String name) {
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.horizontal = false;
|
this.horizontal = false; //true = von Punkt aus nach rechts; false = von Punkt aus nach unten
|
||||||
this.position = null;
|
this.position = null;
|
||||||
this.hitsOnMe = 0;
|
this.hitsOnMe = 0;
|
||||||
this.sunk = false;
|
this.sunk = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setPosition(Point pos) {
|
public boolean setPosition(Point pos, List<Ship> shipsList, int boardSize) {
|
||||||
//TODO Conte abrfrage ob shif da sein darf
|
// ueberpruefe boundaries
|
||||||
this.position = pos;
|
if (pos.x < 0 || pos.y < 0 || pos.x >= boardSize || pos.y >= boardSize) {
|
||||||
return true;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bestimme die Endposition anhand der Ausrichtung
|
||||||
|
int endX = pos.x;
|
||||||
|
int endY = pos.y;
|
||||||
|
|
||||||
|
if (this.horizontal) { // rechts links
|
||||||
|
endX = pos.x + this.size - 1;
|
||||||
|
if (endX >= boardSize) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else { // oben unten
|
||||||
|
endY = pos.y + this.size - 1;
|
||||||
|
if (endY >= boardSize) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Liste an Punkten die das Schiff einnehmen wuerde
|
||||||
|
List<Point> shipPoints = new ArrayList<>();
|
||||||
|
for (int i = 0; i < this.size; i++) {
|
||||||
|
int x = this.horizontal ? pos.x + i : pos.x; //falls horizontal dann pos.x + i ansonsten pos.x
|
||||||
|
int y = this.horizontal ? pos.y : pos.y + i;
|
||||||
|
shipPoints.add(new Point(x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ueberlappen mit anderen Schiffen pruefen
|
||||||
|
for (Ship otherShip : shipsList) {
|
||||||
|
// eigenes Schiff ueberspringen
|
||||||
|
if (otherShip == this) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// ueberspringe falls noch nicht gesetzt
|
||||||
|
if (otherShip.position == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Punkte die das andere Schiff besetzt
|
||||||
|
List<Point> otherShipPoints = otherShip.getOccupiedPoints();
|
||||||
|
// ueberlappen checken
|
||||||
|
for (Point p : shipPoints) {
|
||||||
|
if (otherShipPoints.contains(p)) {
|
||||||
|
// ueberlappen entdeckt
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// kein ueberlappen also setze das Schiff
|
||||||
|
this.position = pos;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Point> getOccupiedPoints() {
|
||||||
|
List<Point> points = new ArrayList<>();
|
||||||
|
if (this.position == null) {
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < this.size; i++) {
|
||||||
|
int x = this.horizontal ? this.position.x + i : this.position.x;
|
||||||
|
int y = this.horizontal ? this.position.y : this.position.y + i;
|
||||||
|
points.add(new Point(x, y));
|
||||||
|
}
|
||||||
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Point getPosition() {
|
public Point getPosition() {
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
public class SocketPackage {
|
||||||
|
|
||||||
|
private String name = "";
|
||||||
|
private String data = "";
|
||||||
|
|
||||||
|
public SocketPackage(String name, String data) {
|
||||||
|
this.setName(name);
|
||||||
|
this.setData(data);
|
||||||
|
}
|
||||||
|
public SocketPackage() {
|
||||||
|
this("","");
|
||||||
|
}
|
||||||
|
public SocketPackage(String message) {
|
||||||
|
if (message.length() <= 0) {
|
||||||
|
throw new IllegalArgumentException("Socket message cannot be empty.");
|
||||||
|
}
|
||||||
|
String[] components = message.split(" ");
|
||||||
|
this.setName(components[0]);
|
||||||
|
if (components.length > 1) {
|
||||||
|
this.setData(message.substring(components[0].length() + 1));
|
||||||
|
} else {
|
||||||
|
this.setData("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
if (name == null) name = "";
|
||||||
|
this.name = name.toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(String data) {
|
||||||
|
if (data == null) data = "";
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getData() {
|
||||||
|
return this.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
if (this.data == null || this.data.length() == 0) {
|
||||||
|
return this.name;
|
||||||
|
} else {
|
||||||
|
return this.name + " " + this.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> splitData() {
|
||||||
|
return Arrays.asList(this.data.split(" "));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
public class SpecificAiPlayer1 extends AiPlayer{
|
public class SpecificAiPlayerEasy extends AiPlayer{
|
||||||
|
|
||||||
public SpecificAiPlayer1(int size) {
|
public SpecificAiPlayerEasy(int size) {
|
||||||
super(size);
|
super(size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
public class SpecificAiPlayer1 extends AiPlayer{
|
public class SpecificAiPlayerHard extends AiPlayer{
|
||||||
|
|
||||||
public SpecificAiPlayer1(int size) {
|
public SpecificAiPlayerHard(int size) {
|
||||||
super(size);
|
super(size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.awt.Point;
|
||||||
|
|
||||||
public class SpecificAiPlayerMedium extends AiPlayer{
|
public class SpecificAiPlayerMedium extends AiPlayer{
|
||||||
|
|
||||||
|
@ -13,7 +16,7 @@ public class SpecificAiPlayerMedium extends AiPlayer{
|
||||||
// Shoot at the enemy and receive the hit response
|
// Shoot at the enemy and receive the hit response
|
||||||
enemy.receiveShoot(nextShot);
|
enemy.receiveShoot(nextShot);
|
||||||
|
|
||||||
HitResponse hitResponse = enemy.board.getHitResponsOnPoint(nextShot)
|
HitResponse hitResponse = enemy.board.getHitResponsOnPoint(nextShot);
|
||||||
// If it's a hit or sunk, add adjacent cells to the hitsQueue
|
// If it's a hit or sunk, add adjacent cells to the hitsQueue
|
||||||
if (hitResponse.getHitResponse() == HitResponseType.HIT) {
|
if (hitResponse.getHitResponse() == HitResponseType.HIT) {
|
||||||
addAdjacentPoints(nextShot);
|
addAdjacentPoints(nextShot);
|
||||||
|
@ -58,6 +61,11 @@ public class SpecificAiPlayerMedium extends AiPlayer{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean alreadyShot(Point p) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'alreadyShot'");
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isValidPoint(Point point) {
|
private boolean isValidPoint(Point point) {
|
||||||
return point.x >= 0 && point.x < board.getSize() &&
|
return point.x >= 0 && point.x < board.getSize() &&
|
||||||
point.y >= 0 && point.y < board.getSize();
|
point.y >= 0 && point.y < board.getSize();
|
||||||
|
|
Loading…
Reference in New Issue