Compare commits

..

53 Commits

Author SHA1 Message Date
Luca Conte 3c7d68109a Merge pull request 'fix ready' (#31) from game-end-stuff into main
Reviewed-on: #31
2024-12-23 22:22:00 +00:00
Luca Conte eaa5b64956 fix ready 2024-12-23 23:21:48 +01:00
Luca Conte 5b3ecb52bb Merge pull request 'add rotate instruction' (#30) from game-end-stuff into main
Reviewed-on: #30
2024-12-23 22:15:19 +00:00
Luca Conte 9ea176cc6d add rotate instruction 2024-12-23 23:15:04 +01:00
Luca Conte 7a706e1b73 Merge pull request 'game-end-stuff' (#29) from game-end-stuff into main
Reviewed-on: #29
2024-12-23 22:13:57 +00:00
Luca Conte 175241395e add docs to makefile 2024-12-23 23:13:11 +01:00
Luca Conte 1b08b39105 don't repaint fields after game end 2024-12-23 23:12:43 +01:00
Luca Conte 8dd697bb66 proper game closing 2024-12-23 23:04:16 +01:00
Luca Conte 30360c7bd4 Merge pull request 'kommentar-check' (#28) from kommentar-check into main
Reviewed-on: #28
2024-12-23 20:37:06 +00:00
Luca Conte 6f98a82a90 KOOMMMEEENTTAAAREEEEEEEE 2024-12-23 21:36:19 +01:00
Luca Conte a4cb3f68d5 Merge branch 'FH_Last_changes' into kommentar-check 2024-12-23 20:51:53 +01:00
eyFlorian 424dd2544e FUCK ME 2024-12-23 20:50:46 +01:00
Luca Conte 27157fb0a3 Merge pull request 'Add komentare' (#27) from ole into main
Reviewed-on: #27
2024-12-23 19:49:01 +00:00
Luca Conte 0fef0069f8 wtf 2024-12-23 20:48:51 +01:00
Luca Conte 5839b13980 Merge branch 'main' into ole 2024-12-23 20:47:40 +01:00
Luca Conte 0f42a66e4a Merge pull request 'lucasjoshua' (#26) from lucasjoshua into main
Reviewed-on: #26
2024-12-23 19:46:03 +00:00
Luca Conte c14f7d5bfe Merge branch 'main' into lucasjoshua 2024-12-23 20:44:31 +01:00
Luca Conte f13e0ab2ba Merge pull request 'Kommentare und Withdraw' (#24) from FH_Last_changes into main
Reviewed-on: #24
2024-12-23 19:39:53 +00:00
Luca Conte e85f151b33 a bit cleaner withdraw 2024-12-23 20:28:06 +01:00
Luca Conte 7fb19bfeac Merge branch 'main' into FH_Last_changes 2024-12-23 20:17:51 +01:00
Luca Conte 9ed0dc1e9e Merge pull request 'wip-fix-ai-players' (#25) from wip-fix-ai-players into main
Reviewed-on: #25
2024-12-23 19:14:59 +00:00
Luca Conte 9d51e708e5 remove game board on win or lose 2024-12-23 20:13:52 +01:00
Luca Conte 44f04a454f proper thread killing and online player myTurn handling 2024-12-23 20:02:11 +01:00
Joshua 678ed9d81e Got rid of some todos 2024-12-23 19:28:02 +01:00
Luca Conte be6b50739f Merge branch 'lucasjoshua' into wip-fix-ai-players 2024-12-23 19:05:24 +01:00
Joshua 458aa46638 Merge remote-tracking branch 'origin/lucasjoshua' into lucasjoshua 2024-12-23 18:51:02 +01:00
Joshua be46f3587e Fixed semesterCounter for onlineGame. 2024-12-23 18:50:39 +01:00
Kaver 9c6d629357 fix Board halb 2024-12-23 18:41:10 +01:00
ole 70749c2c62 add Komentare 2024-12-23 18:36:15 +01:00
Joshua 3ad7233383 JoinGame now calls GameController.startOnlineGame(...) correctly. 2024-12-23 18:35:22 +01:00
Joshua 529178f4db Updated backButton.png. 2024-12-23 18:08:40 +01:00
eyFlorian 4045d3ce7b Kommentare und Withdraw 2024-12-23 15:28:33 +01:00
Luca Conte d97826db6c Merge pull request 'die letzten javadoc kommentare' (#23) from cleanup-work into main
Reviewed-on: #23
2024-12-22 23:29:12 +00:00
Luca Conte 2cce52b827 die letzten javadoc kommentare 2024-12-23 00:28:55 +01:00
Luca Conte f73114eaeb Merge pull request 'cleanup-work' (#22) from cleanup-work into main
Reviewed-on: #22
2024-12-22 23:06:00 +00:00
Luca Conte 931a757a67 Merge branch 'main' into cleanup-work 2024-12-23 00:05:49 +01:00
Luca Conte 8b4b017e85 MORE javadoc 2024-12-23 00:03:54 +01:00
Luca Conte 6909b9417f FINALLY FIX THE INDENTATION REEEE 2024-12-23 00:03:46 +01:00
flo 29d4118d8f Merge pull request 'AiPlayer Kommentare hinzugefügt' (#21) from FH_Fixes into main
Reviewed-on: #21
Reviewed-by: lgc <main@lugico.de>
2024-12-22 22:36:39 +00:00
Kaver 0cea473146 smol jdoc changes 2024-12-22 23:17:52 +01:00
Kaver 1e58626e6f jdoc 2024-12-22 00:02:03 +01:00
Joshua 8933a40d53 Changed the color of ships to white, as to make AI ships invisible. 2024-12-21 16:54:08 +01:00
Joshua cb9b110621 Added and integrated new sounds.
Added standardPort to be default value of port field.
2024-12-21 16:26:10 +01:00
Kaver 4dd1c9b39b Code aufräumen und kleine Anpassungen/Korrekturen vorgenommen 2024-12-20 19:39:56 +01:00
Luca Conte a3827d6bd0 add metric shit ton of javadoc comments 2024-12-20 18:29:49 +01:00
Luca Conte b7215db6d9 destroy players on game end 2024-12-20 17:57:50 +01:00
Luca Conte 7f610b4a90 Merge branch 'ole' into cleanup-work 2024-12-20 17:56:41 +01:00
Luca Conte 65451d6912 destroy for AI Player 2024-12-20 17:55:38 +01:00
ole bfb25dfe2c disable testButton 2024-12-20 17:32:53 +01:00
ole 3370975e57 change parameta from showPanelWin and loos to check the request 2024-12-20 17:31:32 +01:00
Luca Conte 20732e730c some cleanup 2024-12-20 17:31:16 +01:00
ole f4cf28f4bf add endScreen machanic 2024-12-20 17:30:21 +01:00
ole 7ef04711c3 add getter for Player 1 2024-12-20 17:29:37 +01:00
38 changed files with 1147 additions and 312 deletions

Binary file not shown.

BIN
Sound/loosescreenlaugh.mp3 Normal file

Binary file not shown.

BIN
Sound/win.mp3 Normal file

Binary file not shown.

BIN
Sound/yourturn.mp3 Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 396 B

View File

@ -29,6 +29,9 @@ test-jar: jar
# $(JR) -cp "$(OUT_DIR)/:$(LIB_DIR)/*" $(MAIN_CLASS) # $(JR) -cp "$(OUT_DIR)/:$(LIB_DIR)/*" $(MAIN_CLASS)
$(JR) -jar $(OUT_DIR)/$(JAR_NAME) $(JR) -jar $(OUT_DIR)/$(JAR_NAME)
docs:
javadoc -cp "$(LIB_DIR)/*" -d "docs" $(SRC_DIR)/*.java
test: classfiles test: classfiles
$(JR) -cp "$(OUT_DIR)$(SEPERATOR)$(LIB_DIR)/*" $(MAIN_CLASS) $(JR) -cp "$(OUT_DIR)$(SEPERATOR)$(LIB_DIR)/*" $(MAIN_CLASS)

View File

@ -1,14 +1,12 @@
/**
* Die Klasse AiPlayer ist die Basis für alle Ki Spieler und jede Spezifische Ki erweitert diese Klasse.
* @author Florian und Florian
* */
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
/**
* Die Klasse AiPlayer ist die Basis für alle Ki Spieler und jede Spezifische Ki erweitert diese Klasse.
* @author Florian Alexy und Florian Hantzschel
* */
public abstract class AiPlayer extends LocalPlayer implements Runnable { public abstract class AiPlayer extends LocalPlayer implements Runnable {
/** /**
@ -18,6 +16,7 @@ public abstract class AiPlayer extends LocalPlayer implements Runnable {
/** /**
* Konstruktor * Konstruktor
* @author Florian Alexy und Florian Hantzschel
*/ */
public AiPlayer() { public AiPlayer() {
this.setName("AI Player"); this.setName("AI Player");
@ -27,6 +26,7 @@ public abstract class AiPlayer extends LocalPlayer implements Runnable {
/** /**
* Gibt einen zufälligen Punkt im Spielfeld zurück. * Gibt einen zufälligen Punkt im Spielfeld zurück.
* @return Ein zufälliger Punkt * @return Ein zufälliger Punkt
* @author Florian Alexy und Florian Hantzschel
*/ */
public Point RandomPoint() { public Point RandomPoint() {
Random random = new Random(); // Pseudo Random für zufallszahlen Random random = new Random(); // Pseudo Random für zufallszahlen
@ -38,6 +38,7 @@ public abstract class AiPlayer extends LocalPlayer implements Runnable {
/** /**
* Initialisiert das Board. * Initialisiert das Board.
* @param size größe des Boards * @param size größe des Boards
* @author Florian Alexy und Florian Hantzschel
*/ */
@Override @Override
public void createBoard(int size) { public void createBoard(int size) {
@ -48,6 +49,7 @@ public abstract class AiPlayer extends LocalPlayer implements Runnable {
/** /**
* Ki Methode zum zufälligen Setzten der Schiffe * Ki Methode zum zufälligen Setzten der Schiffe
* @author Florian Alexy und Florian Hantzschel
*/ */
public void aiSetShips() { public void aiSetShips() {
for(int i = 0; i < super.board.getShips().size(); i++) { // Interiert durch alle Shiffe for(int i = 0; i < super.board.getShips().size(); i++) { // Interiert durch alle Shiffe
@ -58,13 +60,20 @@ public abstract class AiPlayer extends LocalPlayer implements Runnable {
} }
/** /**
* Ki Methode zum zufälligen Schießen auf das gegnerische Board. * Ki Methode zum zufälligen Schießen auf das gegnerische Board.
* @author Florian Alexy und Florian Hantzschel
*/ */
public void aiShoot() { public void aiShoot() {
if (!this.myTurn) return;
this.enemy.receiveShoot(RandomPoint()); this.enemy.receiveShoot(RandomPoint());
return; return;
} }
/**
* Nachdem receiveShoot beim gegner den schuss verarbeitet hat,
* wird diese Methode mit der antwort aufgerufen.
* @param hitResponse the hitresponse
* @author Florian Alexy und Florian Hantzschel und Luca Conte
*/
@Override @Override
public synchronized void receiveHit(HitResponse hitResponse) { public synchronized void receiveHit(HitResponse hitResponse) {
// Eltern-Klasse LocalPlayer updatet myTurn // Eltern-Klasse LocalPlayer updatet myTurn
@ -78,6 +87,11 @@ public abstract class AiPlayer extends LocalPlayer implements Runnable {
} }
/**
* Erhält einen schuss vom gegner und verarbeitet ihn.
* @param point the location to be shot
* @author Florian Alexy und Florian Hantzschel und Luca Conte
*/
@Override @Override
public synchronized void receiveShoot(Point point) { public synchronized void receiveShoot(Point point) {
super.receiveShoot(point); super.receiveShoot(point);
@ -91,6 +105,7 @@ public abstract class AiPlayer extends LocalPlayer implements Runnable {
/** /**
* Wird aufgerufen, wenn in determineCoinToss festgestellt wurde das die Ki anfängt. * Wird aufgerufen, wenn in determineCoinToss festgestellt wurde das die Ki anfängt.
* Erster Schuss wird gestartet. * Erster Schuss wird gestartet.
* @author Florian Alexy und Florian Hantzschel und Luca Conte
*/ */
@Override @Override
public void beginTurn() { public void beginTurn() {
@ -100,8 +115,8 @@ public abstract class AiPlayer extends LocalPlayer implements Runnable {
} }
/** /**
* Die Methode wird immer aufgerufen, wenn ein Schuss abgefeuert werden soll. * Closes past threads and tries firing a shot.
* Es wird erst ein Schuss abgefeuert, wenn der vorherige schuss abgeschlossen wurde. * @author Luca Conte, Florian Alexy und Florian Hantzschel
*/ */
public void run() { public void run() {
Iterator<Thread> i = this.shootThreads.iterator(); Iterator<Thread> i = this.shootThreads.iterator();
@ -128,4 +143,25 @@ public abstract class AiPlayer extends LocalPlayer implements Runnable {
this.aiShoot(); this.aiShoot();
} }
/**
* Closes all running threads and does some cleanup work so the garbage collector will delete the player
* @author Luca Conte
*/
@Override
public void destroy() {
super.destroy();
Iterator<Thread> i = this.shootThreads.iterator();
while(i.hasNext()) {
Thread thread = i.next();
try {
thread.interrupt();
thread.join();
i.remove();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} }

View File

@ -7,6 +7,10 @@ import java.net.InetSocketAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
/**
* Provides an Interface to communicate using a socket asynchronously
* @author Luca Conte, Peer Ole Wachtel
*/
public class AsyncSocket { public class AsyncSocket {
private Socket socket; private Socket socket;
private Thread checkerThread; private Thread checkerThread;
@ -19,6 +23,12 @@ public class AsyncSocket {
private BufferedReader in; private BufferedReader in;
private BufferedWriter out; private BufferedWriter out;
/**
* Creates a socket server and turns the first incoming connection into an AsyncSocket
* @param port the port to listen on for a connection
* @param handler the handler that will be called when a message is received
* @author Luca Conte
*/
public AsyncSocket(int port, AsyncSocketListener handler) { public AsyncSocket(int port, AsyncSocketListener handler) {
this.setHandler(handler); this.setHandler(handler);
@ -45,6 +55,12 @@ public class AsyncSocket {
this.connectorThread.start(); this.connectorThread.start();
} }
/**
* Connects to the address provided and turns the resulting socket into an AsyncSocket
* @param address the socket address to connect to
* @param handler the handler that will be called when a message is received
* @author Luca Conte
*/
public AsyncSocket(InetSocketAddress address, AsyncSocketListener handler) { public AsyncSocket(InetSocketAddress address, AsyncSocketListener handler) {
this.setHandler(handler); this.setHandler(handler);
@ -68,11 +84,22 @@ public class AsyncSocket {
this.connectorThread.start(); this.connectorThread.start();
} }
/**
* @param socket the socket to be wrapped in an AsyncSocket
* @param handler the handler that will be called when a message is received
* @author Luca Conte
*/
public AsyncSocket(Socket socket, AsyncSocketListener handler) throws IOException { public AsyncSocket(Socket socket, AsyncSocketListener handler) throws IOException {
this.setHandler(handler); this.setHandler(handler);
this.initSocket(socket); this.initSocket(socket);
} }
/**
* creates input and ouput writer / readers as well as a checker thread to repeatedly check
* for incoming messages
* @param socket the socket to be wrapped
* @author Luca Conte
*/
private void initSocket(Socket socket) throws IOException { private void initSocket(Socket socket) throws IOException {
System.out.println("Initialising sockets"); System.out.println("Initialising sockets");
this.socket = socket; this.socket = socket;
@ -122,17 +149,39 @@ public class AsyncSocket {
this.flushBuffer(); this.flushBuffer();
} }
/**
* sets the message handler for the async socket
* @param handler the `AsyncSocketListener` to be set as the new handler
* @author Luca Conte
*/
public void setHandler(AsyncSocketListener handler) { public void setHandler(AsyncSocketListener handler) {
this.handler = handler; this.handler = handler;
} }
/**
* sends a message through the socket
* @param socketPackage the socket package to be sent
* @author Luca Conte
*/
public synchronized void send(SocketPackage socketPackage) { public synchronized void send(SocketPackage socketPackage) {
this.sendLine(socketPackage.toString()); this.sendLine(socketPackage.toString());
} }
/**
* sends a message through the socket
* @param packageName the name of the package to be sent
* @author Luca Conte
*/
public synchronized void send(String packageName) { public synchronized void send(String packageName) {
this.send(packageName, ""); this.send(packageName, "");
} }
/**
* sends a message through the socket
* @param packageName the name of the package to be sent
* @param packageContent the content of the package to be sent.
* `packageName` and `packageContent` are joined with a space " "
* @author Luca Conte
*/
public synchronized 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;
@ -140,11 +189,19 @@ public class AsyncSocket {
this.sendLine(packageName + packageContent); this.sendLine(packageName + packageContent);
} }
/**
* sends a string of text into the socket, concatenated with CRLF
* @author Luca Conte
*/
public synchronized void sendLine(String message) { public synchronized void sendLine(String message) {
sendBuffer = sendBuffer + message + "\r\n"; sendBuffer = sendBuffer + message + "\r\n";
this.flushBuffer(); this.flushBuffer();
} }
/**
* flushes the buffers to send all pending messages
* @author Luca Conte
*/
private synchronized void flushBuffer() { private synchronized void flushBuffer() {
if (!this.sendBuffer.isEmpty() && this.out != null) { if (!this.sendBuffer.isEmpty() && this.out != null) {
try { try {
@ -159,12 +216,19 @@ public class AsyncSocket {
} }
} }
/**
* closes the socket connection and removes the checker thread
* @author Luca Conte
*/
public void close() { public void close() {
this.shouldStop = true; this.shouldStop = true;
try { try {
this.socket.close(); this.socket.close();
if (this.checkerThread != null) {
this.checkerThread.interrupt();
this.checkerThread.join(); this.checkerThread.join();
}
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} catch (InterruptedException e) { } catch (InterruptedException e) {

View File

@ -1,3 +1,7 @@
/**
* defines a message listener for AsyncSockets
* @author Luca Conte
*/
public interface AsyncSocketListener { public interface AsyncSocketListener {
public void receive(String message); public void receive(String message);
} }

View File

@ -1,14 +1,37 @@
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/**
* Diese Klasse ist das Board von eimem spieler und enthält alle logischen operationen.
* Sprich ist das Backend Board.
*
* @author Peer Ole Wachtel, Florian Alexy und Florian Hantzschel
*/
public class Board { public class Board {
/**
* Alle bisher empfangenen HitResponsen
*/
private List<HitResponse> hits; private List<HitResponse> hits;
/**
* Alle Schiffe des Semesters
*/
private List<Ship> ships; private List<Ship> ships;
/**
* Die größe des Spielfeldes
*/
private final int size; private final int size;
/**
* Erstellt ein neues Board.
* setzt die übergebene Spielfeldgröße.
* Erstellt die Liste aller Schiffe des Semesters
* @param size Die größe des Spielfeldes
* @author Peer Ole Wachtel, Florian Alexy und Florian Hantzschel
*/
public Board(int size) { public Board(int size) {
this.size = size; this.size = size;
this.ships = new ArrayList<>(); this.ships = new ArrayList<>();
@ -16,6 +39,12 @@ public class Board {
this.createShip(size - 13); this.createShip(size - 13);
} }
/**
* Nimmt einen punkt entgegen und Gibt einen HitResponse zurück.
* @param point auf den geschossen wurde
* @return
* @author Peer Ole Wachtel
*/
public synchronized HitResponse hit (Point point){ public synchronized HitResponse hit (Point point){
HitResponse response = new HitResponse(HitResponseType.MISS,point); HitResponse response = new HitResponse(HitResponseType.MISS,point);
for (int i = 0; i < this.ships.size(); i++) { for (int i = 0; i < this.ships.size(); i++) {
@ -42,6 +71,12 @@ public class Board {
return response; return response;
} }
/**
* finds adjacened hit responses and sets their type to SUNK if they are currently HIT
* this makes it so that all the points of the ship are marked as SUNK, not just the final hit
* @param p the Point from which to propate the SUNK type
* @author Luca Conte
*/
private void propagateSunk(Point p) { private void propagateSunk(Point p) {
HitResponse hit = this.getHitResponseOnPoint(p); HitResponse hit = this.getHitResponseOnPoint(p);
@ -55,17 +90,36 @@ public class Board {
propagateSunk(new Point(p.getX(), p.getY() - 1)); propagateSunk(new Point(p.getX(), p.getY() - 1));
} }
/**
* creates all the ships on a board given a certain semester
* @param semester the semester to be played in
* @author Peer Ole Wachtel
*/
private void createShip(int semester){ private void createShip(int semester){
List<ShipData> shipData = Ship.semeterList.get(semester -1); List<ShipData> shipData = Ship.semeterList.get(semester-1);
for (int i = 0; i < shipData.size(); i++) { for (int i = 0; i < shipData.size(); i++) {
this.ships.add(new Ship(shipData.get(i).size(), shipData.get(i).name())); this.ships.add(new Ship(shipData.get(i).size(), shipData.get(i).name()));
} }
} }
/**
* returns a list of all the Ships on the board
* @return a list of all the Ships on the board
* @author Peer Ole Wachtel
*/
public List<Ship> getShips() { public List<Ship> getShips() {
return ships; return ships;
} }
/**
* adds a HitResponse to the list of Hits on the board
* If a hit response already exists on the same position, the hit response will not be added
* If the hit response is of type `HitResponseType.SUNK` it will propagate this hit response type
* to all adjacened hit responses with type HIT using `propagateSunk`.
* @param hitResponse the HitResponse to be added
* @return true when the hit response was added, otherwise false
* @author Peer Ole Wachtel, Luca Conte
*/
public synchronized boolean addHits(HitResponse hitResponse) { public synchronized boolean addHits(HitResponse hitResponse) {
if (this.getHitResponseOnPoint(hitResponse.getPoint()) == null){ if (this.getHitResponseOnPoint(hitResponse.getPoint()) == null){
this.hits.add(hitResponse); this.hits.add(hitResponse);
@ -81,6 +135,11 @@ public class Board {
return false; return false;
} }
/**
* @param point the position to get the hit response from
* @return the hit response at the position `point`
* @author Peer Ole Wachtel
*/
public synchronized HitResponse getHitResponseOnPoint(Point point) { public synchronized HitResponse getHitResponseOnPoint(Point point) {
for (int i = 0; i < this.hits.size(); i++){ for (int i = 0; i < this.hits.size(); i++){
if (this.hits.get(i).getPoint().equals(point)){ if (this.hits.get(i).getPoint().equals(point)){
@ -90,6 +149,11 @@ public class Board {
return null; return null;
} }
/**
* returns the size of the board
* @return the size of the board
* @author Florian Alexy, Florian Hantzschel
*/
public int getSize() { public int getSize() {
return this.size; return this.size;
} }

View File

@ -21,7 +21,7 @@ public class BoardDisplay extends JPanel {
/** /**
* Fügt Buttons zu Liste hinzu und aktualisiert Feld durch Aufruf von paintFields * Fügt Buttons zu Liste hinzu und aktualisiert Feld durch Aufruf von paintFields
* @param button * @param button Jeweiliger Button der hinzugefügt werden soll
* @author Joshua Kuklok * @author Joshua Kuklok
*/ */
public void addShipButton(ShipButton button) { public void addShipButton(ShipButton button) {
@ -31,15 +31,15 @@ public class BoardDisplay extends JPanel {
/** /**
* Gibt currentShip zurück * Gibt currentShip zurück
* @return currentShip * @return currentShip Objekt der Klasse Schiff
* @author Lucas Bronson, Luca Conte, Joshua Kuklok * @author Lucas Bronson Luca Conte
*/ */
public Ship getCurrentShip() { public Ship getCurrentShip() {
return currentShip; return currentShip;
} }
/** /**
* Konstruktor der startLocalGame. * Konstruktor des Board Displays
* @param gridSize Die Größe des Spielfelds * @param gridSize Die Größe des Spielfelds
* @param player Der Spieler * @param player Der Spieler
* @author Lucas Bronson * @author Lucas Bronson
@ -55,8 +55,8 @@ public class BoardDisplay extends JPanel {
// Erstellung vom Spielfeld // Erstellung vom 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++) {
final int x = j - 1; // Temporäre Variable final int x = j - 1; // Temporäre Variable für überspringen von Rahmenzeile-/spalte
final int y = i - 1; // Temporäre Variable final int y = i - 1; // Temporäre Variable für überspringen von Rahmenzeile-/spalte
if (i == 0 && j == 0) { if (i == 0 && j == 0) {
add(new JLabel(" ")); add(new JLabel(" "));
} else if (i == 0) { } else if (i == 0) {
@ -67,7 +67,7 @@ public class BoardDisplay extends JPanel {
} else if (j == 0) { } else if (j == 0) {
JLabel rowLabel = new JLabel(String.valueOf((char) ('A' + i - 1))); JLabel rowLabel = new JLabel(String.valueOf((char) ('A' + i - 1)));
rowLabel.setHorizontalAlignment(SwingConstants.CENTER); rowLabel.setHorizontalAlignment(SwingConstants.CENTER);
rowLabel.setFont(new Font("Arial", Font.BOLD, 14)); rowLabel.setFont(new Font("Roboto", Font.BOLD, 14));
add(rowLabel); add(rowLabel);
} else { } else {
// Spielfeld (interaktive Zellen) // Spielfeld (interaktive Zellen)
@ -174,6 +174,7 @@ public class BoardDisplay extends JPanel {
if(currentShip != null) { if(currentShip != null) {
test = currentShip.getVirtualOccupiedPoints(mousePosition, horizontal); test = currentShip.getVirtualOccupiedPoints(mousePosition, horizontal);
} }
if (player == null || player.getBoard() == null) return;
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++) {
if(fields[i][j] == null) { if(fields[i][j] == null) {
@ -211,7 +212,7 @@ public class BoardDisplay extends JPanel {
} }
for(Ship ship: player.getBoard().getShips()) { for(Ship ship: player.getBoard().getShips()) {
if(ship.isShipOnPos(new Point(i,j))) { if(ship.isShipOnPos(new Point(i,j))) {
fields[i][j].setBackground(Color.LIGHT_GRAY); fields[i][j].setBackground(Color.WHITE);
} }
} }
HitResponse hit = this.player.getBoard().getHitResponseOnPoint(new Point(i, j)); HitResponse hit = this.player.getBoard().getHitResponseOnPoint(new Point(i, j));

View File

@ -23,7 +23,7 @@ public class GameBoard extends JPanel {
ImageIcon gameBoardX = new ImageIcon("graphics/gameboardx.png"); ImageIcon gameBoardX = new ImageIcon("graphics/gameboardx.png");
// kontextText Text-Strings // kontextText Text-Strings
String kT1 = "Bitte Schiffe setzten"; String kT1 = "Bitte Schiffe setzten - Rechtsclick zum drehen";
String kT2 = "Warte auf Gegner"; String kT2 = "Warte auf Gegner";
String kT3 = "Du fängst an"; String kT3 = "Du fängst an";
String kT4 = "Dein Gegner fängt an"; String kT4 = "Dein Gegner fängt an";
@ -40,6 +40,7 @@ public class GameBoard extends JPanel {
// Buttons // Buttons
JButton giveUpButton = new JButton("Aufgeben"); JButton giveUpButton = new JButton("Aufgeben");
/** /**
* Konstruktor von GameBoard. * Konstruktor von GameBoard.
* @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden. * @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden.
@ -55,12 +56,9 @@ public class GameBoard extends JPanel {
List<Ship> shipsP1 =p1.getBoard().getShips(); List<Ship> shipsP1 =p1.getBoard().getShips();
List<Ship> shipsP2 =p2.getBoard().getShips(); List<Ship> shipsP2 =p2.getBoard().getShips();
giveUpButton.addActionListener(new ActionListener() { giveUpButton.addActionListener((e) -> {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Hier könnte Ihr Backend Code stehen
frame.showPanel("MainMenu"); frame.showPanel("MainMenu");
} p1.withdraw();
}); });
} }
@ -108,7 +106,7 @@ public class GameBoard extends JPanel {
JPanel headerPanel = new JPanel(); JPanel headerPanel = new JPanel();
headerPanel.setLayout(new BorderLayout()); headerPanel.setLayout(new BorderLayout());
headerPanel.add(kontextText, BorderLayout.WEST); headerPanel.add(kontextText, BorderLayout.WEST);
kontextText.setFont(new Font("Roboto", Font.BOLD, 30)); //TODO setFont fixen kontextText.setFont(new Font("Roboto", Font.BOLD, 30));
headerPanel.add(giveUpButton, BorderLayout.EAST); headerPanel.add(giveUpButton, BorderLayout.EAST);
JPanel leftButtonsPanel = new JPanel(); JPanel leftButtonsPanel = new JPanel();
@ -136,7 +134,6 @@ public class GameBoard extends JPanel {
opponentBoardPanel.addShipButton(shipButton); opponentBoardPanel.addShipButton(shipButton);
shipButton.setEnabled(false); shipButton.setEnabled(false);
} }
JToggleButton readyButton = new JToggleButton("Bereit"); JToggleButton readyButton = new JToggleButton("Bereit");
readyButton.setBackground(Color.GREEN); readyButton.setBackground(Color.GREEN);
rightButtonsPanel.add(readyButton); rightButtonsPanel.add(readyButton);
@ -151,14 +148,18 @@ public class GameBoard extends JPanel {
ownBoardPanel.resetAllShips(); ownBoardPanel.resetAllShips();
} }
}); });
// TODO buttons erst disablen wenn alle Schiffe platziert sind
// Um Bereit-Meldung and Backend zu geben, kontextText zu setzten und ready/reset Button zu deaktivieren // Um Bereit-Meldung and Backend zu geben, kontextText zu setzten und ready/reset Button zu deaktivieren
readyButton.addActionListener(new ActionListener() { readyButton.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
kontextText.setText(kT2); kontextText.setText(kT2);
p1.ready(); p1.ready();
if(true) { if(p1.isReady()) {
remove(readyButton);
remove(resetButton);
remove(rightButtonsPanel);
remove(leftButtonsPanel);
readyButton.setEnabled(false); readyButton.setEnabled(false);
resetButton.setEnabled(false); resetButton.setEnabled(false);
} }
@ -201,15 +202,36 @@ public class GameBoard extends JPanel {
/** /**
* Aktualisiert Zustand(kontextText) je nach Zug * Aktualisiert Zustand(kontextText) je nach Zug
* @author Luca Conte * @author Luca Conte, Joshua Kuklok
*/ */
public void refresh() { public void refresh() {
if (this.p1.myTurn) { if (this.p1.myTurn) {
if (!kontextText.getText().equals(kT5)) {
this.kontextText.setText(kT5); this.kontextText.setText(kT5);
SoundHandler.playSound("yourturn");
}
} else { } else {
this.kontextText.setText(kT6); this.kontextText.setText(kT6);
} }
this.ownBoardPanel.refresh(); this.ownBoardPanel.refresh();
this.opponentBoardPanel.refresh(); this.opponentBoardPanel.refresh();
} }
/**
* Getter für Player1
* @return Player 1
* @author Peer Ole Wachtel
*/
public Player getP1() {
return p1;
}
/**
* Getter für Player2
* @return Player 2
* @author Luca Conte
*/
public Player getP2() {
return p2;
}
} }

View File

@ -5,28 +5,65 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
/**
* The central Backend Component
* @author Luca Conte
*/
public class GameController { public class GameController {
private static MainFrame mainFrame; private static MainFrame mainFrame;
/**
* returns the current MainFrame
* @return the current MainFrame
* @author Luca Conte
*/
public static MainFrame getMainFrame() { public static MainFrame getMainFrame() {
return GameController.mainFrame; return GameController.mainFrame;
} }
/**
* sets the current MainFrame
* @param mainFrame the current MainFrame
* @author Luca Conte
*/
public static void setMainFrame(MainFrame mainFrame) { public static void setMainFrame(MainFrame mainFrame) {
GameController.mainFrame = mainFrame; GameController.mainFrame = mainFrame;
} }
/**
* converts a semester to be played in into its respective board size
* @param semester the semester to be played in
* @author Luca Conte
*/
public static int semesterToBoardSize(int semester) { public static int semesterToBoardSize(int semester) {
return semester + 13; return semester + 13;
} }
/**
* converts a board size into its respective semester
* @param size the board size to get the semester of
* @author Luca Conte
*/
public static int boardSizeToSemester(int size) { public static int boardSizeToSemester(int size) {
return size - 13; return size - 13;
} }
/**
* the list of supported versions of the online protocol
* https://github.com/lgc-4/ProgProjekt-Netzwerkstandard
*/
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
)); ));
/**
* Starts a game with one local player and one online player.
* @param localPlayerClass the class of the local player to be instantiated. must extend `LocalPlayer`
* @param localPlayerName the name of the local player. Only necessarry when localPlayerClass is `HumanPlayer`
* @param address the Address of the opposing player. If the hostname of the address is set to be 0.0.0.0, it
* is interpreted that this instance should instead listen on the defined port for incoming connections.
* @param size the board size that it is intended to be played in
* @author Luca Conte
*/
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;
@ -89,7 +126,8 @@ public class GameController {
/** /**
* finds the largest common version in two lists of version strings * finds the largest common version in two lists of version strings
* @return null if no common versions are found * @return null if no common versions are found otherwise returns the most recent version present in both lists
* @author Luca Conte
*/ */
public static String findMostRecentVersion(List<String> versions1, List<String> versions2) { public static String findMostRecentVersion(List<String> versions1, List<String> versions2) {
if (versions1 == null || versions2 == null) return null; if (versions1 == null || versions2 == null) return null;
@ -114,10 +152,13 @@ public class GameController {
/** /**
* compares two version strings * compares two version strings
* @param version1 the first version to be compared
* @param version2 the second version to be compared
* @return * @return
* 0 if versions are equal * 0 if versions are equal
* 1 if version1 is more recent than version2 * 1 if version1 is more recent than version2
* -1 otherwise * -1 otherwise
* @author Luca Conte
*/ */
public static int compareVersions(String version1, String version2) { public static int compareVersions(String version1, String version2) {
if (!checkVersionString(version1) || !checkVersionString(version2)) { if (!checkVersionString(version1) || !checkVersionString(version2)) {
@ -143,11 +184,21 @@ public class GameController {
/** /**
* checks if a provided string matches the format of a version number * checks if a provided string matches the format of a version number
* @param versionString the version String to be checked
* @author Luca Conte
*/ */
public static boolean checkVersionString(String versionString) { public static boolean checkVersionString(String versionString) {
return versionString != null && versionString.matches("\\d+\\.\\d+\\.\\d+"); return versionString != null && versionString.matches("\\d+\\.\\d+\\.\\d+");
} }
/**
* Starts a game with two local players
* @param localPlayerClass the class of the local player to be instantiated. must extend `LocalPlayer`
* @param localPlayerName the name of the local player. Only necessarry when localPlayerClass is `HumanPlayer`
* @param enemyClass the class of the enemy player. Must extend `AiPlayer`. For Humans VS Human games use an online game instead.
* @param size the board size that it is intended to be played in
* @author Luca Conte
*/
public static void startLocalGame(Class<? extends LocalPlayer> localPlayerClass, String localPlayerName, Class<? extends AiPlayer> enemyClass, int size) { public static void startLocalGame(Class<? extends LocalPlayer> localPlayerClass, String localPlayerName, Class<? extends AiPlayer> enemyClass, int size) {
LocalPlayer localPlayer; LocalPlayer localPlayer;
@ -175,6 +226,13 @@ public class GameController {
startGameWithInstancedPlayers(localPlayer, aiPlayer, size); startGameWithInstancedPlayers(localPlayer, aiPlayer, size);
} }
/**
* switches to the ingame screen
* @param p1 the first player. This player is always shown on the left side of the screen and is expected to be the Human player, if there is one.
* @param p2 the second player
* @param boardSize the board size to be played in
* @author Luca Conte
*/
public static void startGameWithInstancedPlayers(LocalPlayer p1, Player p2, int boardSize) { public static void startGameWithInstancedPlayers(LocalPlayer p1, Player p2, int boardSize) {
mainFrame.showPanelSLG("GameBoard", boardSizeToSemester(boardSize), p1, p2); mainFrame.showPanelSLG("GameBoard", boardSizeToSemester(boardSize), p1, p2);

View File

@ -1,6 +1,6 @@
/** /**
* Hauptklasse über die der MainFrame gestartet wird * Hauptklasse über die der MainFrame gestartet wird
* @author Lucas Bronson, Ole Wachtel, Joshua Kuklok * @author Lucas Bronson, Peer Ole Wachtel, Joshua Kuklok
*/ */
public class HalloSchiffeVersenken { public class HalloSchiffeVersenken {
@ -8,19 +8,10 @@ public class HalloSchiffeVersenken {
* Erstellt und setzt den Mainframe * Erstellt und setzt den Mainframe
* @param args Argumente an Main durch Konsole etc. * @param args Argumente an Main durch Konsole etc.
* @throws InterruptedException * @throws InterruptedException
* @author Peer Ole Wachtel
*/ */
public static void main(String[] args) throws InterruptedException { public static void main(String[] args) throws InterruptedException {
MainFrame mf = new MainFrame(); MainFrame mf = new MainFrame();
mf.setVisible(true); mf.setVisible(true);
} }
} }
/*
*TODO
* Alle Textfonts anpassen
* SOUND interrupt?
* BACKEND aufruf bei aufgeben
* check bevor ready ob alle schiffe platziert?
* testcode rausnehmen
* FidgetButton als surprise (button während spiels, der zufällig farbe wechseln kann und sounds abspielt)
*/

View File

@ -1,14 +1,38 @@
/**
* Eine Antwort auf einen Schuss
* enthält einen Punkt, auf den geschossen wurde, sowie einen typen,
* der angibt, ob es sich bei dem Schuss um einen Treffer handelt
* @author Peer Ole Wachtel
*/
public class HitResponse { public class HitResponse {
/**
* Speichert den typ der HitResponse.
*/
private HitResponseType type; private HitResponseType type;
/**
* Speicher den Punkt wofür die HitResponse gilt.
*/
private Point point; private Point point;
/**
* Erstellt eine neue HitResponse und setzt den Punkt und typ.
* @param type der HitResponse.
* @param point für den die HitResponse gilt.
* @author Peer Ole Wachtel.
*/
public HitResponse(HitResponseType type, Point point) { public HitResponse(HitResponseType type, Point point) {
this.type = type; this.type = type;
this.point = point; this.point = point;
} }
/**
*Erstellt eine neue HitResponse und setzt den Punkt und typ.
* @param typeIndex der HitResponse.
* @param point für den die HitResponse gilt.
* @throws IllegalArgumentException wenn der übergebene int nicht auf ein typ referenziert werden kann.
* @author Peer Ole Wachtel.
*/
public HitResponse (int typeIndex, Point point) { public HitResponse (int typeIndex, Point point) {
if (typeIndex >= 0 && typeIndex < HitResponseType.values().length) { if (typeIndex >= 0 && typeIndex < HitResponseType.values().length) {
this.type = HitResponseType.values()[typeIndex]; this.type = HitResponseType.values()[typeIndex];
@ -18,23 +42,48 @@ public class HitResponse {
} }
} }
/**
* returns the type of the HitResponse
* @return the type of the HitResponse
* @author Florian Hantzschel
*/
public HitResponseType getHitResponse() { public HitResponseType getHitResponse() {
return this.type; return this.type;
} }
/**
* returns the point of the HitResponse
* @return the point of the HitResponse
* @author Florian Hantzschel
*/
public Point getPoint() { public Point getPoint() {
return this.point; return this.point;
} }
/**
* Setter für den type
* @param type auf den die HitResponse gesetzt werden soll.
* @author Peer Ole Wachtel
*/
public void setType(HitResponseType type) { public void setType(HitResponseType type) {
this.type = type; this.type = type;
} }
/**
* Gibt den passenden string nach Netzwerkstandard für eine HitResponse zurück.
* @return den passenden string nach Netzwerkstandard für eine HitResponse.
* @author Peer Ole Wachtel.
*/
@Override @Override
public String toString() { public String toString() {
return this.getPoint().toString() + " " + this.type.ordinal(); return this.getPoint().toString() + " " + this.type.ordinal();
} }
/**
* Getter für den typ der HitResponse.
* @return den typ der HitRespnse.
* @author Peer Ole Wachtel.
*/
public HitResponseType getType() { public HitResponseType getType() {
return type; return type;
} }

View File

@ -1,3 +1,7 @@
/**
* Stellt die verschiedenen möglichkeiten einer HitResponse als typ dar.
* @author Peer Ole Wachtel
*/
public enum HitResponseType { public enum HitResponseType {
MISS, HIT, SUNK, VICTORY MISS, HIT, SUNK, VICTORY
} }

View File

@ -1,4 +1,18 @@
/**
* Repräsentiert einen menschlichen Spieler
* @author Luca Conte, Florian Hantzschel
*/
public class HumanPlayer extends LocalPlayer { public class HumanPlayer extends LocalPlayer {
/**
* shoots a shot onto the provided point on the enemy board
* if it is not the players turn, this method does nothing.
* @param point the location to be shot
* @author Luca Conte
*/
@Override
public void shoot(Point point) {
if (!this.myTurn) return;
enemy.receiveShoot(point);
}
} }

View File

@ -12,6 +12,9 @@ import java.net.InetSocketAddress;
*/ */
public class JoinGame extends JPanel { public class JoinGame extends JPanel {
// Funktionshilfen
String standardPort = "51525";
// Grafiken // Grafiken
ImageIcon backButtonIcon = new ImageIcon("graphics/backButton.png"); ImageIcon backButtonIcon = new ImageIcon("graphics/backButton.png");
@ -39,9 +42,9 @@ public class JoinGame extends JPanel {
* @param playerName Name des Spielers * @param playerName Name des Spielers
* @author Lucas Bronson, Joshua Kuklok * @author Lucas Bronson, Joshua Kuklok
*/ */
public JoinGame(MainFrame frame,int g,int playerType,String playerName) { public JoinGame(MainFrame frame,int g,int playerType,String playerName, int semesterCounter) {
setLayout(null); setLayout(null);
buildPanel(frame,g,playerType,playerName); buildPanel(frame,g,playerType,playerName, semesterCounter);
} }
/** /**
@ -52,7 +55,8 @@ public class JoinGame extends JPanel {
* @param playerName Name des Spielers * @param playerName Name des Spielers
* @author Lucas Bronson, Joshua Kuklok * @author Lucas Bronson, Joshua Kuklok
*/ */
private void buildPanel(MainFrame frame,int g,int playerType,String playerName) { private void buildPanel(MainFrame frame,int g,int playerType,String playerName, int semesterCounter) {
System.out.println("semesterzahl in JoinGame" + semesterCounter);
if(g==1){ if(g==1){
spielBeitretenLabel= new JLabel("Spiel beitreten"); spielBeitretenLabel= new JLabel("Spiel beitreten");
}else{ }else{
@ -71,6 +75,7 @@ public class JoinGame extends JPanel {
} }
portTextField.setBounds(50, 225, 250, 50); portTextField.setBounds(50, 225, 250, 50);
portTextField.setText(standardPort);
spielBeitretenLabel.setFont(robotoFont.deriveFont(50f)); spielBeitretenLabel.setFont(robotoFont.deriveFont(50f));
@ -100,6 +105,7 @@ public class JoinGame extends JPanel {
if (ipAddress.isEmpty()) { if (ipAddress.isEmpty()) {
ipAddress = "0.0.0.0"; ipAddress = "0.0.0.0";
} }
System.out.println(portTextField.getText());
String portText = portTextField.getText(); String portText = portTextField.getText();
int port = Integer.parseInt(portText); int port = Integer.parseInt(portText);
@ -109,13 +115,13 @@ public class JoinGame extends JPanel {
try { try {
if(playerType == 0) { if(playerType == 0) {
GameController.startOnlineGame(HumanPlayer.class, playerName, address,GameController.semesterToBoardSize(2)); GameController.startOnlineGame(HumanPlayer.class, playerName, address,GameController.semesterToBoardSize(semesterCounter));
} else if(playerType == 1) { } else if(playerType == 1) {
GameController.startOnlineGame(SpecificAiPlayerEasy.class, playerName, address,GameController.semesterToBoardSize(2)); GameController.startOnlineGame(SpecificAiPlayerEasy.class, playerName, address,GameController.semesterToBoardSize(semesterCounter));
} else if (playerType == 2) { } else if (playerType == 2) {
GameController.startOnlineGame(SpecificAiPlayerMedium.class, playerName, address,GameController.semesterToBoardSize(2)); GameController.startOnlineGame(SpecificAiPlayerMedium.class, playerName, address,GameController.semesterToBoardSize(semesterCounter));
} else if (playerType == 3) { } else if (playerType == 3) {
GameController.startOnlineGame(SpecificAiPlayerHard.class, playerName, address,GameController.semesterToBoardSize(2)); GameController.startOnlineGame(SpecificAiPlayerHard.class, playerName, address,GameController.semesterToBoardSize(semesterCounter));
} }
} catch (IOException ex) { } catch (IOException ex) {
throw new RuntimeException(ex); throw new RuntimeException(ex);

View File

@ -1,15 +1,36 @@
import java.util.Random; import java.util.Random;
/**
* repräsentiert einen Player, der Lokal an dem Gerät spielt,
* auf dem dieses Programm läuft
* @author Luca Conte, Peer Ole Wachtel, Florian Hantzschel
*/
public class LocalPlayer extends Player { public class LocalPlayer extends Player {
/**
* erstellt einen LocalPlayer und setzt myCoin random
* @author Peer Ole Wachtel
*/
public LocalPlayer(){ public LocalPlayer(){
super(); super();
Random random = new Random(); Random random = new Random();
this.myCoin = random.nextBoolean(); this.myCoin = random.nextBoolean();
} }
/**
* receives a shot onto a point from the enemy
* @param point the location to be shot
* @author Luca Conte, Peer Ole Wachtel
*/
@Override @Override
public synchronized void receiveShoot(Point point) { public synchronized void receiveShoot(Point point) {
if (!this.enemy.myTurn) {
System.out.println("enemy tried to fire when not their turn!");
return;
}
this.enemy.myTurn = false;
HitResponse hitResponse = board.getHitResponseOnPoint(point); HitResponse hitResponse = board.getHitResponseOnPoint(point);
if (!(hitResponse == null)){ if (!(hitResponse == null)){
enemy.receiveHit(hitResponse); enemy.receiveHit(hitResponse);
@ -22,22 +43,34 @@ public class LocalPlayer extends Player {
switch (hitResponse.getType()) { switch (hitResponse.getType()) {
case HIT, SUNK -> this.myTurn = false; case HIT, SUNK -> this.myTurn = false;
case MISS -> this.myTurn = true; case MISS -> this.myTurn = true;
case VICTORY -> System.out.println("Game Over"); //TODO Was halt bei victory passiert ist hier wurder verloheren case VICTORY -> this.lose();
} }
GameController.getMainFrame().refreshGameBoard(); GameController.getMainFrame().refreshGameBoard();
} }
/**
* receives a hit response from the enemy as a response to a receiveShoot call
* @param hitResponse the hitresponse
* @author Peer Ole Wachtel
*/
@Override @Override
public synchronized void receiveHit(HitResponse hitResponse) { public synchronized void receiveHit(HitResponse hitResponse) {
enemy.board.addHits(hitResponse); enemy.board.addHits(hitResponse);
switch (hitResponse.getType()) { switch (hitResponse.getType()) {
case HIT, SUNK -> this.myTurn = true; case HIT, SUNK -> this.myTurn = true;
case MISS -> this.myTurn = false; case MISS -> this.myTurn = false;
case VICTORY -> System.out.println("Win"); // TODO was halt beim victory passier ist hier wurde gewonnen case VICTORY -> this.win();
} }
GameController.getMainFrame().refreshGameBoard(); GameController.getMainFrame().refreshGameBoard();
} }
/**
* receives the enemies coin toss result
* this method does nothing if the player has already received the enemies coin
* it will also call `determineCoinToss`
* @param coin the coin of the enemy player
* @author Luca Conte
*/
@Override @Override
public synchronized void receiveCoin(boolean coin) { public synchronized void receiveCoin(boolean coin) {
if (!this.hasReceivedCoin) { if (!this.hasReceivedCoin) {
@ -46,12 +79,20 @@ public class LocalPlayer extends Player {
} }
} }
/**
* sends shot to enemy player.
* should ONLY be called on HumanPlayer
* @author Luca Conte
*/
@Override @Override
public void shoot(Point point){ public void shoot(Point point){
this.myTurn = false; return;
enemy.receiveShoot(point);
} }
/**
* marks the player as ready, if all ships have been placed
* @author Luca Conte
*/
@Override @Override
public synchronized void ready() { public synchronized void ready() {
for (Ship ship : this.board.getShips()) { for (Ship ship : this.board.getShips()) {

View File

@ -1,34 +0,0 @@
import java.awt.*;
import javax.swing.*;
/**
* Klasse für Erstellung von looseScreen Objekten
* Dient zur Anzeige das ein Spiel verloren wurde
*/
public class LooseScreen extends JPanel {
JLabel looseLabel = new JLabel("Du hast Verloren");
JButton okButton = new JButton("Zurück zum Hauptmenü");
Font robotoFont = new Font("Roboto", Font.BOLD, 45);
/**
* Konstruktor der LooseScreen Klasse
* @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden.
* @author Lucas Bronson
*/
public LooseScreen(MainFrame frame) {
setLayout(new BorderLayout());
buildPanel(frame);
}
/**
* Panel bauen/Objekte hinzufügen
* @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden.
* @author Lucas Bronson
*/
public void buildPanel(MainFrame frame) {
add(looseLabel);
okButton.setBounds(650,525,200,50);
looseLabel.setBounds(500,450,500,50);
looseLabel.setFont(robotoFont);
}
}

48
src/LoseScreen.java Normal file
View File

@ -0,0 +1,48 @@
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
/**
* Klasse für Erstellung von looseScreen Objekten
* Dient zur Anzeige das ein Spiel verloren wurde
* @author Joshua Kuklok, Luca Bronson
*/
public class LoseScreen extends JPanel {
JLabel loseLabel = new JLabel("Du hast Verloren");
JButton okButton = new JButton("Zurück zum Hauptmenü");
Font robotoFont = new Font("Roboto", Font.BOLD, 45);
/**
* Konstruktor der LoseScreen Klasse
* @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden.
* @author Lucas Bronson
*/
public LoseScreen(MainFrame frame) {
setLayout(null);
buildPanel(frame);
}
/**
* Panel bauen/Objekte hinzufügen
* @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden.
* @author Lucas Bronson, Joshua Kuklok
*/
public void buildPanel(MainFrame frame) {
add(loseLabel);
okButton.setBounds(625,525,200,50);
loseLabel.setBounds(550,450,500,50);
loseLabel.setFont(robotoFont);
SoundHandler.playSound("loose");
// Zurückkehren zum Hauptmenü, wenn okButton gedrückt wird
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
frame.showPanel("MainMenu");
}
});
add(loseLabel);
add(okButton);
}
}

View File

@ -45,14 +45,12 @@ public class MainFrame extends JFrame {
MainMenuView mainMenuView = new MainMenuView(this); MainMenuView mainMenuView = new MainMenuView(this);
startLocalGame localGame = new startLocalGame(this); startLocalGame localGame = new startLocalGame(this);
startMultiplayerGame multiplayerGame = new startMultiplayerGame(this); startMultiplayerGame multiplayerGame = new startMultiplayerGame(this);
coinToss coinToss = new coinToss(this);
Verbinden verbinden = new Verbinden(this); Verbinden verbinden = new Verbinden(this);
// Panels hinzufügen // Panels hinzufügen
mainPanel.add(mainMenuView, "MainMenu"); mainPanel.add(mainMenuView, "MainMenu");
mainPanel.add(localGame, "LocalGame"); mainPanel.add(localGame, "LocalGame");
mainPanel.add(multiplayerGame, "MultiplayerGame"); mainPanel.add(multiplayerGame, "MultiplayerGame");
mainPanel.add(coinToss, "coinToss");
mainPanel.add(verbinden, "Verbinden"); mainPanel.add(verbinden, "Verbinden");
// mainPanel.add(winLooseScreen, "WinLooseScreen"); // mainPanel.add(winLooseScreen, "WinLooseScreen");
@ -80,10 +78,10 @@ public class MainFrame extends JFrame {
* @param playerName Name des Spielers * @param playerName Name des Spielers
* @author Lucas Bronson, Joshua Kuklok * @author Lucas Bronson, Joshua Kuklok
*/ */
public void showPanelSMG(String panelName, int num, int playerType,String playerName) { public void showPanelSMG(String panelName, int num, int playerType,String playerName, int semesterCounter) {
this.localMult = num; this.localMult = num;
JoinGame joinGame = new JoinGame(this, localMult, playerType, playerName); JoinGame joinGame = new JoinGame(this, localMult, playerType, playerName, semesterCounter);
mainPanel.add(joinGame, panelName); mainPanel.add(joinGame, panelName);
mainPanel.revalidate(); mainPanel.revalidate();
mainPanel.repaint(); mainPanel.repaint();
@ -127,9 +125,19 @@ public class MainFrame extends JFrame {
/** /**
* Spezifische ShowPanel für WinScreen Klasse * Spezifische ShowPanel für WinScreen Klasse
* @param panelName Name des anzuzeigenden Panels * @param panelName Name des anzuzeigenden Panels
* @author Lucas Bronson * @param player Player von dem die funktion aufgerufen worden ist
* @author Lucas Bronson, Peer Ole Wachtel, Luca Conte
*/ */
public void showPanelWin(String panelName){ public void showPanelWin(String panelName, Player player){
if(gameBoard == null || player != gameBoard.getP1()){
return;
}
this.gameBoard.getP1().destroy();
this.gameBoard.getP2().destroy();
this.gameBoard.removeAll();
this.gameBoard = null;
WinScreen winScreen = new WinScreen(this); WinScreen winScreen = new WinScreen(this);
mainPanel.add(winScreen, panelName); mainPanel.add(winScreen, panelName);
mainPanel.revalidate(); mainPanel.revalidate();
@ -140,10 +148,20 @@ public class MainFrame extends JFrame {
/** /**
* Spezifische ShowPanel für LooseScreen Klasse * Spezifische ShowPanel für LooseScreen Klasse
* @param panelName Name des anzuzeigenden Panels * @param panelName Name des anzuzeigenden Panels
* @author Lucas Bronson * @param player Player von dem die funktion aufgerufen worden ist
* @author Lucas Bronson, Peer Ole Wachtel, Luca Conte
*/ */
public void showPanelLoose(String panelName){ public void showPanelLose(String panelName, Player player){
LooseScreen looseScreen = new LooseScreen(this); if(gameBoard == null || player != gameBoard.getP1()){
return;
}
this.gameBoard.getP1().destroy();
this.gameBoard.getP2().destroy();
this.gameBoard.removeAll();
this.gameBoard = null;
LoseScreen looseScreen = new LoseScreen(this);
mainPanel.add(looseScreen,panelName); mainPanel.add(looseScreen,panelName);
mainPanel.revalidate(); mainPanel.revalidate();
mainPanel.repaint(); mainPanel.repaint();
@ -151,7 +169,7 @@ public class MainFrame extends JFrame {
} }
/** /**
* Aktualisiert das Spielfeld (kontextText) * Aktualisiert das Spielfeld
* @author Luca Conte * @author Luca Conte
*/ */
public void refreshGameBoard() { public void refreshGameBoard() {

View File

@ -1,28 +1,57 @@
public abstract class OnlinePlayer extends Player implements AsyncSocketListener{ /**
* Abstrakte Repräsentation eines Spielers, der an einem anderen gerät spielt
* und durch eine Online Verbindung mit dieser Instanz kommuniziert
* @author Luca Conte, Peer Ole Wachtel
*/
public abstract class OnlinePlayer extends Player implements AsyncSocketListener {
protected AsyncSocket socket; protected AsyncSocket socket;
protected int wantedBoardSize; protected int wantedBoardSize;
protected boolean hasReceivedCoinPackage; protected boolean hasReceivedCoinPackage;
/**
* Constructor
* @param size the size of the board the enemy player wants to play with
* the actual board size will be determined once the semester of the online partner is known
* @param socket an AsyncSocket to communicate with the enemy through
* @author Peer Ole Wachtel, Luca Conte
*/
public OnlinePlayer(Integer size, AsyncSocket socket) { public OnlinePlayer(Integer size, AsyncSocket socket) {
this.socket = socket; this.socket = socket;
this.wantedBoardSize = size; this.wantedBoardSize = size;
this.myCoin = null; this.myCoin = null;
socket.setHandler(this); socket.setHandler(this);
//TODO Auto-generated constructor stub
} }
/**
* sends the IAM Package for introduction
* @author Luca Conte
*/
public abstract void sendIAM(); public abstract void sendIAM();
/**
* receives a message from the AsyncSocket
* satisfies AsyncSocketListener interface
* @author Luca Conte
*/
public abstract void receive(String message); public abstract void receive(String message);
@Override /**
public abstract void receiveShoot(Point point); * receives the coin toss result from the enemy
* @param coin the result of the coin toss
@Override * @author Peer Ole Wachtel
public abstract void receiveHit(HitResponse hitResponse); */
@Override @Override
public abstract void receiveCoin(boolean coin); public abstract void receiveCoin(boolean coin);
/**
* closes the socket and does player cleanup work
* @author Luca Conte
*/
@Override
public void destroy() {
super.destroy();
this.socket.close();
}
} }

View File

@ -1,11 +1,29 @@
import java.util.List; import java.util.List;
/**
* eine Implementierung des Kommunikationsprotokoll nach Version 1.1.0 des Netzwerkstandards
* https://github.com/lgc-4/ProgProjekt-Netzwerkstandard
* @author Peer Ole Wachtel, Luca Conte
*/
public class OnlinePlayer_1_1_0 extends OnlinePlayer { public class OnlinePlayer_1_1_0 extends OnlinePlayer {
/**
* Erstellt einen Online Player
* @param size die maximale Größe des Spielfelds
* @param socket der Socket zur Kommunikation mit dem Online Partner
*/
public OnlinePlayer_1_1_0(Integer size, AsyncSocket socket) { public OnlinePlayer_1_1_0(Integer size, AsyncSocket socket) {
super(size, socket); super(size, socket);
} }
/**
* receives a message from the AsyncSocket
* implemented according to version 1.1.0 of https://github.com/lgc-4/ProgProjekt-Netzwerkstandard
* @param message the message from the socket
* @author Peer Ole Wachtel, Luca Conte, Florian Hantzschel
*/
@Override @Override
public void receive(String message) { public void receive(String message) {
SocketPackage p = new SocketPackage(message); SocketPackage p = new SocketPackage(message);
@ -34,8 +52,8 @@ public class OnlinePlayer_1_1_0 extends OnlinePlayer {
case "COIN": case "COIN":
if(!this.hasReceivedCoinPackage && (p.getData().equals("1") || p.getData().equals("0"))){ if(!this.hasReceivedCoinPackage && (p.getData().equals("1") || p.getData().equals("0"))){
this.myCoin = p.getData().equals("1"); this.myCoin = p.getData().equals("1");
this.ready();
this.hasReceivedCoinPackage = true; this.hasReceivedCoinPackage = true;
this.ready();
} }
break; break;
@ -52,7 +70,23 @@ public class OnlinePlayer_1_1_0 extends OnlinePlayer {
Point point = new Point(data.get(0)); Point point = new Point(data.get(0));
int typeIndex = Integer.parseInt(data.get(1)); int typeIndex = Integer.parseInt(data.get(1));
if (Point.isValidSyntax(data.get(0)) && typeIndex >= 0 && typeIndex < HitResponseType.values().length){ if (Point.isValidSyntax(data.get(0)) && typeIndex >= 0 && typeIndex < HitResponseType.values().length){
this.enemy.receiveHit(new HitResponse(typeIndex, point));
HitResponse hitResponse = new HitResponse(typeIndex, point);
this.enemy.receiveHit(hitResponse);
switch (hitResponse.getType()) {
case HIT, SUNK:
this.myTurn = false;
break;
case MISS:
this.myTurn = true;
break;
case VICTORY:
// GameController.getMainFrame().showPanelWin("", this.enemy);
break;
}
} }
} }
break; break;
@ -61,28 +95,66 @@ public class OnlinePlayer_1_1_0 extends OnlinePlayer {
//TODO CHAT //TODO CHAT
break; break;
case "WITHDRAW":
this.withdraw();
break;
default: default:
//nichts passier da Paket ungültig //nichts passier da Paket ungültig
break; break;
} }
} }
/**
* sends introduction package IAM to online partner.
* @author Luca Conte
*/
@Override @Override
public synchronized void sendIAM() { public synchronized void sendIAM() {
if (this.enemy == null) throw new RuntimeException("enemy has not yet been defined"); if (this.enemy == null) throw new RuntimeException("enemy has not yet been defined");
socket.send(new SocketPackage("IAM", GameController.boardSizeToSemester(this.wantedBoardSize) + " " + this.enemy.name)); socket.send(new SocketPackage("IAM", GameController.boardSizeToSemester(this.wantedBoardSize) + " " + this.enemy.name));
} }
/**
* receives a shot from the enemy and sends it to the online partner
* if it is not the enemies turn, this method does nothing.
* @param point the point to be shot
* @author Peer Ole Wachtel, Luca Conte
*/
@Override @Override
public synchronized void receiveShoot(Point point){ public synchronized void receiveShoot(Point point){
if (!this.enemy.myTurn) return;
super.socket.send(new SocketPackage("SHOOT",point.toString())); super.socket.send(new SocketPackage("SHOOT",point.toString()));
} }
/**
* receives a hitresponse from the enemy player and sends it to the online partner
* @param hitResponse the hitresponse to be sent
* @author Peer Ole Wachtel, Luca Conte
*/
@Override @Override
public synchronized void receiveHit(HitResponse hitResponse) { public synchronized void receiveHit(HitResponse hitResponse) {
switch (hitResponse.getType()) {
case HIT, SUNK:
this.myTurn = true;
break;
case MISS:
this.myTurn = false;
break;
case VICTORY:
// GameController.getMainFrame().showPanelLose("", this.enemy);
break;
}
super.socket.send(new SocketPackage("HIT", hitResponse.toString())); super.socket.send(new SocketPackage("HIT", hitResponse.toString()));
} }
/**
* receives the coin toss result from the enemy player and sends it to the online partner
* if this player has already received the enemies coin, this method does nothing.
* @param coin the result of the coin toss
* @author Peer Ole Wachtel, Luca Conte
*/
@Override @Override
public synchronized void receiveCoin(boolean coin) { public synchronized void receiveCoin(boolean coin) {
if (!this.hasReceivedCoin) { if (!this.hasReceivedCoin) {
@ -92,8 +164,25 @@ public class OnlinePlayer_1_1_0 extends OnlinePlayer {
} }
} }
/**
* für Online Player nicht zu implementieren
* nur für HumanPlayer relevant
* @author Luca Conte, Peer Ole Wachtel
*/
@Override @Override
public synchronized void shoot(Point point) { public synchronized void shoot(Point point) {
super.socket.send(new SocketPackage("SHOOT", point.toString())); // SHOULD NEVER BE CALLED ON ONLINE PLAYER. ONLY ON HUMAN PLAYER
return;
}
/**
* empfängt Withdraw vom Gegner und leitet es an den Online Partner weiter
* beendet das Spiel
* @author Luca Conte
*/
@Override
public void receiveWithdraw() {
this.socket.send(new SocketPackage("WITHDRAW"));
super.receiveWithdraw();
} }
} }

View File

@ -1,3 +1,7 @@
/**
* abstrakte repräsentation eines Spielers
* @author Peer Ole Wachtel, Luca Conte, Lucas Bronson
*/
public abstract class Player { public abstract class Player {
protected boolean myTurn; protected boolean myTurn;
protected boolean isServer; protected boolean isServer;
@ -12,6 +16,10 @@ public abstract class Player {
protected boolean hasReceivedCoin; protected boolean hasReceivedCoin;
/**
* Konstruktor
* @author Peer Ole Wachtel, Luca Conte
*/
public Player() { public Player() {
this.setName("Player"); this.setName("Player");
this.hasReceivedCoin = false; this.hasReceivedCoin = false;
@ -20,35 +28,85 @@ public abstract class Player {
this.gameRunning = false; this.gameRunning = false;
} }
/**
* initialises this players board
* @param size the size of the board to be created
* @author Peer Ole Wachtel
*/
public void createBoard(int size) { public void createBoard(int size) {
this.board = new Board(size); this.board = new Board(size);
} }
/**
* receives a shot onto a point from the enemy
* @param point the location to be shot
* @author Luca Conte, Peer Ole Wachtel
*/
public abstract void receiveShoot(Point point); public abstract void receiveShoot(Point point);
/**
* receives a hit response from the enemy as a response to a receiveShoot call
* @param hitResponse the hitresponse
* @author Peer Ole Wachtel
*/
public abstract void receiveHit(HitResponse hitResponse); public abstract void receiveHit(HitResponse hitResponse);
/**
* sends shot to enemy player.
* should ONLY be called on HumanPlayer
* @author Luca Conte
*/
public abstract void shoot(Point point); public abstract void shoot(Point point);
/**
* only relevant for AI Players.
* starts the first turn
* @author Luca Conte
*/
public void beginTurn() { public void beginTurn() {
System.out.println("issa my turn-a"); System.out.println("issa my turn-a");
} }
/**
* sets the enemy Player
* @author Peer Ole Wachtel
*/
public void setEnemy(Player enemy) { public void setEnemy(Player enemy) {
this.enemy = enemy; this.enemy = enemy;
} }
/**
* sets the name of this player
* @param name the name of this player
* @author Luca Conte
*/
public void setName(String name) { public void setName(String name) {
this.name = name; this.name = name;
} }
/**
* returns the name of this player
* @return the name of this player
* @author Luca Conte
*/
public String getName() { public String getName() {
return this.name; return this.name;
} }
/**
* returns the board of this player
* @return the board of this player
* @author Lucas Bronson
*/
public Board getBoard() { public Board getBoard() {
return this.board; return this.board;
} }
/**
* marks the player as ready by sending their coin to the enemy player
* calls determineCoinToss if the enemy coin has already been received
* @author Luca Conte
*/
public void ready() { public void ready() {
this.enemy.receiveCoin(this.myCoin); this.enemy.receiveCoin(this.myCoin);
this.sentCoin = true; this.sentCoin = true;
@ -57,6 +115,11 @@ public abstract class Player {
} }
}; };
/**
* determines the result of the coin toss
* this method does nothing if either player is not ready yet or has not yet sent their coin
* @author Luca Conte, Peer Ole Wachtel
*/
protected void determineCoinToss() { protected void determineCoinToss() {
if (!this.sentCoin || this.myCoin == null || !this.hasReceivedCoin || this.enemy.myCoin == null) return; if (!this.sentCoin || this.myCoin == null || !this.hasReceivedCoin || this.enemy.myCoin == null) return;
boolean result = this.enemy.myCoin ^ this.myCoin; // XOR boolean result = this.enemy.myCoin ^ this.myCoin; // XOR
@ -68,13 +131,81 @@ public abstract class Player {
GameController.getMainFrame().refreshGameBoard(); GameController.getMainFrame().refreshGameBoard();
} }
/**
* receives the coin toss from the enemy player
* @param coin the coin of the enemy player
* @author Peer Ole Wachtel
*/
public abstract void receiveCoin(boolean coin); public abstract void receiveCoin(boolean coin);
/**
* returns whether the game this player is in has started, meaning both players are ready and have sent their coins
* @return the game's running state
* @author Luca Conte
*/
public boolean isGameRunning() { public boolean isGameRunning() {
return this.gameRunning; return this.gameRunning;
} }
/**
* returns whether this player is ready and has sent their coin to the enemy player
* @return the player's ready state
* @author Lucas Bronson
*/
public boolean isReady() { public boolean isReady() {
return this.sentCoin; return this.sentCoin;
} }
/**
* removes connections to the enemy and its board as well as setting myTurn and gameRunning to false
* this stops the AI Players from making more moves and allows the garbage collector to remove the boards
* and players
*
* This method should be called at the end of a game
*
* @author Luca Conte
*/
public void destroy() {
this.myTurn = false;
this.gameRunning = false;
this.board = null;
this.enemy = null;
}
/**
* the player wins
* ends the game
* @author Luca Conte
*/
public void win() {
GameController.getMainFrame().showPanelWin("", this);
}
/**
* the player loses
* ends the game
* @author Luca Conte
*/
public void lose() {
GameController.getMainFrame().showPanelLose("", this);
}
/**
* the player loses by withdrawal
* ends the game
* @author Luca Conte
*/
public void withdraw() {
this.enemy.receiveWithdraw();
this.lose();
}
/**
* the enemy player withdraws
* ends the game
* @author Luca Conte
*/
public void receiveWithdraw(){
this.win();
}
} }

View File

@ -1,11 +1,32 @@
/**
* repräsentation der Koordinaten eines Feldes auf dem Spielfeld
* @author Peer Ole Wachtel, Luca Conte
*/
public class Point { public class Point {
private int x; private int x;
private int y; private int y;
/**
* initialises a point using X and Y coordinates starting at 0
* @param x the x coordinate of the point starting at 0
* @param y the y coordinate of the point starting at 0
* @author Peer Ole Wachtel
*/
public Point (int x, int y) { public Point (int x, int y) {
this.setX(x); this.setX(x);
this.setY(y); this.setY(y);
} }
/**
* initialises a Point using a coordinate provided in the format of a letter followed by a number
* this coordinate is checked using `isValidSyntax`
* If the coordinate is not in a valid syntax, an `IllegalArgumentException` will be thrown, stating as such
* The number part of the coordinate starts at 1 instead of 0 so for example, the
* string A1 will result in the X and Y coordinates of (0, 0)
* @param str the coordinate in alphanumeric format
* @throws IllegalArgumentException if the coordinate is invalid according to `isValidSyntax`
* @author Peer Ole Wachtel, Luca Conte
*/
public Point (String str) { public Point (String str) {
if (Point.isValidSyntax(str)) { if (Point.isValidSyntax(str)) {
this.setX(str.charAt(0)); this.setX(str.charAt(0));
@ -15,34 +36,78 @@ public class Point {
} }
} }
/**
* returns this point as a string in its alphanumeric format
* @return this point as a string in its alphanumeric format
* @author Luca Conte, Peer Ole Wachtel
*/
@Override @Override
public String toString() { public String toString() {
return (char) ('A' + this.x) + String.valueOf(this.y + 1); return (char) ('A' + this.x) + String.valueOf(this.y + 1);
} }
/**
* returns the X coordinate of the point starting at 0
* @return the X coordinate of the point starting at 0
* @author Peer Ole Wachtel
*/
public int getX() { public int getX() {
return x; return x;
} }
/**
* returns the Y coordinate of the point starting at 0
* @return the Y coordinate of the point starting at 0
* @author Peer Ole Wachtel
*/
public int getY() { public int getY() {
return y; return y;
} }
/**
* sets the X coordinate of the point starting at 0
* @param x the X coordinate of the point starting at 0
* @author Peer Ole Wachtel
*/
public void setX(int x) { public void setX(int x) {
this.x = x; this.x = x;
} }
/**
* sets the Y coordinate of the point starting at 0
* @param y the Y coordinate of the point starting at 0
* @author Peer Ole Wachtel
*/
public void setY(int y) { public void setY(int y) {
this.y = y; this.y = y;
} }
/**
* sets the X coordinate of the from its character value in alphanumeric form
* @param c the character to be transformed into
* @author Peer Ole Wachtel
*/
public void setX(char c) { public void setX(char c) {
this.x = c - 'A'; this.x = c - 'A';
} }
/**
* checks whether a string is a valid alphanumeric point coordinate
* @param str the string to be tested
* @return whether the string is valid according to the regular expression `^[A-Z]\\d+$`
* @author Peer Ole Wachtel
*/
public static boolean isValidSyntax(String str) { public static boolean isValidSyntax(String str) {
return str.matches("^[A-Z]\\d+$"); return str.matches("^[A-Z]\\d+$");
} }
/**
* returns whether two points are equal
* two points with equivalent coordinates are considered equal
* @param o the other object/Point to compare this one to
* @return whether the objects are equal
* @author Luca Conte
*/
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;
@ -52,6 +117,13 @@ public class Point {
return p.getX() == this.getX() && p.getY() == this.getY(); return p.getX() == this.getX() && p.getY() == this.getY();
} }
/**
* determines whether two points are neighbours
* points are considered neighbours if their positions are equal or within a difference of 1 on both X and Y axis
* @param other the point to check for neighbourship
* @return whether the points are neighbours
* @author Luca Conte
*/
public boolean neighbours(Point other) { public boolean neighbours(Point other) {
if (other == null) return false; if (other == null) return false;
return (int)Math.abs(this.getX() - other.getX()) <= 1 && (int)Math.abs(this.getY() - other.getY()) <= 1; return (int)Math.abs(this.getX() - other.getX()) <= 1 && (int)Math.abs(this.getY() - other.getY()) <= 1;

View File

@ -5,44 +5,56 @@ import java.util.List;
record ShipData (int size, String name){} record ShipData (int size, String name){}
/**
* repräsentation eines Schiffes auf dem Spielfeld
* @author Peer Ole Wachtel, Lucas Bronson, Florian Hanzschel
*/
public class Ship { public class Ship {
static List<List<ShipData>> semeterList = Arrays.asList(Arrays.asList( static List<List<ShipData>> semeterList =
Arrays.asList(
Arrays.asList(
new ShipData(2, "PRG 1"), new ShipData(2, "PRG 1"),
new ShipData(2, "GDI"), new ShipData(2, "GDI"),
new ShipData(2, "MAT 1"), new ShipData(2, "MAT 1"),
new ShipData(2, "THI"), new ShipData(2, "THI"),
new ShipData(4, "STP"), new ShipData(4, "STP"),
new ShipData(6, "ENG")), new ShipData(6, "ENG")
),
Arrays.asList( Arrays.asList(
new ShipData(2, "PRG 2"), new ShipData(2, "PRG 2"),
new ShipData(2, "DBS 1"), new ShipData(2, "DBS 1"),
new ShipData(2, "MAT 2"), new ShipData(2, "MAT 2"),
new ShipData(2, "STA"), new ShipData(2, "STA"),
new ShipData(2, "AUD")), new ShipData(2, "AUD")
),
Arrays.asList( Arrays.asList(
new ShipData(2, "PRG 3"), new ShipData(2, "PRG 3"),
new ShipData(2, "DBS 2"), new ShipData(2, "DBS 2"),
new ShipData(2, "MAT 3"), new ShipData(2, "MAT 3"),
new ShipData(2, "BSN 1"), new ShipData(2, "BSN 1"),
new ShipData(4, "PRP"), new ShipData(4, "PRP"),
new ShipData(6, "BWL")), new ShipData(6, "BWL")
),
Arrays.asList( Arrays.asList(
new ShipData(2, "WEB"), new ShipData(2, "WEB"),
new ShipData(2, "SE 1"), new ShipData(2, "SE 1"),
new ShipData(2, "CG 1"), new ShipData(2, "CG 1"),
new ShipData(2, "BSN 2"), new ShipData(2, "BSN 2"),
new ShipData(4, "SEM"), new ShipData(4, "SEM"),
new ShipData(6, "E BWL")), new ShipData(6, "E BWL")
),
Arrays.asList( Arrays.asList(
new ShipData(2, "WPF 1"), new ShipData(2, "WPF 1"),
new ShipData(2, "SE 2"), new ShipData(2, "SE 2"),
new ShipData(2, "CG 2"), new ShipData(2, "CG 2"),
new ShipData(2, "PXP 1"), new ShipData(2, "PXP 1"),
new ShipData(6, "EF 1")), new ShipData(6, "EF 1")
),
Arrays.asList( Arrays.asList(
new ShipData(2, "WPF 2"), new ShipData(2, "WPF 2"),
new ShipData(1, "PXP 2"), new ShipData(1, "PXP 2"),
new ShipData(8, "BAA")) new ShipData(8, "BAA")
)
); );
private int size; private int size;
@ -52,6 +64,12 @@ public class Ship {
private int hitsOnMe; private int hitsOnMe;
private boolean sunk; private boolean sunk;
/**
* initialises a Ship with a given size and name
* @param size the size of the ship
* @param name the name of the ship
* @author Peer Ole Wachtel
*/
public Ship (int size, String name) { public Ship (int size, String name) {
this.size = size; this.size = size;
this.name = name; this.name = name;
@ -61,10 +79,23 @@ public class Ship {
this.sunk = false; this.sunk = false;
} }
/**
* resets the position of this ship
* @author Luca Conte
*/
public void resetPosition() { public void resetPosition() {
this.position = null; this.position = null;
} }
/**
* sets the position of this ship, provided it is valid
* @param pos the position to move the ship to
* @param horizontal whether the ship is horizontal or not
* @param shipsList the list of other ships on this board. It will be checked whether the ship is touching any of them
* @param boardSize the size of the board the ship is to be placed on
* @return true if the position was set successfully. false if the ship is out of the bounds of the board or touches a different ship
* @author Luca Conte
*/
public boolean setPosition(Point pos, boolean horizontal, List<Ship> shipsList, int boardSize) { public boolean setPosition(Point pos, boolean horizontal, List<Ship> shipsList, int boardSize) {
if (!this.checkValidPlacement(pos, horizontal, shipsList, boardSize)) return false; if (!this.checkValidPlacement(pos, horizontal, shipsList, boardSize)) return false;
@ -74,6 +105,15 @@ public class Ship {
return true; return true;
} }
/**
* checks whether a position is valid for ship placement
* @param pos the position to check the ship placement at
* @param horizontal whether the ship is to be placed horizontally or not
* @param shipsList the list of other ships on this board. It will be checked whether the ship is touching any of them
* @param boardSize the size of the board the ship is to be placed on
* @return true if the position is valid. false if the ship is out of the bounds of the board or touches a different ship
* @author Florian Hantzschel, Peer Ole Wachtel, Luca Conte
*/
public boolean checkValidPlacement(Point pos, boolean horizontal, List<Ship> shipsList, int boardSize) { public boolean checkValidPlacement(Point pos, boolean horizontal, List<Ship> shipsList, int boardSize) {
// ueberpruefe boundaries // ueberpruefe boundaries
if (pos.getX() < 0 || pos.getY() < 0 || pos.getX() >= boardSize || pos.getY() >= boardSize) { if (pos.getX() < 0 || pos.getY() < 0 || pos.getX() >= boardSize || pos.getY() >= boardSize) {
@ -122,7 +162,11 @@ public class Ship {
} }
/** /**
* Returns the Points on the ship if it were to be placed at positino `pos` in orientation defined by `horizontal` * Returns the Points on the ship if it were to be placed at position `pos` in orientation defined by `horizontal`
* @param pos the position where the ship should be placed
* @param horizontal whether the ship should be placed horizontally
* @return a list of points the ship would occupy, were it placed at position `pos` in orientation `horizontal`
* @author Florian Hantzschel, Luca Conte
*/ */
public List<Point> getVirtualOccupiedPoints(Point pos, boolean horizontal) { public List<Point> getVirtualOccupiedPoints(Point pos, boolean horizontal) {
List<Point> points = new ArrayList<>(); List<Point> points = new ArrayList<>();
@ -137,23 +181,30 @@ public class Ship {
return points; return points;
} }
/**
* Returns the Points the ship occupies
* @return a list of points the ship occupies
* @author Florian Hantzschel, Luca Conte
*/
public List<Point> getOccupiedPoints() { public List<Point> getOccupiedPoints() {
List<Point> points = new ArrayList<>(); return this.getVirtualOccupiedPoints(this.position, this.horizontal);
if (this.position == null) {
return points;
}
for (int i = 0; i < this.size; i++) {
int x = this.horizontal ? this.position.getX() + i : this.position.getX();
int y = this.horizontal ? this.position.getY() : this.position.getY() + i;
points.add(new Point(x, y));
}
return points;
} }
/**
* returns the position of this ship
* @return the position of this ship
* @author Peer Ole Wachtel
*/
public Point getPosition() { public Point getPosition() {
return position; return position;
} }
/**
* checks whether the ship occupies a certain point
* @param pos the point to be checkd
* @return whether the point provided is one of the points occupied by the ship
* @author Peer Ole Wachtel, Lucas Bronson
*/
public boolean isShipOnPos(Point pos){ public boolean isShipOnPos(Point pos){
if(this.position == null){ if(this.position == null){
return false; return false;
@ -165,6 +216,13 @@ public class Ship {
return false; return false;
} }
/**
* "shoots" this ship.
* @return a hit response, depending on whether the ship was hit or not. If the amount of times
* the ship was hit is greater or equal to the size of the ship, the ship is considered sunk.
* @param pos the point where the ship is shot
* @author Peer Ole Wachtel
*/
public HitResponseType shootOnShip(Point pos) { public HitResponseType shootOnShip(Point pos) {
if (this.isShipOnPos(pos)) { if (this.isShipOnPos(pos)) {
hitsOnMe++; hitsOnMe++;
@ -179,22 +237,47 @@ public class Ship {
} }
} }
/**
* returns whether the ship has been sunk or not
* @return whether the ship has been sunk or not
* @author Peer Ole Wachtel
*/
public boolean isSunk() { public boolean isSunk() {
return sunk; return sunk;
} }
/**
* sets the orientation of the ship
* @param horizontal whether the ship is to be placed in a horizontal orientation
* @author Lucas Bronson
*/
public void setHorizontal(boolean horizontal) { public void setHorizontal(boolean horizontal) {
this.horizontal = horizontal; this.horizontal = horizontal;
} }
/**
* returns the size of the ship
* @return the size of the ship
* @author Lucas Bronson
*/
public int getSize() { public int getSize() {
return size; return size;
} }
/**
* returns the name of the ship
* @return the name of the ship
* @author Lucas Bronson
*/
public String getName() { public String getName() {
return name; return name;
} }
//potentiell falsch neu /**
* returns whether the ship has been placed or not
* @return whether the ship has been placed or not
* @author Lucas Bronson
*/
public boolean isPlaced(){ public boolean isPlaced(){
return this.position != null; return this.position != null;
} }

View File

@ -11,9 +11,9 @@ public class ShipButton extends JButton {
private BoardDisplay boardDisplay; private BoardDisplay boardDisplay;
/** /**
* TODO fertig beschreiben * Erstellt Buttons für die beiden Spieler (Module/Schiffe)
* @param ship * @param ship Schiff von welchem der Name genommen wird
* @param boardDisplay * @param boardDisplay Klasse für Interaktion
* @author Lucas Bronson, Luca Conte, Joshua Kuklok * @author Lucas Bronson, Luca Conte, Joshua Kuklok
*/ */
public ShipButton(Ship ship, BoardDisplay boardDisplay) { public ShipButton(Ship ship, BoardDisplay boardDisplay) {

View File

@ -1,17 +1,39 @@
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
/**
* beschreibt ein Package das durch einen AsyncSocket gesendet werden kann nach Netzwerkstandard
* https://github.com/lgc-4/ProgProjekt-Netzwerkstandard
* @author Luca Conte
*/
public class SocketPackage { public class SocketPackage {
private String name = ""; private String name = "";
private String data = ""; private String data = "";
/**
* initialises a socket package by prividing a package name and data
* @param name the name of the package
* @param data the data of the package
* @author Luca Conte
*/
public SocketPackage(String name, String data) { public SocketPackage(String name, String data) {
this.setName(name); this.setName(name);
this.setData(data); this.setData(data);
} }
/**
* initialises an empty socket package
* @author Luca Conte
*/
public SocketPackage() { public SocketPackage() {
this("",""); this("","");
} }
/**
* initialises a socket package from a message
* the message is parsed according to https://github.com/lgc-4/ProgProjekt-Netzwerkstandard
* @param message the message to be parsed
* @author Luca Conte
*/
public SocketPackage(String message) { public SocketPackage(String message) {
if (message.length() <= 0) { if (message.length() <= 0) {
throw new IllegalArgumentException("Socket message cannot be empty."); throw new IllegalArgumentException("Socket message cannot be empty.");
@ -25,24 +47,51 @@ public class SocketPackage {
} }
} }
/**
* sets the package name
* the name is always stored in upper case
* @param name the new name of the package
* @author Luca Conte
*/
public void setName(String name) { public void setName(String name) {
if (name == null) name = ""; if (name == null) name = "";
this.name = name.toUpperCase(); this.name = name.toUpperCase();
} }
/**
* sets the package data
* @param name the new data of the package
* @author Luca Conte
*/
public void setData(String data) { public void setData(String data) {
if (data == null) data = ""; if (data == null) data = "";
this.data = data; this.data = data;
} }
/**
* returns the name of the package
* @return the name of the package
* @author Luca Conte
*/
public String getName() { public String getName() {
return this.name; return this.name;
} }
/**
* returns the data of the package
* @return the data of the package
* @author Luca Conte
*/
public String getData() { public String getData() {
return this.data; return this.data;
} }
/**
* parses the package into a string according to https://github.com/lgc-4/ProgProjekt-Netzwerkstandard
* the package name and data are joined using a space " " `0x20`
* @return the package in string format
* @author Luca Conte
*/
public String toString() { public String toString() {
if (this.data == null || this.data.length() == 0) { if (this.data == null || this.data.length() == 0) {
return this.name; return this.name;
@ -51,6 +100,11 @@ public class SocketPackage {
} }
} }
/**
* returns the data string as a list, split at every space " " `0x20`
* @return the data string as a list, split at every space " " `0x20`
* @author Luca Conte
*/
public List<String> splitData() { public List<String> splitData() {
return Arrays.asList(this.data.split(" ")); return Arrays.asList(this.data.split(" "));
} }

View File

@ -25,7 +25,9 @@ public class SoundHandler {
"hit", "./Sound/hit.mp3", "hit", "./Sound/hit.mp3",
"destroyed", "./Sound/hit.mp3", "destroyed", "./Sound/hit.mp3",
"plop", "./Sound/plop.mp3", "plop", "./Sound/plop.mp3",
"loose", "./Sound/loosescreenWAH.mp3" "loose", "./Sound/loosescreenlaugh.mp3",
"win", "./Sound/win.mp3",
"yourturn", "./Sound/yourturn.mp3"
)); ));
/** /**
@ -67,9 +69,9 @@ public class SoundHandler {
} }
/** /**
* TODO funktion beschreiben (potentiell nicht benötigte Funktion?) * fügt einen neuen Sound zum SoundHanlder hinzu
* @param soundName * @param soundName der intern zu verwendende Name des Sounds
* @param path * @param path der Dateipfad zur Sound Datei
* @author Ole Wachtel * @author Ole Wachtel
*/ */
static void add(String soundName, String path){ static void add(String soundName, String path){
@ -77,8 +79,8 @@ public class SoundHandler {
} }
/** /**
* TODO funktion beschreiben (potentiell nicht benötigte Funktion?) * schaltet den Ton an oder aus
* @param sound * @param sound ob der sound an ist
* @author Ole Wachtel * @author Ole Wachtel
*/ */
static void setSoundOn(boolean sound){ static void setSoundOn(boolean sound){

View File

@ -1,12 +1,13 @@
/** /**
* Diese Klasse implementiert den Einfachsten Ki Spieler. * Diese Klasse implementiert den Einfachsten Ki Spieler.
* @author Florian und Florian * @author Florian Alexy und Florian Hantzschel
* */ * */
public class SpecificAiPlayerEasy extends AiPlayer{ public class SpecificAiPlayerEasy extends AiPlayer{
/** /**
* Bein einfachen Ki Spieler wird nur der AiPlayer initialisiert und der Name gesetzt, * Bein einfachen Ki Spieler wird nur der AiPlayer initialisiert und der Name gesetzt,
* da in der Eltern-Klasse AiPlayer eine default implementierung für alle Methoden existieren. * da in der Eltern-Klasse AiPlayer eine default implementierung für alle Methoden existieren.
* @author Florian Alexy und Florian Hantzschel
*/ */
public SpecificAiPlayerEasy() { public SpecificAiPlayerEasy() {
super(); super();

View File

@ -1,16 +1,16 @@
import java.util.ArrayList;
// import java.util.Random; wird nicht mehr verwendet
/** /**
* Diese Klasse implementiert den Harten Ki Spieler. * Diese Klasse implementiert den Harten Ki Spieler.
* @author Florian und Florian * @author Florian Alexy und Florian Hantzschel
* */ * */
import java.util.ArrayList;
import java.util.Random;
public class SpecificAiPlayerHard extends AiPlayer{ public class SpecificAiPlayerHard extends AiPlayer{
private int gridSize; private int gridSize;
private boolean[][] shotsFired; private boolean[][] shotsFired;
private final ArrayList<Point> hitQueue; private final ArrayList<Point> hitQueue;
private final Random random; //private final Random random; wird nicht mehr verwendet
private int nextChessRow; private int nextChessRow;
private int nextChessCol; private int nextChessCol;
@ -21,10 +21,15 @@ public class SpecificAiPlayerHard extends AiPlayer{
VERTIKAL VERTIKAL
} }
private Orientierung orientierung; private Orientierung orientierung;
private Point firstHit; // Speichert den ersten Treffer zur Bestimmung der Orientierung // Speichert den ersten Treffer zur Bestimmung der Orientierung
private Point firstHit;
/**
* Eltern-Klasse wird initialisiert und alle lokalen variablen,
* die gesetzt werden können, werden initialisiert.
* @author Florian Alexy und Florian Hantzschel
*/
public SpecificAiPlayerHard() { public SpecificAiPlayerHard() {
super(); super();
this.setName("AI Player Hard"); this.setName("AI Player Hard");
@ -32,19 +37,28 @@ public class SpecificAiPlayerHard extends AiPlayer{
this.shotsFired = new boolean[gridSize][gridSize];*/ this.shotsFired = new boolean[gridSize][gridSize];*/
this.gridSize = 0; this.gridSize = 0;
this.hitQueue = new ArrayList<>(); this.hitQueue = new ArrayList<>();
this.random = new Random(); //this.random = new Random(); wird nicht mehr verwendet
this.nextChessRow = 0; this.nextChessRow = 0;
this.nextChessCol = 0; this.nextChessCol = 0;
this.orientierung = Orientierung.UNBEKANNT; this.orientierung = Orientierung.UNBEKANNT;
this.firstHit = null; this.firstHit = null;
} }
// Checks if a position has already been shot at /**
* Prüft, ob auf den punkt schonmal geschossen wurde.
* @param p zu prüfender Punkt
* @return boolean
* @author Florian Alexy und Florian Hantzschel
*/
public boolean alreadyShot(Point p) { public boolean alreadyShot(Point p) {
return shotsFired[p.getX()][p.getY()]; return shotsFired[p.getX()][p.getY()];
} }
// Generates the next move for the AI /**
* Bestimmt den nächsten punkt, der beschossen werden soll.
* @return Position
* @author Florian Alexy und Florian Hantzschel
*/
public Point getNextMove() { public Point getNextMove() {
if(gridSize == 0) { if(gridSize == 0) {
this.gridSize = super.board.getSize(); this.gridSize = super.board.getSize();
@ -73,6 +87,12 @@ public class SpecificAiPlayerHard extends AiPlayer{
return new Point(row, col); return new Point(row, col);
} }
/**
* Nachdem receiveShoot beim gegner den schuss verarbeitet hat,
* wird diese Methode mit der antwort aufgerufen.
* @param hitResponse the hitresponse
* @author Florian Alexy und Florian Hantzschel
*/
@Override @Override
public synchronized void receiveHit(HitResponse hitResponse) { public synchronized void receiveHit(HitResponse hitResponse) {
super.receiveHit(hitResponse); super.receiveHit(hitResponse);
@ -113,6 +133,7 @@ public class SpecificAiPlayerHard extends AiPlayer{
/** /**
* Entfernt aus der hitQueue alle Punkte, die nicht der erkannten Orientierung entsprechen. * Entfernt aus der hitQueue alle Punkte, die nicht der erkannten Orientierung entsprechen.
* @author Florian Alexy und Florian Hantzschel
*/ */
private void cleanUpHitQueue() { private void cleanUpHitQueue() {
if (firstHit == null || this.orientierung == Orientierung.UNBEKANNT) { if (firstHit == null || this.orientierung == Orientierung.UNBEKANNT) {
@ -136,9 +157,10 @@ public class SpecificAiPlayerHard extends AiPlayer{
} }
/** /**
* Fügt benachbarte Felder in der **erkannten Orientierung** hinzu. * Fügt benachbarte Felder in der erkannten Orientierung hinzu.
* - Ist die Orientierung HORIZONTAL, so werden nur links/rechts hinzugefügt. * Ist die Orientierung HORIZONTAL, so werden nur links/rechts hinzugefügt.
* - Ist sie VERTICAL, so werden nur oben/unten hinzugefügt. * Ist sie VERTICAL, so werden nur oben/unten hinzugefügt.
* @author Florian Alexy und Florian Hantzschel
*/ */
private void addPointsByOrientation(Point point) { private void addPointsByOrientation(Point point) {
if (this.orientierung == Orientierung.UNBEKANNT) { if (this.orientierung == Orientierung.UNBEKANNT) {
@ -178,6 +200,7 @@ public class SpecificAiPlayerHard extends AiPlayer{
/** /**
* Diese Methode erweitert die hitsQueue um die umliegenden Punkte die Schiffe seien könnten. * Diese Methode erweitert die hitsQueue um die umliegenden Punkte die Schiffe seien könnten.
* @param point * @param point
* @author Florian Alexy und Florian Hantzschel
*/ */
private void addAdjacentPoints(Point point) { private void addAdjacentPoints(Point point) {
int x = point.getX(); int x = point.getX();
@ -201,6 +224,7 @@ public class SpecificAiPlayerHard extends AiPlayer{
* Die Methode gibt zurück, ob eine Position auf dem Board ist. (Boolean) * Die Methode gibt zurück, ob eine Position auf dem Board ist. (Boolean)
* @param point Punkt der geprüft werden soll * @param point Punkt der geprüft werden soll
* @return Ist auf dem Board oder nicht. * @return Ist auf dem Board oder nicht.
* @author Florian Alexy und Florian Hantzschel
*/ */
private boolean isValidPoint(Point point) { private boolean isValidPoint(Point point) {
return point.getX() >= 0 && point.getX() < gridSize && return point.getX() >= 0 && point.getX() < gridSize &&
@ -208,13 +232,17 @@ public class SpecificAiPlayerHard extends AiPlayer{
} }
/** /**
* Ki Methode um zu schießen. * Ki Methode um zu schießen.
* @author Florian Alexy und Florian Hantzschel
*/ */
@Override @Override
public void aiShoot() { public void aiShoot() {
this.enemy.receiveShoot(getNextMove()); this.enemy.receiveShoot(getNextMove());
} }
// Advances the chess pattern to the next cell /**
* Die Zeilen und spalten variable wird hier angepasst, sodass beim nächsten schuss im Muster geschossen wird.
* @author Florian Alexy und Florian Hantzschel
*/
private void advanceChessPattern() { private void advanceChessPattern() {
nextChessCol += 2; nextChessCol += 2;
if (nextChessCol >= gridSize) { if (nextChessCol >= gridSize) {

View File

@ -1,16 +1,20 @@
/**
* Diese Klasse implementiert den Medium Ki Spieler.
* @author Florian und Florian
* */
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/**
* Diese Klasse implementiert den Medium Ki Spieler.
* @author Florian Alexy und Florian Hantzschel
* */
public class SpecificAiPlayerMedium extends AiPlayer{ public class SpecificAiPlayerMedium extends AiPlayer{
/** /**
* Liste an Punkten die beschossen werden sollen. (Mögliche weitere Segmente vom schiff) * Liste an Punkten die beschossen werden sollen. (Mögliche weitere Segmente vom schiff)
*/ */
private List<Point> hitsQueue = new ArrayList<>(); private List<Point> hitsQueue = new ArrayList<>();
/**
* Eltern-Klasse wird initialisiert und der Name wird gesetzt.
* @author Florian Alexy und Florian Hantzschel
*/
public SpecificAiPlayerMedium() { public SpecificAiPlayerMedium() {
super(); super();
this.setName("AI Player Medium"); this.setName("AI Player Medium");
@ -18,6 +22,7 @@ public class SpecificAiPlayerMedium extends AiPlayer{
/** /**
* Ki Methode um zu schießen. * Ki Methode um zu schießen.
* @author Florian Alexy und Florian Hantzschel
*/ */
@Override @Override
public void aiShoot() { public void aiShoot() {
@ -26,6 +31,12 @@ public class SpecificAiPlayerMedium extends AiPlayer{
enemy.receiveShoot(nextShot); enemy.receiveShoot(nextShot);
} }
/**
* Nachdem receiveShoot beim gegner den schuss verarbeitet hat,
* wird diese Methode mit der antwort aufgerufen.
* @param hitResponse the hitresponse
* @author Florian Alexy und Florian Hantzschel
*/
@Override @Override
public synchronized void receiveHit(HitResponse hitResponse) { public synchronized void receiveHit(HitResponse hitResponse) {
super.receiveHit(hitResponse); super.receiveHit(hitResponse);
@ -37,7 +48,8 @@ public class SpecificAiPlayerMedium extends AiPlayer{
/** /**
* Die Methode bestimmt welche Position als nächstes beschossen werden soll. * Die Methode bestimmt welche Position als nächstes beschossen werden soll.
* @return * @return der Punkt auf den als nächtest geschossen werden soll
* @author Florian Alexy und Florian Hantzschel
*/ */
public Point ComputeNextShot() { public Point ComputeNextShot() {
Point nextShot; Point nextShot;
@ -60,7 +72,8 @@ public class SpecificAiPlayerMedium extends AiPlayer{
/** /**
* Diese Methode erweitert die hitsQueue um die umliegenden Punkte die Schiffe seien könnten. * Diese Methode erweitert die hitsQueue um die umliegenden Punkte die Schiffe seien könnten.
* @param point * @param point der Punkt dessen nachbarn zur hitQueue hinzugefügt werden sollen
* @author Florian Alexy und Florian Hantzschel
*/ */
private void addAdjacentPoints(Point point) { private void addAdjacentPoints(Point point) {
int x = point.getX(); int x = point.getX();
@ -85,6 +98,7 @@ public class SpecificAiPlayerMedium extends AiPlayer{
* Diese Methode gibt zurück, ob eine Position schon beschossen wurde. (Boolean) * Diese Methode gibt zurück, ob eine Position schon beschossen wurde. (Boolean)
* @param p Punkt der geprüft werden soll * @param p Punkt der geprüft werden soll
* @return wurde schon beschossen oder nicht. * @return wurde schon beschossen oder nicht.
* @author Florian Alexy und Florian Hantzschel
*/ */
private boolean alreadyShot(Point p) { private boolean alreadyShot(Point p) {
@ -96,6 +110,7 @@ public class SpecificAiPlayerMedium extends AiPlayer{
* Die Methode gibt zurück, ob eine Position auf dem Board ist. (Boolean) * Die Methode gibt zurück, ob eine Position auf dem Board ist. (Boolean)
* @param point Punkt der geprüft werden soll * @param point Punkt der geprüft werden soll
* @return Ist auf dem Board oder nicht. * @return Ist auf dem Board oder nicht.
* @author Florian Alexy und Florian Hantzschel
*/ */
private boolean isValidPoint(Point point) { private boolean isValidPoint(Point point) {
return point.getX() >= 0 && point.getX() < board.getSize() && return point.getX() >= 0 && point.getX() < board.getSize() &&

View File

@ -7,7 +7,7 @@ import java.awt.*;
*/ */
public class Verbinden extends JPanel{ public class Verbinden extends JPanel{
ImageIcon backButtonIcon = new ImageIcon("graphics/backButton.png"); //ImageIcon backButtonIcon = new ImageIcon("graphics/backButton.png");
JLabel verbindenLabel = new JLabel("Verbinde . . .",SwingConstants.CENTER); JLabel verbindenLabel = new JLabel("Verbinde . . .",SwingConstants.CENTER);

View File

@ -26,7 +26,7 @@ public class WinScreen extends JPanel {
/** /**
* Panel bauen/Objekte hinzufuegen * Panel bauen/Objekte hinzufuegen
* @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden. * @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden.
* @author Lucas Bronson * @author Lucas Bronson, Joshua Kuklok
*/ */
public void buildPanel(MainFrame frame) { public void buildPanel(MainFrame frame) {
Timer timer = new Timer(5, new ActionListener() { Timer timer = new Timer(5, new ActionListener() {
@ -50,13 +50,14 @@ public class WinScreen extends JPanel {
timer.start(); // Timer starten timer.start(); // Timer starten
winLabel.setFont(robotoFont); winLabel.setFont(robotoFont);
winLabel.setHorizontalAlignment(SwingConstants.CENTER); winLabel.setHorizontalAlignment(SwingConstants.CENTER);
//Zurückkehren zum Hauptmenü, wenn okButton gedrückt wird SoundHandler.playSound("win");
// Zurückkehren zum Hauptmenü, wenn okButton gedrückt wird
okButton.addActionListener(new ActionListener() { okButton.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
frame.showPanel("MainMenu"); frame.showPanel("MainMenu");
} }
}); });
add(winLabel); add(winLabel);
add(okButton); add(okButton);

View File

@ -1,39 +0,0 @@
import javax.swing.*;
import java.awt.*;
// TODO Klasse löschen da nicht gebraucht
public class coinToss extends JPanel {
private int reihenfolge = 1; // 1 = Spieler 1 fängt an, 0 = Spieler 2 fängt an
private Timer timer;
private JLabel infoLabel;
// Konstruktor
public coinToss(MainFrame frame) {
setLayout(new BorderLayout());
// Info-Label für den Anzeigetext
infoLabel = new JLabel("", SwingConstants.CENTER);
infoLabel.setFont(new Font("Arial", Font.BOLD, 24));
add(infoLabel, BorderLayout.CENTER);
// Bestimme den Anfangstext basierend auf der "reihenfolge" Variable
if (reihenfolge == 1) {
infoLabel.setText("Du fängst an, mach dich bereit...");
} else {
infoLabel.setText("Dein Gegner fängt an, mach dich bereit...");
}
// Erster Timer, der den Text nach 3 Sekunden auf "Es geht Los!" setzt
/*timer = new Timer(3000, e -> {
infoLabel.setText("Es geht Los!");
// Zweiter Timer, der nach weiteren 3 Sekunden zum Hauptmenü zurückkehrt
Timer backToMenuTimer = new Timer(3000, ev -> {
frame.showPanel("MainMenu");
});
//backToMenuTimer.setRepeats(false); // Timer nur einmal ausführen
backToMenuTimer.start();
});
//timer.setRepeats(false); // Erster Timer soll nur einmal ausgeführt werden
timer.start();*/
}
}

View File

@ -1,4 +1,5 @@
import javax.swing.*; import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.util.HashMap; import java.util.HashMap;
@ -6,13 +7,9 @@ import java.util.HashMap;
/** /**
* Das startLocalGame Panel dient dem Erstellen eines lokalen Spiels. * Das startLocalGame Panel dient dem Erstellen eines lokalen Spiels.
* Hier kann der Benutzer Spieler inklusive Namen und das Semester, in dem sich der Benutzer befindet, einstellen. * Hier kann der Benutzer Spieler inklusive Namen und das Semester, in dem sich der Benutzer befindet, einstellen.
* @author Lucas Bronson, Joshua Kuklok * @author Lucas Bronson, Joshua Kuklok, Luca Conte
*/ */
public class startLocalGame extends JPanel { public class startLocalGame extends JPanel {
// Player
// TODO: entfernen (generell auch test button)
Player p1;
Player p2;
// Funktionshilfen // Funktionshilfen
int semesterCounter = 1; // Semester Counter Label int semesterCounter = 1; // Semester Counter Label
@ -44,12 +41,12 @@ public class startLocalGame extends JPanel {
JButton rightPlayerLeftButton = new JButton("<-"); JButton rightPlayerLeftButton = new JButton("<-");
JButton rightPlayerRightButton = new JButton("->"); JButton rightPlayerRightButton = new JButton("->");
JButton startButton = new JButton("Start!"); JButton startButton = new JButton("Start!");
JButton testButton = new JButton("Test");
// Textfelder // Textfelder
JTextField leftPlayerTextField = new JTextField(20); JTextField leftPlayerTextField = new JTextField(20);
JTextField rightPlayerTextField = new JTextField(20); JTextField rightPlayerTextField = new JTextField(20);
Font robotoFont = new Font("Roboto", Font.BOLD, 45);
/** /**
* Konstruktor der startLocalGame. * Konstruktor der startLocalGame.
* Fügt Buttons, Textfelder und Label hinzu. * Fügt Buttons, Textfelder und Label hinzu.
@ -63,7 +60,8 @@ public class startLocalGame extends JPanel {
setLayout(null); setLayout(null);
// Setze Komponentenpositionen // Setze Komponentenpositionen
frameTitle.setBounds(20, 20, 200, 30); frameTitle.setBounds(20, 20, 500, 60);
frameTitle.setFont(robotoFont.deriveFont(50f));
add(frameTitle); add(frameTitle);
semesterLabel.setBounds(700, 300, 200, 30); semesterLabel.setBounds(700, 300, 200, 30);
@ -81,13 +79,10 @@ public class startLocalGame extends JPanel {
rightPlayerIcon.setBounds(1225, 400, 200, 128); rightPlayerIcon.setBounds(1225, 400, 200, 128);
add(rightPlayerIcon); add(rightPlayerIcon);
semesterCounterLabel.setBounds(725, 475, 50, 50); semesterCounterLabel.setBounds(705, 475, 50, 50);
semesterCounterLabel.setHorizontalAlignment(SwingConstants.CENTER); semesterCounterLabel.setHorizontalAlignment(SwingConstants.CENTER);
add(semesterCounterLabel); add(semesterCounterLabel);
testButton.setBounds(500,800,50,50);
add(testButton);
backButton.setBounds(1380, 20, 80, 80); backButton.setBounds(1380, 20, 80, 80);
add(backButton); add(backButton);
@ -97,10 +92,10 @@ public class startLocalGame extends JPanel {
leftPlayerRightButton.setBounds(250, 450, 50, 50); leftPlayerRightButton.setBounds(250, 450, 50, 50);
add(leftPlayerRightButton); add(leftPlayerRightButton);
semesterUpButton.setBounds(725, 400, 50, 50); semesterUpButton.setBounds(705, 400, 50, 50);
add(semesterUpButton); add(semesterUpButton);
semesterDownButton.setBounds(725, 550, 50, 50); semesterDownButton.setBounds(705, 550, 50, 50);
add(semesterDownButton); add(semesterDownButton);
rightPlayerLeftButton.setBounds(1200, 450, 50, 50); rightPlayerLeftButton.setBounds(1200, 450, 50, 50);
@ -196,14 +191,6 @@ public class startLocalGame extends JPanel {
} }
}); });
// Um zum Gameboard zu wechseln.
testButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
frame.showPanelWin("WinPanel");
}
});
// Um zum startLocalGameLoadingScreen zu wechseln und Daten an Backend weiterzureichen. // Um zum startLocalGameLoadingScreen zu wechseln und Daten an Backend weiterzureichen.
startButton.addActionListener(new ActionListener() { startButton.addActionListener(new ActionListener() {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -216,7 +203,7 @@ public class startLocalGame extends JPanel {
playerClassMap.put(aiPlayerHardIcon, SpecificAiPlayerHard.class); playerClassMap.put(aiPlayerHardIcon, SpecificAiPlayerHard.class);
frame.showPanelSLGLS("startLocalGameLoadingScreen", semesterCounter); //TODO frame.showPanelSLGLS("startLocalGameLoadingScreen", semesterCounter);
Class<? extends LocalPlayer> leftPlayerClass = playerClassMap.get(leftPlayerIcon.getIcon()); Class<? extends LocalPlayer> leftPlayerClass = playerClassMap.get(leftPlayerIcon.getIcon());
Class<? extends AiPlayer> rightPlayerClass = (Class<? extends AiPlayer>) playerClassMap.get(rightPlayerIcon.getIcon()); Class<? extends AiPlayer> rightPlayerClass = (Class<? extends AiPlayer>) playerClassMap.get(rightPlayerIcon.getIcon());
@ -225,41 +212,6 @@ public class startLocalGame extends JPanel {
rightPlayerClass, rightPlayerClass,
GameController.semesterToBoardSize(semesterCounter) GameController.semesterToBoardSize(semesterCounter)
); );
// if (leftPlayerIcon.getIcon() == humanPlayerIcon) {// TODO Wird name wirklich weitergegeben?
// if (rightPlayerIcon.getIcon() == aiPlayerEasyIcon) {
// GameController.startLocalGame(HumanPlayer.class, leftPlayerNickname, SpecificAiPlayerEasy.class, GameController.semesterToBoardSize(semesterCounter));
// } else if (rightPlayerIcon.getIcon() == aiPlayerNormalIcon) {
// GameController.startLocalGame(HumanPlayer.class, leftPlayerNickname, SpecificAiPlayerMedium.class, GameController.semesterToBoardSize(semesterCounter));
// } else if (rightPlayerIcon.getIcon() == aiPlayerHardIcon) {
// GameController.startLocalGame(HumanPlayer.class, leftPlayerNickname, SpecificAiPlayerHard.class, GameController.semesterToBoardSize(semesterCounter));
// }
// } else if (leftPlayerIcon.getIcon() == aiPlayerEasyIcon) {
// if (rightPlayerIcon.getIcon() == aiPlayerEasyIcon) {
// GameController.startLocalGame(SpecificAiPlayerEasy.class, leftPlayerNickname, SpecificAiPlayerEasy.class, GameController.semesterToBoardSize(semesterCounter));
// } else if (rightPlayerIcon.getIcon() == aiPlayerNormalIcon) {
// GameController.startLocalGame(SpecificAiPlayerEasy.class, leftPlayerNickname, SpecificAiPlayerMedium.class, GameController.semesterToBoardSize(semesterCounter));
// } else if (rightPlayerIcon.getIcon() == aiPlayerHardIcon) {
// GameController.startLocalGame(SpecificAiPlayerEasy.class, leftPlayerNickname, SpecificAiPlayerHard.class, GameController.semesterToBoardSize(semesterCounter));
// }
// } else if (rightPlayerIcon.getIcon() == aiPlayerNormalIcon) {
// if (rightPlayerIcon.getIcon() == aiPlayerEasyIcon) {
// GameController.startLocalGame(SpecificAiPlayerMedium.class, leftPlayerNickname, SpecificAiPlayerEasy.class, GameController.semesterToBoardSize(semesterCounter));
// } else if (rightPlayerIcon.getIcon() == aiPlayerNormalIcon) {
// GameController.startLocalGame(SpecificAiPlayerMedium.class, leftPlayerNickname, SpecificAiPlayerMedium.class, GameController.semesterToBoardSize(semesterCounter));
// } else if (rightPlayerIcon.getIcon() == aiPlayerHardIcon) {
// GameController.startLocalGame(SpecificAiPlayerMedium.class, leftPlayerNickname, SpecificAiPlayerHard.class, GameController.semesterToBoardSize(semesterCounter));
// }
// } else if (rightPlayerIcon.getIcon() == aiPlayerHardIcon) {
// if (rightPlayerIcon.getIcon() == aiPlayerEasyIcon) {
// GameController.startLocalGame(SpecificAiPlayerHard.class, leftPlayerNickname, SpecificAiPlayerEasy.class, GameController.semesterToBoardSize(semesterCounter));
// } else if (rightPlayerIcon.getIcon() == aiPlayerNormalIcon) {
// GameController.startLocalGame(SpecificAiPlayerHard.class, leftPlayerNickname, SpecificAiPlayerMedium.class, GameController.semesterToBoardSize(semesterCounter));
// } else if (rightPlayerIcon.getIcon() == aiPlayerHardIcon) {
// GameController.startLocalGame(SpecificAiPlayerHard.class, leftPlayerNickname, SpecificAiPlayerHard.class, GameController.semesterToBoardSize(semesterCounter));
// }
// }
} }
}); });
@ -273,10 +225,13 @@ public class startLocalGame extends JPanel {
private void toggleLeftPlayerIconLeft() { private void toggleLeftPlayerIconLeft() {
if (leftPlayerIcon.getIcon() == humanPlayerIcon) { if (leftPlayerIcon.getIcon() == humanPlayerIcon) {
leftPlayerIcon.setIcon(aiPlayerHardIcon); leftPlayerIcon.setIcon(aiPlayerHardIcon);
} else if (leftPlayerIcon.getIcon() == aiPlayerEasyIcon){ } else if (leftPlayerIcon.getIcon() == aiPlayerEasyIcon){
leftPlayerIcon.setIcon(humanPlayerIcon); leftPlayerIcon.setIcon(humanPlayerIcon);
} else if (leftPlayerIcon.getIcon() == aiPlayerNormalIcon) { } else if (leftPlayerIcon.getIcon() == aiPlayerNormalIcon) {
leftPlayerIcon.setIcon(aiPlayerEasyIcon); leftPlayerIcon.setIcon(aiPlayerEasyIcon);
} else if (leftPlayerIcon.getIcon() == aiPlayerHardIcon) { } else if (leftPlayerIcon.getIcon() == aiPlayerHardIcon) {
leftPlayerIcon.setIcon(aiPlayerNormalIcon); leftPlayerIcon.setIcon(aiPlayerNormalIcon);
} }
@ -289,10 +244,13 @@ public class startLocalGame extends JPanel {
private void toggleLeftPlayerIconRight() { private void toggleLeftPlayerIconRight() {
if (leftPlayerIcon.getIcon() == humanPlayerIcon) { if (leftPlayerIcon.getIcon() == humanPlayerIcon) {
leftPlayerIcon.setIcon(aiPlayerEasyIcon); leftPlayerIcon.setIcon(aiPlayerEasyIcon);
} else if (leftPlayerIcon.getIcon() == aiPlayerEasyIcon){ } else if (leftPlayerIcon.getIcon() == aiPlayerEasyIcon){
leftPlayerIcon.setIcon(aiPlayerNormalIcon); leftPlayerIcon.setIcon(aiPlayerNormalIcon);
} else if (leftPlayerIcon.getIcon() == aiPlayerNormalIcon) { } else if (leftPlayerIcon.getIcon() == aiPlayerNormalIcon) {
leftPlayerIcon.setIcon(aiPlayerHardIcon); leftPlayerIcon.setIcon(aiPlayerHardIcon);
} else if (leftPlayerIcon.getIcon() == aiPlayerHardIcon) { } else if (leftPlayerIcon.getIcon() == aiPlayerHardIcon) {
leftPlayerIcon.setIcon(humanPlayerIcon); leftPlayerIcon.setIcon(humanPlayerIcon);
} }
@ -305,8 +263,10 @@ public class startLocalGame extends JPanel {
private void toggleRightPlayerIconLeft() { private void toggleRightPlayerIconLeft() {
if (rightPlayerIcon.getIcon() == aiPlayerEasyIcon) { if (rightPlayerIcon.getIcon() == aiPlayerEasyIcon) {
rightPlayerIcon.setIcon(aiPlayerHardIcon); rightPlayerIcon.setIcon(aiPlayerHardIcon);
} else if (rightPlayerIcon.getIcon() == aiPlayerNormalIcon){ } else if (rightPlayerIcon.getIcon() == aiPlayerNormalIcon){
rightPlayerIcon.setIcon(aiPlayerEasyIcon); rightPlayerIcon.setIcon(aiPlayerEasyIcon);
} else if (rightPlayerIcon.getIcon() == aiPlayerHardIcon) { } else if (rightPlayerIcon.getIcon() == aiPlayerHardIcon) {
rightPlayerIcon.setIcon(aiPlayerNormalIcon); rightPlayerIcon.setIcon(aiPlayerNormalIcon);
} }
@ -319,8 +279,10 @@ public class startLocalGame extends JPanel {
private void toggleRightPlayerIconRight() { private void toggleRightPlayerIconRight() {
if (rightPlayerIcon.getIcon() == aiPlayerEasyIcon) { if (rightPlayerIcon.getIcon() == aiPlayerEasyIcon) {
rightPlayerIcon.setIcon(aiPlayerNormalIcon); rightPlayerIcon.setIcon(aiPlayerNormalIcon);
} else if (rightPlayerIcon.getIcon() == aiPlayerNormalIcon){ } else if (rightPlayerIcon.getIcon() == aiPlayerNormalIcon){
rightPlayerIcon.setIcon(aiPlayerHardIcon); rightPlayerIcon.setIcon(aiPlayerHardIcon);
} else if (rightPlayerIcon.getIcon() == aiPlayerHardIcon) { } else if (rightPlayerIcon.getIcon() == aiPlayerHardIcon) {
rightPlayerIcon.setIcon(aiPlayerEasyIcon); rightPlayerIcon.setIcon(aiPlayerEasyIcon);
} }
@ -334,10 +296,13 @@ public class startLocalGame extends JPanel {
// Für Linken Spieler // Für Linken Spieler
if (leftPlayerIcon.getIcon() == humanPlayerIcon) { if (leftPlayerIcon.getIcon() == humanPlayerIcon) {
leftPlayerTextField.setText(leftPlayerNickname); leftPlayerTextField.setText(leftPlayerNickname);
} else if (leftPlayerIcon.getIcon() == aiPlayerEasyIcon){ } else if (leftPlayerIcon.getIcon() == aiPlayerEasyIcon){
leftPlayerTextField.setText("Einfach"); leftPlayerTextField.setText("Einfach");
} else if (leftPlayerIcon.getIcon() == aiPlayerNormalIcon) { } else if (leftPlayerIcon.getIcon() == aiPlayerNormalIcon) {
leftPlayerTextField.setText("Mittel"); leftPlayerTextField.setText("Mittel");
} else if (leftPlayerIcon.getIcon() == aiPlayerHardIcon) { } else if (leftPlayerIcon.getIcon() == aiPlayerHardIcon) {
leftPlayerTextField.setText("Schwer"); leftPlayerTextField.setText("Schwer");
} }
@ -345,8 +310,10 @@ public class startLocalGame extends JPanel {
// Für Rechten Spieler // Für Rechten Spieler
if (rightPlayerIcon.getIcon() == aiPlayerEasyIcon){ if (rightPlayerIcon.getIcon() == aiPlayerEasyIcon){
rightPlayerTextField.setText("Einfach"); rightPlayerTextField.setText("Einfach");
} else if (rightPlayerIcon.getIcon() == aiPlayerNormalIcon) { } else if (rightPlayerIcon.getIcon() == aiPlayerNormalIcon) {
rightPlayerTextField.setText("Mittel"); rightPlayerTextField.setText("Mittel");
} else if (rightPlayerIcon.getIcon() == aiPlayerHardIcon) { } else if (rightPlayerIcon.getIcon() == aiPlayerHardIcon) {
rightPlayerTextField.setText("Schwer"); rightPlayerTextField.setText("Schwer");
} }

View File

@ -1,4 +1,5 @@
import javax.swing.*; import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
@ -39,12 +40,14 @@ public class startMultiplayerGame extends JPanel {
// Textfelder // Textfelder
JTextField PlayerTextField = new JTextField(20); JTextField PlayerTextField = new JTextField(20);
Font robotoFont = new Font("Roboto", Font.BOLD, 45);
/** /**
* Konstruktor der startLocalGame. * Konstruktor der startLocalGame.
* Fügt Buttons, Textfelder und Label hinzu. * Fügt Buttons, Textfelder und Label hinzu.
* Fügt ebenfalls ActionListeners hinzu, damit Buttons etc. ihre gewünschte Funktion haben * Fügt ebenfalls ActionListeners hinzu, damit Buttons etc. ihre gewünschte Funktion haben
* @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden. * @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden.
* @author Joshua Kuklok * @author Joshua Kuklok, Lucas Bronson
*/ */
startMultiplayerGame(MainFrame frame) { startMultiplayerGame(MainFrame frame) {
@ -52,7 +55,8 @@ public class startMultiplayerGame extends JPanel {
setLayout(null); setLayout(null);
// Setze Komponentenpositionen // Setze Komponentenpositionen
frameTitle.setBounds(20, 20, 200, 30); frameTitle.setBounds(20, 20, 500, 60);
frameTitle.setFont(robotoFont.deriveFont(50f));
add(frameTitle); add(frameTitle);
semesterLabel.setBounds(700, 300, 200, 30); semesterLabel.setBounds(700, 300, 200, 30);
@ -64,7 +68,7 @@ public class startMultiplayerGame extends JPanel {
PlayerIcon.setBounds(75, 400, 200, 128); PlayerIcon.setBounds(75, 400, 200, 128);
add(PlayerIcon); add(PlayerIcon);
semesterCounterLabel.setBounds(725, 475, 50, 50); // zwischen den Up/Down-Buttons semesterCounterLabel.setBounds(705, 475, 50, 50); // zwischen den Up/Down-Buttons
semesterCounterLabel.setHorizontalAlignment(SwingConstants.CENTER); semesterCounterLabel.setHorizontalAlignment(SwingConstants.CENTER);
add(semesterCounterLabel); add(semesterCounterLabel);
@ -77,10 +81,10 @@ public class startMultiplayerGame extends JPanel {
PlayerRightButton.setBounds(250, 450, 50, 50); PlayerRightButton.setBounds(250, 450, 50, 50);
add(PlayerRightButton); add(PlayerRightButton);
semesterUpButton.setBounds(725, 400, 50, 50); semesterUpButton.setBounds(705, 400, 50, 50);
add(semesterUpButton); add(semesterUpButton);
semesterDownButton.setBounds(725, 550, 50, 50); semesterDownButton.setBounds(705, 550, 50, 50);
add(semesterDownButton); add(semesterDownButton);
joinGameButton.setBounds(1100, 350, 200, 50); joinGameButton.setBounds(1100, 350, 200, 50);
@ -150,13 +154,13 @@ public class startMultiplayerGame extends JPanel {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
if (PlayerIcon.getIcon() == humanPlayerIcon) { if (PlayerIcon.getIcon() == humanPlayerIcon) {
frame.showPanelSMG("JoinGame",1,0, PlayerNickname); frame.showPanelSMG("JoinGame",1,0, PlayerNickname, semesterCounter);
} else if ( PlayerIcon.getIcon() == aiPlayerEasyIcon) { } else if ( PlayerIcon.getIcon() == aiPlayerEasyIcon) {
frame.showPanelSMG("JoinGame",1,1, PlayerNickname); frame.showPanelSMG("JoinGame",1,1, PlayerNickname, semesterCounter);
} else if ( PlayerIcon.getIcon() == aiPlayerNormalIcon) { } else if ( PlayerIcon.getIcon() == aiPlayerNormalIcon) {
frame.showPanelSMG("JoinGame",1,2, PlayerNickname); frame.showPanelSMG("JoinGame",1,2, PlayerNickname, semesterCounter);
} else if ( PlayerIcon.getIcon() == aiPlayerHardIcon) { } else if ( PlayerIcon.getIcon() == aiPlayerHardIcon) {
frame.showPanelSMG("JoinGame",1,3, PlayerNickname); frame.showPanelSMG("JoinGame",1,3, PlayerNickname, semesterCounter);
} }
} }
}); });
@ -167,13 +171,13 @@ public class startMultiplayerGame extends JPanel {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
//Parameter -> panelName, Spiel erstellen oder beitreten (int), Spielertyp(int 0-3), Spielername //Parameter -> panelName, Spiel erstellen oder beitreten (int), Spielertyp(int 0-3), Spielername
if (PlayerIcon.getIcon() == humanPlayerIcon) { if (PlayerIcon.getIcon() == humanPlayerIcon) {
frame.showPanelSMG("JoinGame",0,0, PlayerNickname); frame.showPanelSMG("JoinGame",0,0, PlayerNickname, semesterCounter);
} else if ( PlayerIcon.getIcon() == aiPlayerEasyIcon) { } else if ( PlayerIcon.getIcon() == aiPlayerEasyIcon) {
frame.showPanelSMG("JoinGame",0,1, PlayerNickname); frame.showPanelSMG("JoinGame",0,1, PlayerNickname, semesterCounter);
} else if ( PlayerIcon.getIcon() == aiPlayerNormalIcon) { } else if ( PlayerIcon.getIcon() == aiPlayerNormalIcon) {
frame.showPanelSMG("JoinGame",0,2, PlayerNickname); frame.showPanelSMG("JoinGame",0,2, PlayerNickname, semesterCounter);
} else if ( PlayerIcon.getIcon() == aiPlayerHardIcon) { } else if ( PlayerIcon.getIcon() == aiPlayerHardIcon) {
frame.showPanelSMG("JoinGame",0,3, PlayerNickname); frame.showPanelSMG("JoinGame",0,3, PlayerNickname, semesterCounter);
} }
} }
}); });
@ -188,10 +192,13 @@ public class startMultiplayerGame extends JPanel {
private void togglePlayerIconLeft() { private void togglePlayerIconLeft() {
if (PlayerIcon.getIcon() == humanPlayerIcon) { if (PlayerIcon.getIcon() == humanPlayerIcon) {
PlayerIcon.setIcon(aiPlayerHardIcon); PlayerIcon.setIcon(aiPlayerHardIcon);
} else if (PlayerIcon.getIcon() == aiPlayerEasyIcon){ } else if (PlayerIcon.getIcon() == aiPlayerEasyIcon){
PlayerIcon.setIcon(humanPlayerIcon); PlayerIcon.setIcon(humanPlayerIcon);
} else if (PlayerIcon.getIcon() == aiPlayerNormalIcon) { } else if (PlayerIcon.getIcon() == aiPlayerNormalIcon) {
PlayerIcon.setIcon(aiPlayerEasyIcon); PlayerIcon.setIcon(aiPlayerEasyIcon);
} else if (PlayerIcon.getIcon() == aiPlayerHardIcon) { } else if (PlayerIcon.getIcon() == aiPlayerHardIcon) {
PlayerIcon.setIcon(aiPlayerNormalIcon); PlayerIcon.setIcon(aiPlayerNormalIcon);
} }
@ -204,10 +211,13 @@ public class startMultiplayerGame extends JPanel {
private void togglePlayerIconRight() { private void togglePlayerIconRight() {
if (PlayerIcon.getIcon() == humanPlayerIcon) { if (PlayerIcon.getIcon() == humanPlayerIcon) {
PlayerIcon.setIcon(aiPlayerEasyIcon); PlayerIcon.setIcon(aiPlayerEasyIcon);
} else if (PlayerIcon.getIcon() == aiPlayerEasyIcon){ } else if (PlayerIcon.getIcon() == aiPlayerEasyIcon){
PlayerIcon.setIcon(aiPlayerNormalIcon); PlayerIcon.setIcon(aiPlayerNormalIcon);
} else if (PlayerIcon.getIcon() == aiPlayerNormalIcon) { } else if (PlayerIcon.getIcon() == aiPlayerNormalIcon) {
PlayerIcon.setIcon(aiPlayerHardIcon); PlayerIcon.setIcon(aiPlayerHardIcon);
} else if (PlayerIcon.getIcon() == aiPlayerHardIcon) { } else if (PlayerIcon.getIcon() == aiPlayerHardIcon) {
PlayerIcon.setIcon(humanPlayerIcon); PlayerIcon.setIcon(humanPlayerIcon);
} }
@ -220,10 +230,13 @@ public class startMultiplayerGame extends JPanel {
private void updateTextFields() { private void updateTextFields() {
if (PlayerIcon.getIcon() == humanPlayerIcon) { if (PlayerIcon.getIcon() == humanPlayerIcon) {
PlayerTextField.setText(PlayerNickname); PlayerTextField.setText(PlayerNickname);
} else if (PlayerIcon.getIcon() == aiPlayerEasyIcon){ } else if (PlayerIcon.getIcon() == aiPlayerEasyIcon){
PlayerTextField.setText("Einfach"); PlayerTextField.setText("Einfach");
} else if (PlayerIcon.getIcon() == aiPlayerNormalIcon) { } else if (PlayerIcon.getIcon() == aiPlayerNormalIcon) {
PlayerTextField.setText("Mittel"); PlayerTextField.setText("Mittel");
} else if (PlayerIcon.getIcon() == aiPlayerHardIcon) { } else if (PlayerIcon.getIcon() == aiPlayerHardIcon) {
PlayerTextField.setText("Schwer"); PlayerTextField.setText("Schwer");
} }