diff --git a/Sound/loosescreenWAH.mp3 b/Sound/loosescreenWAH.mp3 deleted file mode 100644 index 25c2f25..0000000 Binary files a/Sound/loosescreenWAH.mp3 and /dev/null differ diff --git a/Sound/loosescreenlaugh.mp3 b/Sound/loosescreenlaugh.mp3 new file mode 100644 index 0000000..213a6c0 Binary files /dev/null and b/Sound/loosescreenlaugh.mp3 differ diff --git a/Sound/win.mp3 b/Sound/win.mp3 new file mode 100644 index 0000000..84e80db Binary files /dev/null and b/Sound/win.mp3 differ diff --git a/Sound/yourturn.mp3 b/Sound/yourturn.mp3 new file mode 100644 index 0000000..728bbda Binary files /dev/null and b/Sound/yourturn.mp3 differ diff --git a/graphics/backButton.png b/graphics/backButton.png index 92c9647..2b1a5e9 100644 Binary files a/graphics/backButton.png and b/graphics/backButton.png differ diff --git a/src/AsyncSocket.java b/src/AsyncSocket.java index 506309f..1937afb 100644 --- a/src/AsyncSocket.java +++ b/src/AsyncSocket.java @@ -225,7 +225,10 @@ public class AsyncSocket { try { this.socket.close(); - if (this.checkerThread != null) this.checkerThread.join(); + if (this.checkerThread != null) { + this.checkerThread.interrupt(); + this.checkerThread.join(); + } } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { diff --git a/src/Board.java b/src/Board.java index f045d8b..9a6ac92 100644 --- a/src/Board.java +++ b/src/Board.java @@ -2,7 +2,7 @@ * Diese Klasse ist das Board von eimem spieler und enthält alle logischen operationen. * Sprich ist das Backend Board. * - * @author Peer Ole Wachtel + * @author Peer Ole Wachtel, Florian Alexy und Florian Hantzschel */ import java.util.ArrayList; @@ -31,7 +31,7 @@ public class Board { * setzt die übergebene Spielfeldgröße. * Erstellt die Liste aller Schiffe des Semesters * @param size Die größe des Spielfeldes - * @author Peer Ole Wachtel + * @author Peer Ole Wachtel, Florian Alexy und Florian Hantzschel */ public Board(int size) { this.size = size; @@ -97,7 +97,7 @@ public class Board { * @author Peer Ole Wachtel */ private void createShip(int semester){ - List shipData = Ship.semeterList.get(semester -1); + List shipData = Ship.semeterList.get(semester-1); for (int i = 0; i < shipData.size(); i++) { this.ships.add(new Ship(shipData.get(i).size(), shipData.get(i).name())); } diff --git a/src/BoardDisplay.java b/src/BoardDisplay.java index 608a11f..f8542d7 100644 --- a/src/BoardDisplay.java +++ b/src/BoardDisplay.java @@ -21,7 +21,7 @@ public class BoardDisplay extends JPanel { /** * 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 */ public void addShipButton(ShipButton button) { @@ -31,8 +31,8 @@ public class BoardDisplay extends JPanel { /** * Gibt currentShip zurück - * @return currentShip - * @author Lucas Bronson, Luca Conte, Joshua Kuklok + * @return currentShip Objekt der Klasse Schiff + * @author Lucas Bronson Luca Conte */ public Ship getCurrentShip() { return currentShip; @@ -55,8 +55,8 @@ public class BoardDisplay extends JPanel { // Erstellung vom Spielfeld for (int i = 0; i <= gridSize; i++) { for (int j = 0; j <= gridSize; j++) { - final int x = j - 1; // Temporäre Variable - final int y = i - 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 für überspringen von Rahmenzeile-/spalte if (i == 0 && j == 0) { add(new JLabel(" ")); } else if (i == 0) { @@ -67,7 +67,7 @@ public class BoardDisplay extends JPanel { } else if (j == 0) { JLabel rowLabel = new JLabel(String.valueOf((char) ('A' + i - 1))); rowLabel.setHorizontalAlignment(SwingConstants.CENTER); - rowLabel.setFont(new Font("Arial", Font.BOLD, 14)); + rowLabel.setFont(new Font("Roboto", Font.BOLD, 14)); add(rowLabel); } else { // Spielfeld (interaktive Zellen) @@ -211,7 +211,7 @@ public class BoardDisplay extends JPanel { } for(Ship ship: player.getBoard().getShips()) { 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)); diff --git a/src/GameBoard.java b/src/GameBoard.java index 0eaa8d3..1370b1c 100644 --- a/src/GameBoard.java +++ b/src/GameBoard.java @@ -40,6 +40,7 @@ public class GameBoard extends JPanel { // Buttons JButton giveUpButton = new JButton("Aufgeben"); + /** * Konstruktor von GameBoard. * @param frame Der Mainframe der Anwendung über den alle Panels angezeigt werden. @@ -55,12 +56,9 @@ public class GameBoard extends JPanel { List shipsP1 =p1.getBoard().getShips(); List shipsP2 =p2.getBoard().getShips(); - giveUpButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - // TODO Hier könnte Ihr Backend Code stehen - frame.showPanel("MainMenu"); - } + giveUpButton.addActionListener((e) -> { + frame.showPanel("MainMenu"); + p1.withdraw(); }); } @@ -108,7 +106,7 @@ public class GameBoard extends JPanel { JPanel headerPanel = new JPanel(); headerPanel.setLayout(new BorderLayout()); 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); JPanel leftButtonsPanel = new JPanel(); @@ -136,7 +134,6 @@ public class GameBoard extends JPanel { opponentBoardPanel.addShipButton(shipButton); shipButton.setEnabled(false); } - JToggleButton readyButton = new JToggleButton("Bereit"); readyButton.setBackground(Color.GREEN); rightButtonsPanel.add(readyButton); @@ -151,7 +148,7 @@ public class GameBoard extends JPanel { 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 readyButton.addActionListener(new ActionListener() { @Override @@ -159,6 +156,10 @@ public class GameBoard extends JPanel { kontextText.setText(kT2); p1.ready(); if(true) { + remove(readyButton); + remove(resetButton); + remove(rightButtonsPanel); + remove(leftButtonsPanel); readyButton.setEnabled(false); resetButton.setEnabled(false); } @@ -201,11 +202,14 @@ public class GameBoard extends JPanel { /** * Aktualisiert Zustand(kontextText) je nach Zug - * @author Luca Conte + * @author Luca Conte, Joshua Kuklok */ public void refresh() { if (this.p1.myTurn) { - this.kontextText.setText(kT5); + if (!kontextText.getText().equals(kT5)) { + this.kontextText.setText(kT5); + SoundHandler.playSound("yourturn"); + } } else { this.kontextText.setText(kT6); } diff --git a/src/HalloSchiffeVersenken.java b/src/HalloSchiffeVersenken.java index ca25a89..7eaa176 100644 --- a/src/HalloSchiffeVersenken.java +++ b/src/HalloSchiffeVersenken.java @@ -13,14 +13,4 @@ public class HalloSchiffeVersenken { MainFrame mf = new MainFrame(); 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) -*/ \ No newline at end of file +} \ No newline at end of file diff --git a/src/HumanPlayer.java b/src/HumanPlayer.java index 6f00dbe..36203ec 100644 --- a/src/HumanPlayer.java +++ b/src/HumanPlayer.java @@ -9,7 +9,6 @@ public class HumanPlayer extends LocalPlayer { @Override public void shoot(Point point) { if (!this.myTurn) return; - this.myTurn = false; enemy.receiveShoot(point); } } diff --git a/src/JoinGame.java b/src/JoinGame.java index 2cc484d..98e2b8c 100644 --- a/src/JoinGame.java +++ b/src/JoinGame.java @@ -12,6 +12,9 @@ import java.net.InetSocketAddress; */ public class JoinGame extends JPanel { + // Funktionshilfen + String standardPort = "51525"; + // Grafiken ImageIcon backButtonIcon = new ImageIcon("graphics/backButton.png"); @@ -39,9 +42,9 @@ public class JoinGame extends JPanel { * @param playerName Name des Spielers * @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); - 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 * @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){ spielBeitretenLabel= new JLabel("Spiel beitreten"); }else{ @@ -71,6 +75,7 @@ public class JoinGame extends JPanel { } portTextField.setBounds(50, 225, 250, 50); + portTextField.setText(standardPort); spielBeitretenLabel.setFont(robotoFont.deriveFont(50f)); @@ -100,6 +105,7 @@ public class JoinGame extends JPanel { if (ipAddress.isEmpty()) { ipAddress = "0.0.0.0"; } + System.out.println(portTextField.getText()); String portText = portTextField.getText(); int port = Integer.parseInt(portText); @@ -109,13 +115,13 @@ public class JoinGame extends JPanel { try { 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) { - GameController.startOnlineGame(SpecificAiPlayerEasy.class, playerName, address,GameController.semesterToBoardSize(2)); + GameController.startOnlineGame(SpecificAiPlayerEasy.class, playerName, address,GameController.semesterToBoardSize(semesterCounter)); } 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) { - GameController.startOnlineGame(SpecificAiPlayerHard.class, playerName, address,GameController.semesterToBoardSize(2)); + GameController.startOnlineGame(SpecificAiPlayerHard.class, playerName, address,GameController.semesterToBoardSize(semesterCounter)); } } catch (IOException ex) { throw new RuntimeException(ex); diff --git a/src/LocalPlayer.java b/src/LocalPlayer.java index 31b40f5..70d3cef 100644 --- a/src/LocalPlayer.java +++ b/src/LocalPlayer.java @@ -20,7 +20,11 @@ public class LocalPlayer extends Player { */ @Override public synchronized void receiveShoot(Point point) { - if (!this.enemy.myTurn) return; + 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); if (!(hitResponse == null)){ @@ -34,7 +38,7 @@ public class LocalPlayer extends Player { switch (hitResponse.getType()) { case HIT, SUNK -> this.myTurn = false; case MISS -> this.myTurn = true; - case VICTORY -> GameController.getMainFrame().showPanelLoose("", this); //TODO Was halt bei victory passiert ist hier wurder verloheren + case VICTORY -> this.lose(); } GameController.getMainFrame().refreshGameBoard(); } @@ -50,7 +54,7 @@ public class LocalPlayer extends Player { switch (hitResponse.getType()) { case HIT, SUNK -> this.myTurn = true; case MISS -> this.myTurn = false; - case VICTORY -> GameController.getMainFrame().showPanelWin("", this); // TODO was halt beim victory passier ist hier wurde gewonnen + case VICTORY -> this.win(); } GameController.getMainFrame().refreshGameBoard(); } @@ -91,4 +95,4 @@ public class LocalPlayer extends Player { super.ready(); } -} \ No newline at end of file +} diff --git a/src/LooseScreen.java b/src/LooseScreen.java deleted file mode 100644 index 28d105f..0000000 --- a/src/LooseScreen.java +++ /dev/null @@ -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); - } -} diff --git a/src/LoseScreen.java b/src/LoseScreen.java new file mode 100644 index 0000000..dffa8f2 --- /dev/null +++ b/src/LoseScreen.java @@ -0,0 +1,47 @@ +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 + */ +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); + } +} diff --git a/src/MainFrame.java b/src/MainFrame.java index e384f92..edef294 100644 --- a/src/MainFrame.java +++ b/src/MainFrame.java @@ -45,14 +45,12 @@ public class MainFrame extends JFrame { MainMenuView mainMenuView = new MainMenuView(this); startLocalGame localGame = new startLocalGame(this); startMultiplayerGame multiplayerGame = new startMultiplayerGame(this); - coinToss coinToss = new coinToss(this); Verbinden verbinden = new Verbinden(this); // Panels hinzufügen mainPanel.add(mainMenuView, "MainMenu"); mainPanel.add(localGame, "LocalGame"); mainPanel.add(multiplayerGame, "MultiplayerGame"); - mainPanel.add(coinToss, "coinToss"); mainPanel.add(verbinden, "Verbinden"); // mainPanel.add(winLooseScreen, "WinLooseScreen"); @@ -80,10 +78,10 @@ public class MainFrame extends JFrame { * @param playerName Name des Spielers * @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; - JoinGame joinGame = new JoinGame(this, localMult, playerType, playerName); + JoinGame joinGame = new JoinGame(this, localMult, playerType, playerName, semesterCounter); mainPanel.add(joinGame, panelName); mainPanel.revalidate(); mainPanel.repaint(); @@ -134,6 +132,12 @@ public class MainFrame extends JFrame { if(player != gameBoard.getP1()){ return; } + + this.gameBoard.getP1().destroy(); + this.gameBoard.getP2().destroy(); + this.gameBoard.removeAll(); + this.gameBoard = null; + WinScreen winScreen = new WinScreen(this); mainPanel.add(winScreen, panelName); mainPanel.revalidate(); @@ -147,13 +151,17 @@ public class MainFrame extends JFrame { * @param player Player von dem die funktion aufgerufen worden ist * @author Lucas Bronson, Peer Ole Wachtel */ - public void showPanelLoose(String panelName, Player player){ + public void showPanelLose(String panelName, Player player){ if(player != gameBoard.getP1()){ return; } + this.gameBoard.getP1().destroy(); this.gameBoard.getP2().destroy(); - LooseScreen looseScreen = new LooseScreen(this); + this.gameBoard.removeAll(); + this.gameBoard = null; + + LoseScreen looseScreen = new LoseScreen(this); mainPanel.add(looseScreen,panelName); mainPanel.revalidate(); mainPanel.repaint(); @@ -170,4 +178,4 @@ public class MainFrame extends JFrame { } this.gameBoard.refresh(); } -} \ No newline at end of file +} diff --git a/src/OnlinePlayer.java b/src/OnlinePlayer.java index 2db0a90..486a48d 100644 --- a/src/OnlinePlayer.java +++ b/src/OnlinePlayer.java @@ -22,12 +22,6 @@ public abstract class OnlinePlayer extends Player implements AsyncSocketListener public abstract void receive(String message); - @Override - public abstract void receiveShoot(Point point); - - @Override - public abstract void receiveHit(HitResponse hitResponse); - @Override public abstract void receiveCoin(boolean coin); diff --git a/src/OnlinePlayer_1_1_0.java b/src/OnlinePlayer_1_1_0.java index b401a6e..2ba932a 100644 --- a/src/OnlinePlayer_1_1_0.java +++ b/src/OnlinePlayer_1_1_0.java @@ -10,7 +10,7 @@ public class OnlinePlayer_1_1_0 extends OnlinePlayer { * 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 + * @author Peer Ole Wachtel, Luca Conte, Florian Hantzschel */ @Override public void receive(String message) { @@ -58,7 +58,23 @@ public class OnlinePlayer_1_1_0 extends OnlinePlayer { Point point = new Point(data.get(0)); int typeIndex = Integer.parseInt(data.get(1)); 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; @@ -67,6 +83,10 @@ public class OnlinePlayer_1_1_0 extends OnlinePlayer { //TODO CHAT break; + case "WITHDRAW": + this.withdraw(); + break; + default: //nichts passier da Paket ungültig break; @@ -102,6 +122,18 @@ public class OnlinePlayer_1_1_0 extends OnlinePlayer { */ @Override 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())); } @@ -125,4 +157,10 @@ public class OnlinePlayer_1_1_0 extends OnlinePlayer { // SHOULD NEVER BE CALLED ON ONLINE PLAYER. ONLY ON HUMAN PLAYER return; } -} \ No newline at end of file + + @Override + public void receiveWithdraw() { + this.socket.send(new SocketPackage("WITHDRAW")); + super.receiveWithdraw(); + } +} diff --git a/src/Player.java b/src/Player.java index 840c4cc..92cddab 100644 --- a/src/Player.java +++ b/src/Player.java @@ -138,6 +138,7 @@ public abstract class Player { * and players * * This method should be called at the end of a game + * This method should be called at the end of a game * * @author Luca Conte */ @@ -147,4 +148,20 @@ public abstract class Player { this.board = null; this.enemy = null; } + + public void win() { + GameController.getMainFrame().showPanelWin("", this); + } + public void lose() { + GameController.getMainFrame().showPanelLose("", this); + } + + public void withdraw() { + this.enemy.receiveWithdraw(); + this.lose(); + } + + public void receiveWithdraw(){ + this.win(); + } } diff --git a/src/ShipButton.java b/src/ShipButton.java index dcf4983..4df8417 100644 --- a/src/ShipButton.java +++ b/src/ShipButton.java @@ -11,9 +11,9 @@ public class ShipButton extends JButton { private BoardDisplay boardDisplay; /** - * TODO fertig beschreiben - * @param ship - * @param boardDisplay + * Erstellt Buttons für die beiden Spieler (Module/Schiffe) + * @param ship Schiff von welchem der Name genommen wird + * @param boardDisplay Klasse für Interaktion * @author Lucas Bronson, Luca Conte, Joshua Kuklok */ public ShipButton(Ship ship, BoardDisplay boardDisplay) { diff --git a/src/SoundHandler.java b/src/SoundHandler.java index 41fed75..900bd41 100644 --- a/src/SoundHandler.java +++ b/src/SoundHandler.java @@ -25,7 +25,9 @@ public class SoundHandler { "hit", "./Sound/hit.mp3", "destroyed", "./Sound/hit.mp3", "plop", "./Sound/plop.mp3", - "loose", "./Sound/loosescreenWAH.mp3" + "loose", "./Sound/loosescreenlaugh.mp3", + "win", "./Sound/win.mp3", + "yourturn", "./Sound/yourturn.mp3" )); /** diff --git a/src/SpecificAiPlayerEasy.java b/src/SpecificAiPlayerEasy.java index a499e81..6be23bb 100644 --- a/src/SpecificAiPlayerEasy.java +++ b/src/SpecificAiPlayerEasy.java @@ -1,12 +1,13 @@ /** * Diese Klasse implementiert den Einfachsten Ki Spieler. - * @author Florian und Florian + * @author Florian Alexy und Florian Hantzschel * */ public class SpecificAiPlayerEasy extends AiPlayer{ /** * 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. + * @author Florian Alexy und Florian Hantzschel */ public SpecificAiPlayerEasy() { super(); diff --git a/src/SpecificAiPlayerHard.java b/src/SpecificAiPlayerHard.java index 067af48..292bf6d 100644 --- a/src/SpecificAiPlayerHard.java +++ b/src/SpecificAiPlayerHard.java @@ -1,16 +1,16 @@ /** * 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; +// import java.util.Random; wird nicht mehr verwendet public class SpecificAiPlayerHard extends AiPlayer{ private int gridSize; private boolean[][] shotsFired; private final ArrayList hitQueue; - private final Random random; + //private final Random random; wird nicht mehr verwendet private int nextChessRow; private int nextChessCol; @@ -24,7 +24,11 @@ public class SpecificAiPlayerHard extends AiPlayer{ private Point firstHit; // Speichert den ersten Treffer zur Bestimmung der Orientierung - + /** + * Eltern-Klasse wird initialisiert und alle lokalen variablen, + * die gesetzt werden können, werden initialisiert. + * @author Florian Alexy und Florian Hantzschel + */ public SpecificAiPlayerHard() { super(); this.setName("AI Player Hard"); @@ -32,19 +36,28 @@ public class SpecificAiPlayerHard extends AiPlayer{ this.shotsFired = new boolean[gridSize][gridSize];*/ this.gridSize = 0; this.hitQueue = new ArrayList<>(); - this.random = new Random(); + //this.random = new Random(); wird nicht mehr verwendet this.nextChessRow = 0; this.nextChessCol = 0; this.orientierung = Orientierung.UNBEKANNT; 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) { 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() { if(gridSize == 0) { this.gridSize = super.board.getSize(); @@ -73,6 +86,12 @@ public class SpecificAiPlayerHard extends AiPlayer{ 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 public synchronized void receiveHit(HitResponse hitResponse) { super.receiveHit(hitResponse); @@ -113,6 +132,7 @@ public class SpecificAiPlayerHard extends AiPlayer{ /** * Entfernt aus der hitQueue alle Punkte, die nicht der erkannten Orientierung entsprechen. + * @author Florian Alexy und Florian Hantzschel */ private void cleanUpHitQueue() { if (firstHit == null || this.orientierung == Orientierung.UNBEKANNT) { @@ -136,9 +156,10 @@ public class SpecificAiPlayerHard extends AiPlayer{ } /** - * Fügt benachbarte Felder in der **erkannten Orientierung** hinzu. - * - Ist die Orientierung HORIZONTAL, so werden nur links/rechts hinzugefügt. - * - Ist sie VERTICAL, so werden nur oben/unten hinzugefügt. + * Fügt benachbarte Felder in der erkannten Orientierung hinzu. + * Ist die Orientierung HORIZONTAL, so werden nur links/rechts hinzugefügt. + * Ist sie VERTICAL, so werden nur oben/unten hinzugefügt. + * @author Florian Alexy und Florian Hantzschel */ private void addPointsByOrientation(Point point) { if (this.orientierung == Orientierung.UNBEKANNT) { @@ -178,6 +199,7 @@ public class SpecificAiPlayerHard extends AiPlayer{ /** * Diese Methode erweitert die hitsQueue um die umliegenden Punkte die Schiffe seien könnten. * @param point + * @author Florian Alexy und Florian Hantzschel */ private void addAdjacentPoints(Point point) { int x = point.getX(); @@ -201,6 +223,7 @@ public class SpecificAiPlayerHard extends AiPlayer{ * Die Methode gibt zurück, ob eine Position auf dem Board ist. (Boolean) * @param point Punkt der geprüft werden soll * @return Ist auf dem Board oder nicht. + * @author Florian Alexy und Florian Hantzschel */ private boolean isValidPoint(Point point) { return point.getX() >= 0 && point.getX() < gridSize && @@ -208,13 +231,17 @@ public class SpecificAiPlayerHard extends AiPlayer{ } /** * Ki Methode um zu schießen. + * @author Florian Alexy und Florian Hantzschel */ @Override public void aiShoot() { 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() { nextChessCol += 2; if (nextChessCol >= gridSize) { diff --git a/src/SpecificAiPlayerMedium.java b/src/SpecificAiPlayerMedium.java index a27390a..aa2c6ca 100644 --- a/src/SpecificAiPlayerMedium.java +++ b/src/SpecificAiPlayerMedium.java @@ -1,6 +1,6 @@ /** * Diese Klasse implementiert den Medium Ki Spieler. - * @author Florian und Florian + * @author Florian Alexy und Florian Hantzschel * */ import java.util.ArrayList; import java.util.List; @@ -11,6 +11,10 @@ public class SpecificAiPlayerMedium extends AiPlayer{ */ private List hitsQueue = new ArrayList<>(); + /** + * Eltern-Klasse wird initialisiert und der Name wird gesetzt. + * @author Florian Alexy und Florian Hantzschel + */ public SpecificAiPlayerMedium() { super(); this.setName("AI Player Medium"); @@ -18,6 +22,7 @@ public class SpecificAiPlayerMedium extends AiPlayer{ /** * Ki Methode um zu schießen. + * @author Florian Alexy und Florian Hantzschel */ @Override public void aiShoot() { @@ -25,7 +30,13 @@ public class SpecificAiPlayerMedium extends AiPlayer{ // Shoot at the enemy and receive the hit response 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 public synchronized void receiveHit(HitResponse hitResponse) { super.receiveHit(hitResponse); @@ -38,6 +49,7 @@ public class SpecificAiPlayerMedium extends AiPlayer{ /** * Die Methode bestimmt welche Position als nächstes beschossen werden soll. * @return + * @author Florian Alexy und Florian Hantzschel */ public Point ComputeNextShot() { Point nextShot; @@ -61,6 +73,7 @@ public class SpecificAiPlayerMedium extends AiPlayer{ /** * Diese Methode erweitert die hitsQueue um die umliegenden Punkte die Schiffe seien könnten. * @param point + * @author Florian Alexy und Florian Hantzschel */ private void addAdjacentPoints(Point point) { 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) * @param p Punkt der geprüft werden soll * @return wurde schon beschossen oder nicht. + * @author Florian Alexy und Florian Hantzschel */ 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) * @param point Punkt der geprüft werden soll * @return Ist auf dem Board oder nicht. + * @author Florian Alexy und Florian Hantzschel */ private boolean isValidPoint(Point point) { return point.getX() >= 0 && point.getX() < board.getSize() && diff --git a/src/Verbinden.java b/src/Verbinden.java index 3e8cdbe..94ed9a1 100644 --- a/src/Verbinden.java +++ b/src/Verbinden.java @@ -7,7 +7,7 @@ import java.awt.*; */ 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); diff --git a/src/WinScreen.java b/src/WinScreen.java index f97dbe5..179800c 100644 --- a/src/WinScreen.java +++ b/src/WinScreen.java @@ -26,7 +26,7 @@ public class WinScreen extends JPanel { /** * Panel bauen/Objekte hinzufuegen * @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) { Timer timer = new Timer(5, new ActionListener() { @@ -50,13 +50,14 @@ public class WinScreen extends JPanel { timer.start(); // Timer starten winLabel.setFont(robotoFont); 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() { @Override public void actionPerformed(ActionEvent e) { frame.showPanel("MainMenu"); } - }); add(winLabel); add(okButton); diff --git a/src/coinToss.java b/src/coinToss.java deleted file mode 100644 index ef3dafe..0000000 --- a/src/coinToss.java +++ /dev/null @@ -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();*/ - } -} diff --git a/src/startLocalGame.java b/src/startLocalGame.java index 1af1fa1..81a47db 100644 --- a/src/startLocalGame.java +++ b/src/startLocalGame.java @@ -1,4 +1,5 @@ import javax.swing.*; +import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.HashMap; @@ -6,13 +7,9 @@ import java.util.HashMap; /** * 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. - * @author Lucas Bronson, Joshua Kuklok + * @author Lucas Bronson, Joshua Kuklok, Luca Conte */ public class startLocalGame extends JPanel { - // Player - // TODO: entfernen (generell auch test button) - Player p1; - Player p2; // Funktionshilfen int semesterCounter = 1; // Semester Counter Label @@ -44,12 +41,12 @@ public class startLocalGame extends JPanel { JButton rightPlayerLeftButton = new JButton("<-"); JButton rightPlayerRightButton = new JButton("->"); JButton startButton = new JButton("Start!"); - JButton testButton = new JButton("Test"); // Textfelder JTextField leftPlayerTextField = new JTextField(20); JTextField rightPlayerTextField = new JTextField(20); + Font robotoFont = new Font("Roboto", Font.BOLD, 45); /** * Konstruktor der startLocalGame. * Fügt Buttons, Textfelder und Label hinzu. @@ -63,7 +60,8 @@ public class startLocalGame extends JPanel { setLayout(null); // Setze Komponentenpositionen - frameTitle.setBounds(20, 20, 200, 30); + frameTitle.setBounds(20, 20, 500, 60); + frameTitle.setFont(robotoFont.deriveFont(50f)); add(frameTitle); semesterLabel.setBounds(700, 300, 200, 30); @@ -81,13 +79,10 @@ public class startLocalGame extends JPanel { rightPlayerIcon.setBounds(1225, 400, 200, 128); add(rightPlayerIcon); - semesterCounterLabel.setBounds(725, 475, 50, 50); + semesterCounterLabel.setBounds(705, 475, 50, 50); semesterCounterLabel.setHorizontalAlignment(SwingConstants.CENTER); add(semesterCounterLabel); - testButton.setBounds(500,800,50,50); - add(testButton); - backButton.setBounds(1380, 20, 80, 80); add(backButton); @@ -97,10 +92,10 @@ public class startLocalGame extends JPanel { leftPlayerRightButton.setBounds(250, 450, 50, 50); add(leftPlayerRightButton); - semesterUpButton.setBounds(725, 400, 50, 50); + semesterUpButton.setBounds(705, 400, 50, 50); add(semesterUpButton); - semesterDownButton.setBounds(725, 550, 50, 50); + semesterDownButton.setBounds(705, 550, 50, 50); add(semesterDownButton); 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. startButton.addActionListener(new ActionListener() { @SuppressWarnings("unchecked") @@ -216,7 +203,7 @@ public class startLocalGame extends JPanel { playerClassMap.put(aiPlayerHardIcon, SpecificAiPlayerHard.class); - frame.showPanelSLGLS("startLocalGameLoadingScreen", semesterCounter); //TODO + frame.showPanelSLGLS("startLocalGameLoadingScreen", semesterCounter); Class leftPlayerClass = playerClassMap.get(leftPlayerIcon.getIcon()); Class rightPlayerClass = (Class) playerClassMap.get(rightPlayerIcon.getIcon()); @@ -225,41 +212,6 @@ public class startLocalGame extends JPanel { rightPlayerClass, 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)); - // } - // } - } }); diff --git a/src/startMultiplayerGame.java b/src/startMultiplayerGame.java index dcb6530..cd10369 100644 --- a/src/startMultiplayerGame.java +++ b/src/startMultiplayerGame.java @@ -1,4 +1,5 @@ import javax.swing.*; +import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -39,12 +40,14 @@ public class startMultiplayerGame extends JPanel { // Textfelder JTextField PlayerTextField = new JTextField(20); + Font robotoFont = new Font("Roboto", Font.BOLD, 45); + /** * Konstruktor der startLocalGame. * Fügt Buttons, Textfelder und Label hinzu. * 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. - * @author Joshua Kuklok + * @author Joshua Kuklok, Lucas Bronson */ startMultiplayerGame(MainFrame frame) { @@ -52,7 +55,8 @@ public class startMultiplayerGame extends JPanel { setLayout(null); // Setze Komponentenpositionen - frameTitle.setBounds(20, 20, 200, 30); + frameTitle.setBounds(20, 20, 500, 60); + frameTitle.setFont(robotoFont.deriveFont(50f)); add(frameTitle); semesterLabel.setBounds(700, 300, 200, 30); @@ -64,7 +68,7 @@ public class startMultiplayerGame extends JPanel { PlayerIcon.setBounds(75, 400, 200, 128); 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); add(semesterCounterLabel); @@ -77,10 +81,10 @@ public class startMultiplayerGame extends JPanel { PlayerRightButton.setBounds(250, 450, 50, 50); add(PlayerRightButton); - semesterUpButton.setBounds(725, 400, 50, 50); + semesterUpButton.setBounds(705, 400, 50, 50); add(semesterUpButton); - semesterDownButton.setBounds(725, 550, 50, 50); + semesterDownButton.setBounds(705, 550, 50, 50); add(semesterDownButton); joinGameButton.setBounds(1100, 350, 200, 50); @@ -150,13 +154,13 @@ public class startMultiplayerGame extends JPanel { @Override public void actionPerformed(ActionEvent e) { if (PlayerIcon.getIcon() == humanPlayerIcon) { - frame.showPanelSMG("JoinGame",1,0, PlayerNickname); + frame.showPanelSMG("JoinGame",1,0, PlayerNickname, semesterCounter); } else if ( PlayerIcon.getIcon() == aiPlayerEasyIcon) { - frame.showPanelSMG("JoinGame",1,1, PlayerNickname); + frame.showPanelSMG("JoinGame",1,1, PlayerNickname, semesterCounter); } else if ( PlayerIcon.getIcon() == aiPlayerNormalIcon) { - frame.showPanelSMG("JoinGame",1,2, PlayerNickname); + frame.showPanelSMG("JoinGame",1,2, PlayerNickname, semesterCounter); } 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) { //Parameter -> panelName, Spiel erstellen oder beitreten (int), Spielertyp(int 0-3), Spielername if (PlayerIcon.getIcon() == humanPlayerIcon) { - frame.showPanelSMG("JoinGame",0,0, PlayerNickname); + frame.showPanelSMG("JoinGame",0,0, PlayerNickname, semesterCounter); } else if ( PlayerIcon.getIcon() == aiPlayerEasyIcon) { - frame.showPanelSMG("JoinGame",0,1, PlayerNickname); + frame.showPanelSMG("JoinGame",0,1, PlayerNickname, semesterCounter); } else if ( PlayerIcon.getIcon() == aiPlayerNormalIcon) { - frame.showPanelSMG("JoinGame",0,2, PlayerNickname); + frame.showPanelSMG("JoinGame",0,2, PlayerNickname, semesterCounter); } else if ( PlayerIcon.getIcon() == aiPlayerHardIcon) { - frame.showPanelSMG("JoinGame",0,3, PlayerNickname); + frame.showPanelSMG("JoinGame",0,3, PlayerNickname, semesterCounter); } } });