diff --git a/src/AiPlayer.java b/src/AiPlayer.java index 2d3ba33..0f75c90 100644 --- a/src/AiPlayer.java +++ b/src/AiPlayer.java @@ -2,7 +2,9 @@ import java.util.Random; public abstract class AiPlayer extends LocalPlayer { - public AiPlayer() {} + public AiPlayer() { + this.setName("AI Player"); + } public Point RandomPoint() { Random random = new Random(); // Pseudo Random für zufallszahlen int posx = random.nextInt(super.board.getSize()); // Generiert 0 - 13 diff --git a/src/BoardDisplay.java b/src/BoardDisplay.java index c9760ad..d7f12c6 100644 --- a/src/BoardDisplay.java +++ b/src/BoardDisplay.java @@ -7,11 +7,25 @@ import java.util.List; /** * TODO Klassenbeschreibung + * reines im frontend zeichnen für preview */ public class BoardDisplay extends JPanel { private JButton[][] fields; private int gridSize; - private List ships; + //private List ships;//brauchen wir nicht mehr + private Ship currentShip; + private Player player; + private boolean vertical = false; + private List shipButtonList; + + public void addShipButton(ShipButton button) { + shipButtonList.add(button); + paintFields(); + } + + public Ship getCurrentShip() { + return currentShip; + } /** * Konstruktor der startLocalGame. @@ -20,14 +34,18 @@ public class BoardDisplay extends JPanel { * @param player */ public BoardDisplay(int gridSize, Player player) { - super(new GridLayout(gridSize + 1, gridSize + 1)); // +1 wegen extra Zeile/Splate + super(new GridLayout(gridSize + 1, gridSize + 1)); // +1 wegen extra Zeile/Spalte this.fields = new JButton[gridSize][gridSize]; - this.ships = new ArrayList<>(); + //this.ships = new ArrayList<>(); + this.shipButtonList = new ArrayList<>(); + this.player = player; + this.gridSize = gridSize; + System.out.println("Name in Boarddisplay: " + player.getName());//Testausgabe // Erstellung von Spielfeld for (int i = 0; i <= gridSize; i++) { for (int j = 0; j <= gridSize; j++) { - final int x = i; // Temporäre Variable - final int y = j; // Temporäre Variable + final int x = i - 1; // Temporäre Variable + final int y = j - 1; // Temporäre Variable if (i == 0 && j == 0) { add(new JLabel(" ")); } else if (i == 0) { @@ -43,7 +61,7 @@ public class BoardDisplay extends JPanel { } else { // Spielfeld (interaktive Zellen) JButton field = new JButton(""); - field.setBackground(Color.LIGHT_GRAY); + field.setBackground(Color.BLUE); field.setOpaque(true); field.setBorderPainted(true); fields[i - 1][j - 1] = field; @@ -61,23 +79,38 @@ public class BoardDisplay extends JPanel { // field.setBackground(Color.LIGHT_GRAY); // } // }); - int finalI = i; - int finalJ = j; field.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - Point o= new Point(finalI, finalJ); - System.out.println(o); - handleFieldClick(field, o,player); + if (SwingUtilities.isRightMouseButton(e)) { + togglePlacementDirection(); // Ausrichtung ändern + } else if (SwingUtilities.isLeftMouseButton(e)) { + Point o = new Point(x, y); + currentShip.setHorizontal(vertical); + handleFieldClick(o); // Linksklick -> Schiff platzieren + } } }); } } } - // this.ships = new ArrayList(); + } + public void selectCurrentShip(Ship ship) { + this.currentShip = ship; + paintFields(); + } + + public void resetAllShips() { + //ships.clear(); + this.currentShip = null; + for (Ship ship : player.getBoard().getShips()) { + ship.resetPosition(); + } + paintFields(); + } /** * TODO Funktion beschreiben etc. * @param ship @@ -86,31 +119,6 @@ public class BoardDisplay extends JPanel { * @param player * @return */ - private boolean setShip(Ship ship, Point o, boolean horizontal,Player player) { - //boolean a = true; - if (placeable(ship, ship.getPosition(), horizontal)) { - ship.setPosition(new Point(o.getX(),o.getY()),player.getBoard().getShips(),gridSize); - ship.setHorizontal(horizontal); - ships.add(ship); - List occupied = ship.getOccupiedPoints(); - for(Point p: occupied) { - fields[p.getX()][p.getY()].setBackground(Color.LIGHT_GRAY); - } - return true; - }else{ - return false; - } - } - - /*private boolean placeable(Ship ship,Point o, boolean horizontal) { - if (horizontal && (o.getX() + ship.getSize() > gridSize)) { // Fehler - return false; - } - if (!horizontal && (o.getY() + ship.getSize() > gridSize)) { - return false; - } - return true; - }*/ /** * TODO Funktion beschreiben etc. @@ -119,43 +127,63 @@ public class BoardDisplay extends JPanel { * @param horizontal * @return */ - private boolean placeable(Ship ship, Point o, boolean horizontal) { - if (horizontal && (o.getX() + ship.getSize() > gridSize)) { - return false; - } - if (!horizontal && (o.getY() + ship.getSize() > gridSize)) { - return false; - } - // Prüfen auf Kollision mit bestehenden Schiffen - for (Ship other : ships) { - for (Point p : other.getOccupiedPoints()) { - for (Point newP : ship.getOccupiedPoints()) { - if (p.equals(newP)) { - return false; // Überschneidung gefunden + /** + * Wechselt die Platzierungsrichtung zwischen horizontal und vertikal. + */ + private void togglePlacementDirection() { + vertical = !vertical; + String direction = vertical ? "vertikal" : "horizontal"; + System.out.println("Platzierungsrichtung geändert zu: " + direction); + } + + /** + * Handhabt das Platzieren eines Schiffs auf dem Spielfeld. + * @param o Die Koordinaten des Klicks. + */ + private void handleFieldClick(Point o) { + if (!this.currentShip.setPosition(o,player.getBoard().getShips(),this.gridSize)) { + } + paintFields(); + //if(this.currentShip.isPlaced()){ + // this.currentShip. + // }; + // Beispiel: Setze ein Schiff bei einem Klick + //if (setShip(new Ship(3, "TestShip"), o, true,player)) { + // field.setBackground(Color.BLUE); // Visualisiere Schiff + //} + } + + public void paintFields() { + for(int i = 0; i < gridSize; i++) { + for(int j = 0; j < gridSize; j++) { + if(fields[i][j] == null) { + continue; + } + fields[i][j].setBackground(Color.BLUE); + for(Ship ship: player.getBoard().getShips()) { + if(ship.isShipOnPos(new Point(i,j))) { + fields[i][j].setBackground(Color.LIGHT_GRAY); + break; } } } } - - return true; - } - - - private void selectShip(MouseEvent e) { - Ship current = (Ship) e.getSource(); - } - - /** - * TODO Funktion beschreiben etc. - * @param field - * @param o - * @param player - */ - private void handleFieldClick(JButton field, Point o,Player player) { - // Beispiel: Setze ein Schiff bei einem Klick - if (setShip(new Ship(3, "TestShip"), o, true,player)) { - field.setBackground(Color.BLUE); // Visualisiere Schiff + for( ShipButton shipButton: shipButtonList) { + shipButton.refreshButtonState(); } } + + private void previewShipPlacement(int startX, int startY, boolean vertical) { + //TODO schreiben + } + + private void clearPreview() { + + } + + public void refresh() { + paintFields(); + } + } \ No newline at end of file diff --git a/src/GameBoard.java b/src/GameBoard.java index 3ed0619..0f22fa7 100644 --- a/src/GameBoard.java +++ b/src/GameBoard.java @@ -13,6 +13,14 @@ import java.util.List; * Der Benutzer kann hier seine Schiffe platzieren, das Spiel starten etc. */ public class GameBoard extends JPanel { + + private BoardDisplay ownBoardPanel; + private BoardDisplay opponentBoardPanel; + + private Player p1; + private Player p2; + + // Funktionshilfen //int semesterCounter = 1; //TODO: ersetzen durch param von vorpanel @@ -21,10 +29,19 @@ public class GameBoard extends JPanel { ImageIcon gameBoardEmtpy = new ImageIcon("graphics/gameboardempty.png"); ImageIcon gameBoardX = new ImageIcon("graphics/gameboardx.png"); + // kontextText Text-Strings + String kT1 = "Bitte Schiffe setzten"; + String kT2 = "Warte auf Gegner"; + String kT3 = "Du fängst an"; + String kT4 = "Dein Gegner fängt an"; + String kT5 = "Du bist am Zug"; + String kT6 = "Dein Gegner ist am Zug"; + String kT7 = "Du hast das Spiel gewonnen"; + String kT8 = "Du hast das Spiel verloren"; + // Labels JLabel frameTitle = new JLabel("GameBoard"); - JLabel kontextText = new JLabel("Beispielhafter Kontext-Text"); - //kontextText.setFont(new Font("Roboto", Font.BOLD, 24)); //TODO setFont fixen + JLabel kontextText = new JLabel(kT1); JButton backButton = new JButton(backButtonIcon); // Eigene ModulButtons @@ -37,36 +54,11 @@ public class GameBoard extends JPanel { * @param p2 Zweites Spielerobjekt */ GameBoard(MainFrame frame, int semesterCounter,Player p1, Player p2) { - JToggleButton leftPlayerModul1 = new JToggleButton("Modul 1"); //TODO: Dynamische Namen durch abgleich mit Semester - JToggleButton leftPlayerModul2 = new JToggleButton("Modul 2"); - JToggleButton leftPlayerModul3 = new JToggleButton("Modul 3"); - JToggleButton leftPlayerModul4 = new JToggleButton("Modul 4"); - JToggleButton leftPlayerModul5 = new JToggleButton("Modul 5"); - JToggleButton leftPlayerModul6 = new JToggleButton("Modul 6"); - JToggleButton leftPlayerModul7 = new JToggleButton("Reset"); - - JToggleButton[] leftPlayerButtons=new JToggleButton[]{ - leftPlayerModul1, leftPlayerModul2, leftPlayerModul3, leftPlayerModul4, - leftPlayerModul5, leftPlayerModul6, leftPlayerModul7, - }; - - // Gegnerische ModulButtons - JToggleButton rightPlayerModul1 = new JToggleButton("Modul 1"); - JToggleButton rightPlayerModul2 = new JToggleButton("Modul 2"); - JToggleButton rightPlayerModul3 = new JToggleButton("Modul 3"); - JToggleButton rightPlayerModul4 = new JToggleButton("Modul 4"); - JToggleButton rightPlayerModul5 = new JToggleButton("Modul 5"); - JToggleButton rightPlayerModul6 = new JToggleButton("Modul 6"); - JToggleButton rightPlayerModul7 = new JToggleButton("Bereit"); - - JToggleButton[] rightlayerButtons=new JToggleButton[]{ - rightPlayerModul1, rightPlayerModul2, rightPlayerModul3, rightPlayerModul4, - rightPlayerModul5, rightPlayerModul6, rightPlayerModul7, - }; - - buildPanel(frame, semesterCounter,p1,p2,leftPlayerButtons,rightlayerButtons); + this.p1 = p1; + this.p2 = p2; + buildPanel(frame, semesterCounter); List shipsP1 =p1.getBoard().getShips(); - updateButtonLabels(shipsP1,leftPlayerButtons); + List shipsP2 =p2.getBoard().getShips(); backButton.addActionListener(e -> frame.showPanel("MainMenu")); } @@ -82,73 +74,106 @@ public class GameBoard extends JPanel { } } + // Timer für pulsierenden Effekt + Timer timer = new Timer(10, new ActionListener() { + private int grayValue = 50; // Start-Grauwert (0 = Schwarz, 255 = Weiß) + private boolean increasing = false; // Richtung des Pulsierens + + @Override + public void actionPerformed(ActionEvent e) { + // Grauwert aktualisieren + kontextText.setForeground(new Color(grayValue, grayValue, grayValue)); + + // Grauwert erhöhen oder verringern + if (increasing) { + grayValue++; + if (grayValue >= 90) { + increasing = false; // Richtung ändern + } + } else { + grayValue--; + if (grayValue <= 0) { + increasing = true; // Richtung ändern + } + } + } + }); + /** * TODO Funktion beschreiben etc. * @param frame * @param semesterCounter - * @param p1 - * @param p2 - * @param leftButtons - * @param rightButtons */ - public void buildPanel(MainFrame frame, int semesterCounter,Player p1,Player p2,JToggleButton[] leftButtons,JToggleButton[] rightButtons) { + public void buildPanel(MainFrame frame, int semesterCounter) { // Hauptlayout - BorderLayout für die Anordnung der Komponenten setLayout(new BorderLayout()); + // Spielfelder erstellen (eigenes und gegnerisches) + // Spielfelder werden in BoardDisplay erstellt + int gridSize = GameController.semesterToBoardSize(semesterCounter); // Größe des Spielfelds + this.ownBoardPanel = new BoardDisplay(gridSize,p1); + this.opponentBoardPanel = new BoardDisplay(gridSize, p2); + // Panel für das Kontext-Text-Feld JPanel headerPanel = new JPanel(); headerPanel.setLayout(new BorderLayout()); headerPanel.add(kontextText, BorderLayout.WEST); + kontextText.setFont(new Font("Roboto", Font.BOLD, 30)); //TODO setFont fixen headerPanel.add(backButton, BorderLayout.EAST); - // Panel für die Buttons des linken Spielers (ganz links) JPanel leftButtonsPanel = new JPanel(); leftButtonsPanel.setLayout(new GridLayout(7, 1)); // 6 Buttons untereinander - leftButtonsPanel.add(leftButtons[0]); - leftButtonsPanel.add(leftButtons[1]); - leftButtonsPanel.add(leftButtons[2]); - leftButtonsPanel.add(leftButtons[3]); - leftButtonsPanel.add(leftButtons[4]); - leftButtonsPanel.add(leftButtons[5]); - leftButtonsPanel.add(leftButtons[6]); - // Panel für die Buttons des rechten Spielers (ganz rechts) JPanel rightButtonsPanel = new JPanel(); - rightButtonsPanel.setLayout(new GridLayout(7, 1)); // 6 Buttons untereinander - rightButtonsPanel.add(rightButtons[0]); - rightButtonsPanel.add(rightButtons[1]); - rightButtonsPanel.add(rightButtons[2]); - rightButtonsPanel.add(rightButtons[3]); - rightButtonsPanel.add(rightButtons[4]); - rightButtonsPanel.add(rightButtons[5]); - rightButtonsPanel.add(rightButtons[6]); - - // Spielfelder erstellen (eigenes und gegnerisches) - int gridSize = GameController.semesterToBoardSize(semesterCounter); // Größe des Spielfelds - // Spielfelder werden in BoardDisplay erstellt - //JPanel ownBoardPanel = new JPanel(new GridLayout(gridSize, gridSize)); - //JPanel opponentBoardPanel = new JPanel(new GridLayout(gridSize, gridSize)); - JPanel ownBoardPanel = new BoardDisplay(gridSize,p1); - JPanel opponentBoardPanel = new BoardDisplay(gridSize, p2); + rightButtonsPanel.setLayout(new GridLayout(7, 1)); //Buttons in eine Gruppe packen damit diese beim drücken eines anderen Buttons wieder entwählt werden ButtonGroup leftButtonGroup= new ButtonGroup(); - leftButtonGroup.add(leftButtons[0]); - leftButtonGroup.add(leftButtons[1]); - leftButtonGroup.add(leftButtons[2]); - leftButtonGroup.add(leftButtons[3]); - leftButtonGroup.add(leftButtons[4]); - leftButtonGroup.add(leftButtons[5]); - leftButtonGroup.add(leftButtons[6]); ButtonGroup rightButtonGroup= new ButtonGroup(); - rightButtonGroup.add(rightButtons[0]); - rightButtonGroup.add(rightButtons[1]); - rightButtonGroup.add(rightButtons[2]); - rightButtonGroup.add(rightButtons[3]); - rightButtonGroup.add(rightButtons[4]); - rightButtonGroup.add(rightButtons[5]); - rightButtonGroup.add(rightButtons[6]); + + // Panel für die Buttons des linken Spielers (ganz links) + for(Ship ship : p1.getBoard().getShips()) { + ShipButton shipButton= new ShipButton(ship,ownBoardPanel); + leftButtonsPanel.add(shipButton); + leftButtonGroup.add(shipButton); + ownBoardPanel.addShipButton(shipButton); + } + + for(Ship ship : p2.getBoard().getShips()) { + ShipButton shipButton= new ShipButton(ship,opponentBoardPanel); + rightButtonsPanel.add(shipButton); + rightButtonGroup.add(shipButton); + opponentBoardPanel.addShipButton(shipButton); + shipButton.setEnabled(false); + } + + JToggleButton readyButton = new JToggleButton("Bereit"); + readyButton.setBackground(Color.GREEN); + rightButtonsPanel.add(readyButton); + + JToggleButton resetButton = new JToggleButton("Reset"); + resetButton.setBackground(Color.RED); + leftButtonsPanel.add(resetButton); + + resetButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + ownBoardPanel.resetAllShips(); + } + }); + + readyButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + kontextText.setText(kT2); + p1.ready(); + } + }); + // Panel für die Buttons des rechten Spielers (ganz rechts) + + //JPanel ownBoardPanel = new JPanel(new GridLayout(gridSize, gridSize)); + //JPanel opponentBoardPanel = new JPanel(new GridLayout(gridSize, gridSize)); // Panel für beide Spielfelder (nebeneinander in der Mitte) JPanel centerPanel = new JPanel(); @@ -156,11 +181,42 @@ public class GameBoard extends JPanel { centerPanel.add(ownBoardPanel); centerPanel.add(opponentBoardPanel); + // Spieler-Namen über den Spielfeldern hinzufügen + JPanel playerNamesPanel = new JPanel(); + playerNamesPanel.setLayout(new GridLayout(1, 2)); // Zwei Labels nebeneinander + JLabel player1NameLabel = new JLabel(p1.getName(), SwingConstants.CENTER); + JLabel player2NameLabel = new JLabel(p2.getName(), SwingConstants.CENTER); + System.out.println("Name in Gameboard: " + player1NameLabel.getText()); + + // Schrift und Formatierung der Labels + player1NameLabel.setFont(new Font("Roboto", Font.BOLD, 18)); + player2NameLabel.setFont(new Font("Roboto", Font.BOLD, 18)); + + // Spieler-Labels zum Panel hinzufügen + playerNamesPanel.add(player1NameLabel); + playerNamesPanel.add(player2NameLabel); + + // Spieler-Namen-Panel oberhalb der Spielfelder hinzufügen + JPanel namesAndBoardsPanel = new JPanel(new BorderLayout()); + namesAndBoardsPanel.add(playerNamesPanel, BorderLayout.NORTH); + namesAndBoardsPanel.add(centerPanel, BorderLayout.CENTER); + // Panels dem Hauptlayout hinzufügen add(leftButtonsPanel, BorderLayout.WEST); add(rightButtonsPanel, BorderLayout.EAST); add(headerPanel, BorderLayout.NORTH); - add(centerPanel, BorderLayout.CENTER); + //add(centerPanel, BorderLayout.CENTER); + add(namesAndBoardsPanel, BorderLayout.CENTER); + timer.start(); + } + public void refresh() { + if (this.p1.myTurn) { + this.kontextText.setText(kT5); + } else { + this.kontextText.setText(kT6); + } + this.ownBoardPanel.refresh(); + this.opponentBoardPanel.refresh(); } } diff --git a/src/GameController.java b/src/GameController.java index 5353fdd..f76b7f7 100644 --- a/src/GameController.java +++ b/src/GameController.java @@ -166,6 +166,8 @@ public class GameController { localPlayer.setEnemy(aiPlayer); aiPlayer.setEnemy(localPlayer); + localPlayer.setName(localPlayerName); + startGameWithInstancedPlayers(localPlayer, aiPlayer, size); } diff --git a/src/LocalPlayer.java b/src/LocalPlayer.java index 5bc6dd9..2b67b44 100644 --- a/src/LocalPlayer.java +++ b/src/LocalPlayer.java @@ -38,21 +38,24 @@ public class LocalPlayer extends Player { @Override public synchronized void receiveCoin(boolean coin) { - if (!this.haseReceivedCoin) { - boolean result = coin ^ this.myCoin; // XOR - this.myTurn = result == this.isServer; - this.haseReceivedCoin = true; + if (!this.hasReceivedCoin) { + this.hasReceivedCoin = true; + this.determineCoinToss(); } } - public void sendCoin() { - enemy.receiveCoin(this.myCoin); - } - @Override public void shoot(Point point){ this.myTurn = false; enemy.receiveShoot(point); } + + @Override + public synchronized void ready() { + for (Ship ship : this.board.getShips()) { + if (!ship.isPlaced()) return; + } + super.ready(); + } } \ No newline at end of file diff --git a/src/MainFrame.java b/src/MainFrame.java index 75b27ba..02db6b1 100644 --- a/src/MainFrame.java +++ b/src/MainFrame.java @@ -1,6 +1,8 @@ import javax.swing.*; import java.awt.*; +//TODO Generell button ausblenden anpassen + /** * Der MainFrame dient als Hub und Übergreifendes Fenster auf dem alle weiteren Panel angezeigt werden. * Dadurch werden keine weiteren Fenster geöffnet. @@ -19,6 +21,7 @@ public class MainFrame extends JFrame { // Von startLocalGameLoadingScreen an GameBoard int semesterCounter; // ---------- // + private GameBoard gameBoard; /** * Konstruktor von MainFrame. @@ -93,7 +96,7 @@ public class MainFrame extends JFrame { public void showPanelSLG(String panelName,int semesterCounter, Player p1, Player p2) { this.semesterCounter = semesterCounter; - GameBoard gameBoard = new GameBoard(this, semesterCounter, p1, p2); + this.gameBoard = new GameBoard(this, semesterCounter, p1, p2); mainPanel.add(gameBoard, panelName); mainPanel.revalidate(); mainPanel.repaint(); @@ -114,4 +117,8 @@ public class MainFrame extends JFrame { mainPanel.repaint(); cardLayout.show(mainPanel, panelName); // Show the panel } + + public void refreshGameBoard() { + this.gameBoard.refresh(); + } } \ No newline at end of file diff --git a/src/OnlinePlayer.java b/src/OnlinePlayer.java index 3634c1f..14f3edb 100644 --- a/src/OnlinePlayer.java +++ b/src/OnlinePlayer.java @@ -7,6 +7,7 @@ public abstract class OnlinePlayer extends Player implements AsyncSocketListener public OnlinePlayer(Integer size, AsyncSocket socket) { this.socket = socket; this.wantedBoardSize = size; + this.myCoin = null; socket.setHandler(this); //TODO Auto-generated constructor stub } diff --git a/src/OnlinePlayer_1_1_0.java b/src/OnlinePlayer_1_1_0.java index 31fe50d..a9b513d 100644 --- a/src/OnlinePlayer_1_1_0.java +++ b/src/OnlinePlayer_1_1_0.java @@ -33,8 +33,8 @@ public class OnlinePlayer_1_1_0 extends OnlinePlayer { case "COIN": if(!this.hasReceivedCoinPackage && (p.getData().equals("1") || p.getData().equals("0"))){ - this.myCoin = p.getData().equals("1"); - enemy.receiveCoin(this.myCoin); + this.myCoin = p.getData().equals("1"); + this.ready(); this.hasReceivedCoinPackage = true; } break; @@ -85,9 +85,10 @@ public class OnlinePlayer_1_1_0 extends OnlinePlayer { @Override public synchronized void receiveCoin(boolean coin) { - if (!this.haseReceivedCoin) { + if (!this.hasReceivedCoin) { super.socket.send(new SocketPackage("COIN", String.valueOf(coin ? 1 : 0))); - this.haseReceivedCoin = true; + this.hasReceivedCoin = true; + this.determineCoinToss(); } } diff --git a/src/Player.java b/src/Player.java index 8b6f6f1..7595594 100644 --- a/src/Player.java +++ b/src/Player.java @@ -1,21 +1,21 @@ -import java.util.Random; - public abstract class Player { protected boolean myTurn; protected boolean isServer; protected boolean waitingForResponse; - protected Player enemy; + protected Player enemy; protected String name; protected Board board; - protected boolean myCoin; + protected Boolean myCoin; - protected boolean sendCoin; + protected boolean sentCoin; - protected boolean haseReceivedCoin; + protected boolean hasReceivedCoin; public Player() { - this.haseReceivedCoin = false; - this.sendCoin = false; + this.setName("Player"); + this.hasReceivedCoin = false; + this.sentCoin = false; + this.myTurn = false; } public void createBoard(int size) { @@ -28,8 +28,8 @@ public abstract class Player { public abstract void shoot(Point point); - public void beginTrun() { - + public void beginTurn() { + System.out.println("issa my turn-a"); } public void setEnemy(Player enemy) { @@ -47,5 +47,23 @@ public abstract class Player { return this.board; } + public void ready() { + this.enemy.receiveCoin(this.myCoin); + this.sentCoin = true; + if (hasReceivedCoin) { + this.determineCoinToss(); + } + }; + + protected void determineCoinToss() { + if (!this.sentCoin || this.myCoin == null || !this.hasReceivedCoin || this.enemy.myCoin == null) return; + boolean result = this.enemy.myCoin ^ this.myCoin; // XOR + this.myTurn = result == this.isServer; + if (this.myTurn) { + this.beginTurn(); + } + GameController.getMainFrame().refreshGameBoard(); + } + public abstract void receiveCoin(boolean coin); } diff --git a/src/Point.java b/src/Point.java index bf2b127..d47d401 100644 --- a/src/Point.java +++ b/src/Point.java @@ -42,4 +42,18 @@ public class Point { public static boolean isValidSyntax(String str) { return str.matches("^[A-Z]\\d+$"); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || this.getClass() != o.getClass()) return false; + + Point p = (Point)o; + return p.getX() == this.getX() && p.getY() == this.getY(); + } + + public boolean neighbours(Point other) { + if (other == null) return false; + return (int)Math.abs(this.getX() - other.getX()) <= 1 && (int)Math.abs(this.getY() - other.getY()) <= 1; + } } diff --git a/src/Ship.java b/src/Ship.java index 3be924b..5dfac8c 100644 --- a/src/Ship.java +++ b/src/Ship.java @@ -61,8 +61,21 @@ public class Ship { this.sunk = false; } - public boolean setPosition(Point pos, List shipsList, int boardSize) { - // ueberpruefe boundaries + public void resetPosition() { + this.position = null; + } + + public boolean setPosition(Point pos, boolean horizontal, List shipsList, int boardSize) { + if (!this.checkValidPlacement(pos, horizontal, shipsList, boardSize)) return false; + + // kein ueberlappen also setze das Schiff + this.position = pos; + this.horizontal = horizontal; + return true; + } + + public boolean checkValidPlacement(Point pos, boolean horizontal, List shipsList, int boardSize) { + // ueberpruefe boundaries if (pos.getX() < 0 || pos.getY() < 0 || pos.getX() >= boardSize || pos.getY() >= boardSize) { return false; } @@ -71,7 +84,7 @@ public class Ship { int endX = pos.getX(); int endY = pos.getY(); - if (this.horizontal) { // rechts links + if (horizontal) { // rechts links endX = pos.getX() + this.size - 1; if (endX >= boardSize) { return false; @@ -86,8 +99,8 @@ public class Ship { // Liste an Punkten die das Schiff einnehmen wuerde List shipPoints = new ArrayList<>(); for (int i = 0; i < this.size; i++) { - int x = this.horizontal ? pos.getX() + i : pos.getX(); //falls horizontal dann pos.x + i ansonsten pos.x - int y = this.horizontal ? pos.getY() : pos.getY() + i; + int x = horizontal ? pos.getX() + i : pos.getX(); //falls horizontal dann pos.x + i ansonsten pos.x + int y = horizontal ? pos.getY() : pos.getY() + i; shipPoints.add(new Point(x, y)); } @@ -105,15 +118,11 @@ public class Ship { List otherShipPoints = otherShip.getOccupiedPoints(); // ueberlappen checken for (Point p : shipPoints) { - if (otherShipPoints.contains(p)) { - // ueberlappen entdeckt - return false; - } + for (Point otherPoint : otherShipPoints) { + if (otherPoint.neighbours(p)) return false; + } } } - - // kein ueberlappen also setze das Schiff - this.position = pos; return true; } @@ -135,6 +144,9 @@ public class Ship { } public boolean isShipOnPos(Point pos){ + if(this.position == null){ + return false; + } if ((this.horizontal && pos.getY() == this.position.getY() && pos.getX() >= this.position.getX() && pos.getX() < this.position.getX() + size) || (!(this.horizontal) && pos.getX() == this.position.getX() && pos.getY() >= this.position.getY() && pos.getY() < this.position.getY() + size)) { return true; @@ -170,4 +182,9 @@ public class Ship { public String getName() { return name; } + + //potentiell falsch neu + public boolean isPlaced(){ + return this.position != null; + } } diff --git a/src/ShipButton.java b/src/ShipButton.java new file mode 100644 index 0000000..e282676 --- /dev/null +++ b/src/ShipButton.java @@ -0,0 +1,26 @@ +import javax.swing.*; +import java.awt.*; + +public class ShipButton extends JButton { + private Ship ship; + private BoardDisplay boardDisplay; + public ShipButton(Ship ship, BoardDisplay boardDisplay) { + super(ship.getName()); + this.ship = ship; + this.boardDisplay = boardDisplay; + this.addActionListener((e)->{ + boardDisplay.selectCurrentShip(this.ship); + }); + } + + public void refreshButtonState() { + if(ship.isPlaced()) { + setBackground(Color.LIGHT_GRAY); + } else { + setBackground(Color.WHITE); + } + if(boardDisplay.getCurrentShip() == ship) { + setBackground(Color.CYAN); + } + } +} diff --git a/src/SpecificAiPlayerMedium.java b/src/SpecificAiPlayerMedium.java index 81561b2..ea1ddfb 100644 --- a/src/SpecificAiPlayerMedium.java +++ b/src/SpecificAiPlayerMedium.java @@ -5,6 +5,10 @@ public class SpecificAiPlayerMedium extends AiPlayer{ private List hitsQueue = new ArrayList<>(); + public SpecificAiPlayerMedium() { + this.setName("AI Player Medium"); + } + @Override public void AiShoot() { Point nextShot = ComputeNextShot();