Merge pull request 'cleanup-work' (#22) from cleanup-work into main

Reviewed-on: #22
This commit is contained in:
Luca Conte 2024-12-22 23:06:00 +00:00
commit f73114eaeb
15 changed files with 474 additions and 55 deletions

View File

@ -60,6 +60,7 @@ public abstract class AiPlayer extends LocalPlayer implements Runnable {
* Ki Methode zum zufälligen Schießen auf das gegnerische Board.
*/
public void aiShoot() {
if (!this.myTurn) return;
this.enemy.receiveShoot(RandomPoint());
return;
}
@ -98,10 +99,10 @@ public abstract class AiPlayer extends LocalPlayer implements Runnable {
t.start();
this.shootThreads.add(t);
}
/**
* Die Methode wird immer aufgerufen, wenn ein Schuss abgefeuert werden soll.
* Es wird erst ein Schuss abgefeuert, wenn der vorherige schuss abgeschlossen wurde.
* Closes past threads and tries firing a shot.
* @author Luca Conte
*/
public void run() {
Iterator<Thread> i = this.shootThreads.iterator();
@ -128,4 +129,24 @@ public abstract class AiPlayer extends LocalPlayer implements Runnable {
this.aiShoot();
}
}
/**
* Closes all running threads and does some cleanup work so the garbage collector will delete the player
* @author Luca Conte
*/
@Override
public void destroy() {
super.destroy();
Iterator<Thread> i = this.shootThreads.iterator();
while(i.hasNext()) {
Thread thread = i.next();
try {
thread.join();
i.remove();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

View File

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

View File

@ -1,3 +1,6 @@
/**
* @author Luca Conte
*/
public interface AsyncSocketListener {
public void receive(String message);
}

View File

@ -42,6 +42,12 @@ public class Board {
return response;
}
/**
* finds adjacened hit responses and sets their type to SUNK if they are currently HIT
* this makes it so that all the points of the ship are marked as SUNK, not just the final hit
* @param p the Point from which to propate the SUNK type
* @author Luca Conte
*/
private void propagateSunk(Point p) {
HitResponse hit = this.getHitResponseOnPoint(p);
@ -55,6 +61,10 @@ public class Board {
propagateSunk(new Point(p.getX(), p.getY() - 1));
}
/**
* creates all the ships on a board given a certain semester
* @param semester the semester to be played in
*/
private void createShip(int semester){
List<ShipData> shipData = Ship.semeterList.get(semester -1);
for (int i = 0; i < shipData.size(); i++) {
@ -62,10 +72,22 @@ public class Board {
}
}
/**
* @return a list of all the Ships on the board
*/
public List<Ship> getShips() {
return ships;
}
/**
* adds a HitResponse to the list of Hits on the board
* If a hit response already exists on the same position, the hit response will not be added
* If the hit response is of type `HitResponseType.SUNK` it will propagate this hit response type
* to all adjacened hit responses with type HIT using `propagateSunk`.
* @param hitResponse the HitResponse to be added
* @return true when the hit response was added, otherwise false
*
*/
public synchronized boolean addHits(HitResponse hitResponse) {
if (this.getHitResponseOnPoint(hitResponse.getPoint()) == null){
this.hits.add(hitResponse);
@ -81,6 +103,10 @@ public class Board {
return false;
}
/**
* @param point the position to get the hit response from
* @return the hit response at the position `point`
*/
public synchronized HitResponse getHitResponseOnPoint(Point point) {
for (int i = 0; i < this.hits.size(); i++){
if (this.hits.get(i).getPoint().equals(point)){
@ -90,6 +116,9 @@ public class Board {
return null;
}
/**
* @return the size of the board
*/
public int getSize() {
return this.size;
}

View File

@ -212,4 +212,17 @@ public class GameBoard extends JPanel {
this.ownBoardPanel.refresh();
this.opponentBoardPanel.refresh();
}
/**
* Getter für Player1
* @return Player 1
* @author Peer Ole Wachtel
*/
public Player getP1() {
return p1;
}
public Player getP2() {
return p2;
}
}

View File

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

View File

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

View File

@ -8,8 +8,15 @@ public class LocalPlayer extends Player {
this.myCoin = random.nextBoolean();
}
/**
* receives a shot onto a point from the enemy
* @param point the location to be shot
* @author Luca Conte, Peer Ole Wachtel
*/
@Override
public synchronized void receiveShoot(Point point) {
if (!this.enemy.myTurn) return;
HitResponse hitResponse = board.getHitResponseOnPoint(point);
if (!(hitResponse == null)){
enemy.receiveHit(hitResponse);
@ -22,22 +29,34 @@ public class LocalPlayer extends Player {
switch (hitResponse.getType()) {
case HIT, SUNK -> this.myTurn = false;
case MISS -> this.myTurn = true;
case VICTORY -> System.out.println("Game Over"); //TODO Was halt bei victory passiert ist hier wurder verloheren
case VICTORY -> GameController.getMainFrame().showPanelLoose("", this); //TODO Was halt bei victory passiert ist hier wurder verloheren
}
GameController.getMainFrame().refreshGameBoard();
}
/**
* receives a hit response from the enemy as a response to a receiveShoot call
* @param hitResponse the hitresponse
* @author Peer Ole Wachtel
*/
@Override
public synchronized void receiveHit(HitResponse hitResponse) {
enemy.board.addHits(hitResponse);
switch (hitResponse.getType()) {
case HIT, SUNK -> this.myTurn = true;
case MISS -> this.myTurn = false;
case VICTORY -> System.out.println("Win"); // TODO was halt beim victory passier ist hier wurde gewonnen
case VICTORY -> GameController.getMainFrame().showPanelWin("", this); // TODO was halt beim victory passier ist hier wurde gewonnen
}
GameController.getMainFrame().refreshGameBoard();
}
/**
* receives the enemies coin toss result
* this method does nothing if the player has already received the enemies coin
* it will also call `determineCoinToss`
* @param coin the coin of the enemy player
* @author Luca Conte
*/
@Override
public synchronized void receiveCoin(boolean coin) {
if (!this.hasReceivedCoin) {
@ -46,12 +65,19 @@ public class LocalPlayer extends Player {
}
}
/**
* sends shot to enemy player.
* should ONLY be called on HumanPlayer
*/
@Override
public void shoot(Point point){
this.myTurn = false;
enemy.receiveShoot(point);
return;
}
/**
* marks the player as ready, if all ships have been placed
* @author Luca Conte
*/
@Override
public synchronized void ready() {
for (Ship ship : this.board.getShips()) {

View File

@ -127,9 +127,13 @@ public class MainFrame extends JFrame {
/**
* Spezifische ShowPanel für WinScreen Klasse
* @param panelName Name des anzuzeigenden Panels
* @author Lucas Bronson
* @param player Player von dem die funktion aufgerufen worden ist
* @author Lucas Bronson, Peer Ole Wachtel
*/
public void showPanelWin(String panelName){
public void showPanelWin(String panelName, Player player){
if(player != gameBoard.getP1()){
return;
}
WinScreen winScreen = new WinScreen(this);
mainPanel.add(winScreen, panelName);
mainPanel.revalidate();
@ -140,9 +144,15 @@ public class MainFrame extends JFrame {
/**
* Spezifische ShowPanel für LooseScreen Klasse
* @param panelName Name des anzuzeigenden Panels
* @author Lucas Bronson
* @param player Player von dem die funktion aufgerufen worden ist
* @author Lucas Bronson, Peer Ole Wachtel
*/
public void showPanelLoose(String panelName){
public void showPanelLoose(String panelName, Player player){
if(player != gameBoard.getP1()){
return;
}
this.gameBoard.getP1().destroy();
this.gameBoard.getP2().destroy();
LooseScreen looseScreen = new LooseScreen(this);
mainPanel.add(looseScreen,panelName);
mainPanel.revalidate();

View File

@ -1,9 +1,15 @@
public abstract class OnlinePlayer extends Player implements AsyncSocketListener{
public abstract class OnlinePlayer extends Player implements AsyncSocketListener {
protected AsyncSocket socket;
protected int wantedBoardSize;
protected boolean hasReceivedCoinPackage;
/**
* Constructor
* @param size the size of the board the enemy player wants to play with
* the actual board size will be determined once the semester of the online partner is known
* @param socket an AsyncSocket to communicate with the enemy through
*/
public OnlinePlayer(Integer size, AsyncSocket socket) {
this.socket = socket;
this.wantedBoardSize = size;
@ -25,4 +31,14 @@ public abstract class OnlinePlayer extends Player implements AsyncSocketListener
@Override
public abstract void receiveCoin(boolean coin);
/**
* closes the socket and does player cleanup work
* @author Luca Conte
*/
@Override
public void destroy() {
super.destroy();
this.socket.close();
}
}

View File

@ -6,6 +6,12 @@ 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
*/
@Override
public void receive(String message) {
SocketPackage p = new SocketPackage(message);
@ -34,8 +40,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");
this.ready();
this.hasReceivedCoinPackage = true;
this.ready();
}
break;
@ -67,22 +73,44 @@ public class OnlinePlayer_1_1_0 extends OnlinePlayer {
}
}
/**
* sends introduction package IAM to online partner.
* @author Luca Conte
*/
@Override
public synchronized void sendIAM() {
if (this.enemy == null) throw new RuntimeException("enemy has not yet been defined");
socket.send(new SocketPackage("IAM", GameController.boardSizeToSemester(this.wantedBoardSize) + " " + this.enemy.name));
}
/**
* receives a shot from the enemy and sends it to the online partner
* if it is not the enemies turn, this method does nothing.
* @param point the point to be shot
* @author Peer Ole Wachtel
*/
@Override
public synchronized void receiveShoot(Point point){
if (!this.enemy.myTurn) return;
super.socket.send(new SocketPackage("SHOOT",point.toString()));
}
/**
* receives a hitresponse from the enemy player and sends it to the online partner
* @param hitResponse the hitresponse to be sent
* @author Peer Ole Wachtel
*/
@Override
public synchronized void receiveHit(HitResponse hitResponse) {
super.socket.send(new SocketPackage("HIT", hitResponse.toString()));
}
/**
* receives the coin toss result from the enemy player and sends it to the online partner
* if this player has already received the enemies coin, this method does nothing.
* @param coin the result of the coin toss
* @author Peer Ole Wachtel, Luca Conte
*/
@Override
public synchronized void receiveCoin(boolean coin) {
if (!this.hasReceivedCoin) {
@ -94,6 +122,7 @@ public class OnlinePlayer_1_1_0 extends OnlinePlayer {
@Override
public synchronized void shoot(Point point) {
super.socket.send(new SocketPackage("SHOOT", point.toString()));
// SHOULD NEVER BE CALLED ON ONLINE PLAYER. ONLY ON HUMAN PLAYER
return;
}
}

View File

@ -20,6 +20,11 @@ public abstract class Player {
this.gameRunning = false;
}
/**
* initialises this players board
* @param size the size of the board to be created
* @author Peer Ole Wachtel
*/
public void createBoard(int size) {
this.board = new Board(size);
}
@ -30,25 +35,54 @@ public abstract class Player {
public abstract void shoot(Point point);
/**
* only relevant for AI Players.
* starts the first turn
* @author Luca Conte
*/
public void beginTurn() {
System.out.println("issa my turn-a");
}
/**
* sets the enemy Player
* @author Peer Ole Wachtel
*/
public void setEnemy(Player enemy) {
this.enemy = enemy;
}
/**
* sets the name of this player
* @param name the name of this player
* @author Luca Conte
*/
public void setName(String name) {
this.name = name;
}
/**
* returns the name of this player
* @return the name of this player
* @author Luca Conte
*/
public String getName() {
return this.name;
}
/**
* returns the board of this player
* @return the board of this player
* @author Lucas Bronson
*/
public Board getBoard() {
return this.board;
}
/**
* marks the player as ready by sending their coin to the enemy player
* calls determineCoinToss if the enemy coin has already been received
* @author Luca Conte
*/
public void ready() {
this.enemy.receiveCoin(this.myCoin);
this.sentCoin = true;
@ -57,6 +91,11 @@ public abstract class Player {
}
};
/**
* determines the result of the coin toss
* this method does nothing if either player is not ready yet or has not yet sent their coin
* @author Luca Conte, Peer Ole Wachtel
*/
protected void determineCoinToss() {
if (!this.sentCoin || this.myCoin == null || !this.hasReceivedCoin || this.enemy.myCoin == null) return;
boolean result = this.enemy.myCoin ^ this.myCoin; // XOR
@ -68,13 +107,43 @@ public abstract class Player {
GameController.getMainFrame().refreshGameBoard();
}
/**
* receives the coin toss from the enemy player
* @param coin the coin of the enemy player
* @author Peer Ole Wachtel
*/
public abstract void receiveCoin(boolean coin);
/**
* returns whether the game this player is in has started, meaning both players are ready and have sent their coins
* @return the game's running state
* @author Luca Conte
*/
public boolean isGameRunning() {
return this.gameRunning;
}
/**
* returns whether this player is ready and has sent their coin to the enemy player
* @return the player's ready state
*/
public boolean isReady() {
return this.sentCoin;
}
/**
* removes connections to the enemy and its board as well as setting myTurn and gameRunning to false
* this stops the AI Players from making more moves and allows the garbage collector to remove the boards
* and players
*
* This method should be called at the end of a game
*
* @author Luca Conte
*/
public void destroy() {
this.myTurn = false;
this.gameRunning = false;
this.board = null;
this.enemy = null;
}
}

View File

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

View File

@ -6,43 +6,51 @@ import java.util.List;
record ShipData (int size, String name){}
public class Ship {
static List<List<ShipData>> semeterList = Arrays.asList(Arrays.asList(
new ShipData(2, "PRG 1"),
new ShipData(2, "GDI"),
new ShipData(2, "MAT 1"),
new ShipData(2, "THI"),
new ShipData(4, "STP"),
new ShipData(6, "ENG")),
Arrays.asList(
new ShipData(2, "PRG 2"),
new ShipData(2, "DBS 1"),
new ShipData(2, "MAT 2"),
new ShipData(2, "STA"),
new ShipData(2, "AUD")),
Arrays.asList(
new ShipData(2, "PRG 3"),
new ShipData(2, "DBS 2"),
new ShipData(2, "MAT 3"),
new ShipData(2, "BSN 1"),
new ShipData(4, "PRP"),
new ShipData(6, "BWL")),
Arrays.asList(
new ShipData(2, "WEB"),
new ShipData(2, "SE 1"),
new ShipData(2, "CG 1"),
new ShipData(2, "BSN 2"),
new ShipData(4, "SEM"),
new ShipData(6, "E BWL")),
Arrays.asList(
new ShipData(2, "WPF 1"),
new ShipData(2, "SE 2"),
new ShipData(2, "CG 2"),
new ShipData(2, "PXP 1"),
new ShipData(6, "EF 1")),
Arrays.asList(
new ShipData(2, "WPF 2"),
new ShipData(1, "PXP 2"),
new ShipData(8, "BAA"))
static List<List<ShipData>> semeterList =
Arrays.asList(
Arrays.asList(
new ShipData(2, "PRG 1"),
new ShipData(2, "GDI"),
new ShipData(2, "MAT 1"),
new ShipData(2, "THI"),
new ShipData(4, "STP"),
new ShipData(6, "ENG")
),
Arrays.asList(
new ShipData(2, "PRG 2"),
new ShipData(2, "DBS 1"),
new ShipData(2, "MAT 2"),
new ShipData(2, "STA"),
new ShipData(2, "AUD")
),
Arrays.asList(
new ShipData(2, "PRG 3"),
new ShipData(2, "DBS 2"),
new ShipData(2, "MAT 3"),
new ShipData(2, "BSN 1"),
new ShipData(4, "PRP"),
new ShipData(6, "BWL")
),
Arrays.asList(
new ShipData(2, "WEB"),
new ShipData(2, "SE 1"),
new ShipData(2, "CG 1"),
new ShipData(2, "BSN 2"),
new ShipData(4, "SEM"),
new ShipData(6, "E BWL")
),
Arrays.asList(
new ShipData(2, "WPF 1"),
new ShipData(2, "SE 2"),
new ShipData(2, "CG 2"),
new ShipData(2, "PXP 1"),
new ShipData(6, "EF 1")
),
Arrays.asList(
new ShipData(2, "WPF 2"),
new ShipData(1, "PXP 2"),
new ShipData(8, "BAA")
)
);
private int size;

View File

@ -200,7 +200,7 @@ public class startLocalGame extends JPanel {
testButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
frame.showPanelWin("WinPanel");
//frame.showPanelWin("WinPanel");
}
});