lucasjoshua #14

Merged
lgc merged 13 commits from lucasjoshua into main 2024-12-15 13:27:15 +00:00
13 changed files with 360 additions and 181 deletions

View File

@ -2,7 +2,9 @@ import java.util.Random;
public abstract class AiPlayer extends LocalPlayer { public abstract class AiPlayer extends LocalPlayer {
public AiPlayer() {} public AiPlayer() {
this.setName("AI Player");
}
public Point RandomPoint() { public Point RandomPoint() {
Random random = new Random(); // Pseudo Random für zufallszahlen Random random = new Random(); // Pseudo Random für zufallszahlen
int posx = random.nextInt(super.board.getSize()); // Generiert 0 - 13 int posx = random.nextInt(super.board.getSize()); // Generiert 0 - 13

View File

@ -7,11 +7,25 @@ import java.util.List;
/** /**
* TODO Klassenbeschreibung * TODO Klassenbeschreibung
* reines im frontend zeichnen für preview
*/ */
public class BoardDisplay extends JPanel { public class BoardDisplay extends JPanel {
private JButton[][] fields; private JButton[][] fields;
private int gridSize; private int gridSize;
private List <Ship> ships; //private List <Ship> ships;//brauchen wir nicht mehr
private Ship currentShip;
private Player player;
private boolean vertical = false;
private List<ShipButton> shipButtonList;
public void addShipButton(ShipButton button) {
shipButtonList.add(button);
paintFields();
}
public Ship getCurrentShip() {
return currentShip;
}
/** /**
* Konstruktor der startLocalGame. * Konstruktor der startLocalGame.
@ -20,14 +34,18 @@ public class BoardDisplay extends JPanel {
* @param player * @param player
*/ */
public BoardDisplay(int gridSize, Player player) { public BoardDisplay(int gridSize, Player player) {
super(new GridLayout(gridSize + 1, gridSize + 1)); // +1 wegen extra Zeile/Splate super(new GridLayout(gridSize + 1, gridSize + 1)); // +1 wegen extra Zeile/Spalte
this.fields = new JButton[gridSize][gridSize]; 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 // Erstellung von Spielfeld
for (int i = 0; i <= gridSize; i++) { for (int i = 0; i <= gridSize; i++) {
for (int j = 0; j <= gridSize; j++) { for (int j = 0; j <= gridSize; j++) {
final int x = i; // Temporäre Variable final int x = i - 1; // Temporäre Variable
final int y = j; // Temporäre Variable final int y = j - 1; // Temporäre Variable
if (i == 0 && j == 0) { if (i == 0 && j == 0) {
add(new JLabel(" ")); add(new JLabel(" "));
} else if (i == 0) { } else if (i == 0) {
@ -43,7 +61,7 @@ public class BoardDisplay extends JPanel {
} else { } else {
// Spielfeld (interaktive Zellen) // Spielfeld (interaktive Zellen)
JButton field = new JButton(""); JButton field = new JButton("");
field.setBackground(Color.LIGHT_GRAY); field.setBackground(Color.BLUE);
field.setOpaque(true); field.setOpaque(true);
field.setBorderPainted(true); field.setBorderPainted(true);
fields[i - 1][j - 1] = field; fields[i - 1][j - 1] = field;
@ -61,23 +79,38 @@ public class BoardDisplay extends JPanel {
// field.setBackground(Color.LIGHT_GRAY); // field.setBackground(Color.LIGHT_GRAY);
// } // }
// }); // });
int finalI = i;
int finalJ = j;
field.addMouseListener(new MouseAdapter() { field.addMouseListener(new MouseAdapter() {
@Override @Override
public void mouseClicked(MouseEvent e) { public void mouseClicked(MouseEvent e) {
Point o= new Point(finalI, finalJ); if (SwingUtilities.isRightMouseButton(e)) {
System.out.println(o); togglePlacementDirection(); // Ausrichtung ändern
handleFieldClick(field, o,player); } else if (SwingUtilities.isLeftMouseButton(e)) {
Point o = new Point(x, y);
currentShip.setHorizontal(vertical);
handleFieldClick(o); // Linksklick -> Schiff platzieren
}
} }
}); });
} }
} }
} }
// this.ships = new ArrayList<Ship>(); // this.ships = new ArrayList<Ship>();
} }
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. * TODO Funktion beschreiben etc.
* @param ship * @param ship
@ -86,31 +119,6 @@ public class BoardDisplay extends JPanel {
* @param player * @param player
* @return * @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<Point> 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. * TODO Funktion beschreiben etc.
@ -119,43 +127,63 @@ public class BoardDisplay extends JPanel {
* @param horizontal * @param horizontal
* @return * @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) { * Wechselt die Platzierungsrichtung zwischen horizontal und vertikal.
for (Point p : other.getOccupiedPoints()) { */
for (Point newP : ship.getOccupiedPoints()) { private void togglePlacementDirection() {
if (p.equals(newP)) { vertical = !vertical;
return false; // Überschneidung gefunden 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;
} }
} }
} }
} }
for( ShipButton shipButton: shipButtonList) {
return true; shipButton.refreshButtonState();
}
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
} }
} }
private void previewShipPlacement(int startX, int startY, boolean vertical) {
//TODO schreiben
}
private void clearPreview() {
}
public void refresh() {
paintFields();
}
} }

View File

@ -13,6 +13,14 @@ import java.util.List;
* Der Benutzer kann hier seine Schiffe platzieren, das Spiel starten etc. * Der Benutzer kann hier seine Schiffe platzieren, das Spiel starten etc.
*/ */
public class GameBoard extends JPanel { public class GameBoard extends JPanel {
private BoardDisplay ownBoardPanel;
private BoardDisplay opponentBoardPanel;
private Player p1;
private Player p2;
// Funktionshilfen // Funktionshilfen
//int semesterCounter = 1; //TODO: ersetzen durch param von vorpanel //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 gameBoardEmtpy = new ImageIcon("graphics/gameboardempty.png");
ImageIcon gameBoardX = new ImageIcon("graphics/gameboardx.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 // Labels
JLabel frameTitle = new JLabel("GameBoard"); JLabel frameTitle = new JLabel("GameBoard");
JLabel kontextText = new JLabel("Beispielhafter Kontext-Text"); JLabel kontextText = new JLabel(kT1);
//kontextText.setFont(new Font("Roboto", Font.BOLD, 24)); //TODO setFont fixen
JButton backButton = new JButton(backButtonIcon); JButton backButton = new JButton(backButtonIcon);
// Eigene ModulButtons // Eigene ModulButtons
@ -37,36 +54,11 @@ public class GameBoard extends JPanel {
* @param p2 Zweites Spielerobjekt * @param p2 Zweites Spielerobjekt
*/ */
GameBoard(MainFrame frame, int semesterCounter,Player p1, Player p2) { GameBoard(MainFrame frame, int semesterCounter,Player p1, Player p2) {
JToggleButton leftPlayerModul1 = new JToggleButton("Modul 1"); //TODO: Dynamische Namen durch abgleich mit Semester this.p1 = p1;
JToggleButton leftPlayerModul2 = new JToggleButton("Modul 2"); this.p2 = p2;
JToggleButton leftPlayerModul3 = new JToggleButton("Modul 3"); buildPanel(frame, semesterCounter);
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);
List<Ship> shipsP1 =p1.getBoard().getShips(); List<Ship> shipsP1 =p1.getBoard().getShips();
updateButtonLabels(shipsP1,leftPlayerButtons); List<Ship> shipsP2 =p2.getBoard().getShips();
backButton.addActionListener(e -> frame.showPanel("MainMenu")); 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. * TODO Funktion beschreiben etc.
* @param frame * @param frame
* @param semesterCounter * @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 // Hauptlayout - BorderLayout für die Anordnung der Komponenten
setLayout(new BorderLayout()); 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 // Panel für das Kontext-Text-Feld
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
headerPanel.add(backButton, BorderLayout.EAST); headerPanel.add(backButton, BorderLayout.EAST);
// Panel für die Buttons des linken Spielers (ganz links)
JPanel leftButtonsPanel = new JPanel(); JPanel leftButtonsPanel = new JPanel();
leftButtonsPanel.setLayout(new GridLayout(7, 1)); // 6 Buttons untereinander 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(); JPanel rightButtonsPanel = new JPanel();
rightButtonsPanel.setLayout(new GridLayout(7, 1)); // 6 Buttons untereinander rightButtonsPanel.setLayout(new GridLayout(7, 1));
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);
//Buttons in eine Gruppe packen damit diese beim drücken eines anderen Buttons wieder entwählt werden //Buttons in eine Gruppe packen damit diese beim drücken eines anderen Buttons wieder entwählt werden
ButtonGroup leftButtonGroup= new ButtonGroup(); 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(); ButtonGroup rightButtonGroup= new ButtonGroup();
rightButtonGroup.add(rightButtons[0]);
rightButtonGroup.add(rightButtons[1]); // Panel für die Buttons des linken Spielers (ganz links)
rightButtonGroup.add(rightButtons[2]); for(Ship ship : p1.getBoard().getShips()) {
rightButtonGroup.add(rightButtons[3]); ShipButton shipButton= new ShipButton(ship,ownBoardPanel);
rightButtonGroup.add(rightButtons[4]); leftButtonsPanel.add(shipButton);
rightButtonGroup.add(rightButtons[5]); leftButtonGroup.add(shipButton);
rightButtonGroup.add(rightButtons[6]); 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) // Panel für beide Spielfelder (nebeneinander in der Mitte)
JPanel centerPanel = new JPanel(); JPanel centerPanel = new JPanel();
@ -156,11 +181,42 @@ public class GameBoard extends JPanel {
centerPanel.add(ownBoardPanel); centerPanel.add(ownBoardPanel);
centerPanel.add(opponentBoardPanel); 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 // Panels dem Hauptlayout hinzufügen
add(leftButtonsPanel, BorderLayout.WEST); add(leftButtonsPanel, BorderLayout.WEST);
add(rightButtonsPanel, BorderLayout.EAST); add(rightButtonsPanel, BorderLayout.EAST);
add(headerPanel, BorderLayout.NORTH); 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();
} }
} }

View File

@ -166,6 +166,8 @@ public class GameController {
localPlayer.setEnemy(aiPlayer); localPlayer.setEnemy(aiPlayer);
aiPlayer.setEnemy(localPlayer); aiPlayer.setEnemy(localPlayer);
localPlayer.setName(localPlayerName);
startGameWithInstancedPlayers(localPlayer, aiPlayer, size); startGameWithInstancedPlayers(localPlayer, aiPlayer, size);
} }

View File

@ -38,21 +38,24 @@ public class LocalPlayer extends Player {
@Override @Override
public synchronized void receiveCoin(boolean coin) { public synchronized void receiveCoin(boolean coin) {
if (!this.haseReceivedCoin) { if (!this.hasReceivedCoin) {
boolean result = coin ^ this.myCoin; // XOR this.hasReceivedCoin = true;
this.myTurn = result == this.isServer; this.determineCoinToss();
this.haseReceivedCoin = true;
} }
} }
public void sendCoin() {
enemy.receiveCoin(this.myCoin);
}
@Override @Override
public void shoot(Point point){ public void shoot(Point point){
this.myTurn = false; this.myTurn = false;
enemy.receiveShoot(point); enemy.receiveShoot(point);
} }
@Override
public synchronized void ready() {
for (Ship ship : this.board.getShips()) {
if (!ship.isPlaced()) return;
}
super.ready();
}
} }

View File

@ -1,6 +1,8 @@
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
//TODO Generell button ausblenden anpassen
/** /**
* Der MainFrame dient als Hub und Übergreifendes Fenster auf dem alle weiteren Panel angezeigt werden. * Der MainFrame dient als Hub und Übergreifendes Fenster auf dem alle weiteren Panel angezeigt werden.
* Dadurch werden keine weiteren Fenster geöffnet. * Dadurch werden keine weiteren Fenster geöffnet.
@ -19,6 +21,7 @@ public class MainFrame extends JFrame {
// Von startLocalGameLoadingScreen an GameBoard // Von startLocalGameLoadingScreen an GameBoard
int semesterCounter; int semesterCounter;
// ---------- // // ---------- //
private GameBoard gameBoard;
/** /**
* Konstruktor von MainFrame. * Konstruktor von MainFrame.
@ -93,7 +96,7 @@ public class MainFrame extends JFrame {
public void showPanelSLG(String panelName,int semesterCounter, Player p1, Player p2) { public void showPanelSLG(String panelName,int semesterCounter, Player p1, Player p2) {
this.semesterCounter = semesterCounter; this.semesterCounter = semesterCounter;
GameBoard gameBoard = new GameBoard(this, semesterCounter, p1, p2); this.gameBoard = new GameBoard(this, semesterCounter, p1, p2);
mainPanel.add(gameBoard, panelName); mainPanel.add(gameBoard, panelName);
mainPanel.revalidate(); mainPanel.revalidate();
mainPanel.repaint(); mainPanel.repaint();
@ -114,4 +117,8 @@ public class MainFrame extends JFrame {
mainPanel.repaint(); mainPanel.repaint();
cardLayout.show(mainPanel, panelName); // Show the panel cardLayout.show(mainPanel, panelName); // Show the panel
} }
public void refreshGameBoard() {
this.gameBoard.refresh();
}
} }

View File

@ -7,6 +7,7 @@ public abstract class OnlinePlayer extends Player implements AsyncSocketListener
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;
socket.setHandler(this); socket.setHandler(this);
//TODO Auto-generated constructor stub //TODO Auto-generated constructor stub
} }

View File

@ -33,8 +33,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");
enemy.receiveCoin(this.myCoin); this.ready();
this.hasReceivedCoinPackage = true; this.hasReceivedCoinPackage = true;
} }
break; break;
@ -85,9 +85,10 @@ public class OnlinePlayer_1_1_0 extends OnlinePlayer {
@Override @Override
public synchronized void receiveCoin(boolean coin) { public synchronized void receiveCoin(boolean coin) {
if (!this.haseReceivedCoin) { if (!this.hasReceivedCoin) {
super.socket.send(new SocketPackage("COIN", String.valueOf(coin ? 1 : 0))); super.socket.send(new SocketPackage("COIN", String.valueOf(coin ? 1 : 0)));
this.haseReceivedCoin = true; this.hasReceivedCoin = true;
this.determineCoinToss();
} }
} }

View File

@ -1,21 +1,21 @@
import java.util.Random;
public abstract class Player { public abstract class Player {
protected boolean myTurn; protected boolean myTurn;
protected boolean isServer; protected boolean isServer;
protected boolean waitingForResponse; protected boolean waitingForResponse;
protected Player enemy; protected Player enemy;
protected String name; protected String name;
protected Board board; protected Board board;
protected boolean myCoin; protected Boolean myCoin;
protected boolean sendCoin; protected boolean sentCoin;
protected boolean haseReceivedCoin; protected boolean hasReceivedCoin;
public Player() { public Player() {
this.haseReceivedCoin = false; this.setName("Player");
this.sendCoin = false; this.hasReceivedCoin = false;
this.sentCoin = false;
this.myTurn = false;
} }
public void createBoard(int size) { public void createBoard(int size) {
@ -28,8 +28,8 @@ public abstract class Player {
public abstract void shoot(Point point); public abstract void shoot(Point point);
public void beginTrun() { public void beginTurn() {
System.out.println("issa my turn-a");
} }
public void setEnemy(Player enemy) { public void setEnemy(Player enemy) {
@ -47,5 +47,23 @@ public abstract class Player {
return this.board; 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); public abstract void receiveCoin(boolean coin);
} }

View File

@ -42,4 +42,18 @@ public class Point {
public static boolean isValidSyntax(String str) { public static boolean isValidSyntax(String str) {
return str.matches("^[A-Z]\\d+$"); 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;
}
} }

View File

@ -61,8 +61,21 @@ public class Ship {
this.sunk = false; this.sunk = false;
} }
public boolean setPosition(Point pos, List<Ship> shipsList, int boardSize) { public void resetPosition() {
// ueberpruefe boundaries this.position = null;
}
public boolean setPosition(Point pos, boolean horizontal, List<Ship> 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<Ship> shipsList, int boardSize) {
// 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) {
return false; return false;
} }
@ -71,7 +84,7 @@ public class Ship {
int endX = pos.getX(); int endX = pos.getX();
int endY = pos.getY(); int endY = pos.getY();
if (this.horizontal) { // rechts links if (horizontal) { // rechts links
endX = pos.getX() + this.size - 1; endX = pos.getX() + this.size - 1;
if (endX >= boardSize) { if (endX >= boardSize) {
return false; return false;
@ -86,8 +99,8 @@ public class Ship {
// Liste an Punkten die das Schiff einnehmen wuerde // Liste an Punkten die das Schiff einnehmen wuerde
List<Point> shipPoints = new ArrayList<>(); List<Point> shipPoints = new ArrayList<>();
for (int i = 0; i < this.size; i++) { 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 x = 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 y = horizontal ? pos.getY() : pos.getY() + i;
shipPoints.add(new Point(x, y)); shipPoints.add(new Point(x, y));
} }
@ -105,15 +118,11 @@ public class Ship {
List<Point> otherShipPoints = otherShip.getOccupiedPoints(); List<Point> otherShipPoints = otherShip.getOccupiedPoints();
// ueberlappen checken // ueberlappen checken
for (Point p : shipPoints) { for (Point p : shipPoints) {
if (otherShipPoints.contains(p)) { for (Point otherPoint : otherShipPoints) {
// ueberlappen entdeckt if (otherPoint.neighbours(p)) return false;
return false; }
}
} }
} }
// kein ueberlappen also setze das Schiff
this.position = pos;
return true; return true;
} }
@ -135,6 +144,9 @@ public class Ship {
} }
public boolean isShipOnPos(Point pos){ 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) || 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)) { (!(this.horizontal) && pos.getX() == this.position.getX() && pos.getY() >= this.position.getY() && pos.getY() < this.position.getY() + size)) {
return true; return true;
@ -170,4 +182,9 @@ public class Ship {
public String getName() { public String getName() {
return name; return name;
} }
//potentiell falsch neu
public boolean isPlaced(){
return this.position != null;
}
} }

26
src/ShipButton.java Normal file
View File

@ -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);
}
}
}

View File

@ -5,6 +5,10 @@ public class SpecificAiPlayerMedium extends AiPlayer{
private List<Point> hitsQueue = new ArrayList<>(); private List<Point> hitsQueue = new ArrayList<>();
public SpecificAiPlayerMedium() {
this.setName("AI Player Medium");
}
@Override @Override
public void AiShoot() { public void AiShoot() {
Point nextShot = ComputeNextShot(); Point nextShot = ComputeNextShot();