From 73fd298fe5e20b42304170feead38650496ccaf8 Mon Sep 17 00:00:00 2001 From: Leonardo Brandenberger Date: Fri, 25 Mar 2022 21:48:40 +0100 Subject: [PATCH 1/3] added java docs --- README.md | 6 +- src/main/java/ch/zhaw/pm2/racetrack/Game.java | 97 +++++++------------ .../racetrack/InvalidFileFormatException.java | 12 ++- .../InvalidTrackFormatException.java | 1 + 4 files changed, 47 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index 7754444..cc38efd 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# team02-AngryNerds-projekt1-racetrack -PM2 Team 02 Projekt 1 Racetrack + +#PM2 Team 02 Projekt 1 Racetrack Racetrack is a pen and paper game that dates back to the early 1960s in this version of the game, the game is digitalized and the math behind it is done automatically rather than calculated by hand and the winner gets informed automatically as well. The aim of the game is to finish the race faster than your opponent or win by being the only survivor in case the other cars crash. -In order to not crash you have to keep in mind the acceleration and other players car to get to the finish line safely. +In order to not crash you have to keep in mind the acceleration and other player's car to get to the finish line safely. # Initialization: #### The game can be initialized by the terminal command: diff --git a/src/main/java/ch/zhaw/pm2/racetrack/Game.java b/src/main/java/ch/zhaw/pm2/racetrack/Game.java index 4203a3e..d9d2206 100644 --- a/src/main/java/ch/zhaw/pm2/racetrack/Game.java +++ b/src/main/java/ch/zhaw/pm2/racetrack/Game.java @@ -2,7 +2,6 @@ package ch.zhaw.pm2.racetrack; import ch.zhaw.pm2.racetrack.given.GameSpecification; import ch.zhaw.pm2.racetrack.strategy.*; -import org.hamcrest.core.IsInstanceOf; import java.io.File; import java.io.FileNotFoundException; @@ -29,7 +28,8 @@ public class Game implements GameSpecification { } /** - * This method will initialize the game. Therefore it interacts with the user via UserInterface + * This method will initialize the game. Therefore, it interacts with the user via UserInterface + * * @return true if the initialization is completed. Returns false if there is an error. */ public boolean initPhase() { @@ -70,35 +70,35 @@ public class Game implements GameSpecification { moveStrategy = new UserMoveStrategy(userInterface, i, track.getCarId(i)); break; case 2: - for(File file : config.getMoveDirectory().listFiles()){ - if(file.toString().equals(config.getMoveDirectory().toString() + "\\" + selectedTrack.getName().split("\\.")[0] + "-car-" + track.getCar(i).getID() + ".txt")){ + for (File file : config.getMoveDirectory().listFiles()) { + if (file.toString().equals(config.getMoveDirectory().toString() + "\\" + selectedTrack.getName().split("\\.")[0] + "-car-" + track.getCar(i).getID() + ".txt")) { selectedFile = file; } } - if(selectedFile != null){ + if (selectedFile != null) { try { moveStrategy = new MoveListStrategy(selectedFile); } catch (FileNotFoundException e) { userInterface.printInformation("There is no Move-List implemented. Choose another Strategy!"); } - } else{ + } else { userInterface.printInformation("There is no Move-List implemented. Choose another Strategy!"); } break; case 3: - for(File file : config.getFollowerDirectory().listFiles()){ - if(file.toString().equals(config.getFollowerDirectory().toString() + "\\" + selectedTrack.getName().split("\\.")[0] + "_points.txt")){ + for (File file : config.getFollowerDirectory().listFiles()) { + if (file.toString().equals(config.getFollowerDirectory().toString() + "\\" + selectedTrack.getName().split("\\.")[0] + "_points.txt")) { selectedFile = file; } } - if(selectedFile != null){ + if (selectedFile != null) { try { moveStrategy = new PathFollowerMoveStrategy(selectedFile, track.getCarPos(currentCarIndex)); } catch (FileNotFoundException e) { userInterface.printInformation("There is no Point-List implemented. Choose another Strategy!"); } - } else{ + } else { userInterface.printInformation("There is no Point-List implemented. Choose another Strategy!"); } @@ -112,21 +112,24 @@ public class Game implements GameSpecification { } return true; } else { - userInterface.printInformation("No Trackfile found!"); + userInterface.printInformation("No track file found!"); return false; } } /** - * The functionality was taken out of init to automate testing + * Selects the desired track and returns it. + * The functionality was taken out of init to automate testing. + * * @param selectedTrack the Track which was selected by user */ - Track selectTrack(File selectedTrack) throws InvalidTrackFormatException,FileNotFoundException { + Track selectTrack(File selectedTrack) throws InvalidTrackFormatException, FileNotFoundException { track = new Track(selectedTrack); return track; } /** + * Sets a desired move strategy for a desired car. * The functionality was taken out of init to automate testing * * @param car to set the MoveStrategy @@ -148,7 +151,7 @@ public class Game implements GameSpecification { } /** - * Get the id of the specified car. + * Gets the id of the specified car. * * @param carIndex The zero-based carIndex number * @return A char containing the id of the car @@ -221,7 +224,7 @@ public class Game implements GameSpecification { *

The calling method must check the winner state and decide how to go on. If the winner is different * than {@link Game#NO_WINNER}, or the current car is already marked as crashed the method returns immediately.

* - * @param acceleration A Direction containing the current cars acceleration vector (-1,0,1) in x and y direction + * @param acceleration A Direction containing the current car's acceleration vector (-1,0,1) in x and y direction * for this turn */ @Override @@ -240,9 +243,9 @@ public class Game implements GameSpecification { } } int newWinPoints = track.calculateNewWinPoints(track.getCarPos(currentCarIndex), track.getCar(currentCarIndex).nextPosition()); - if(newWinPoints == 1){ + if (newWinPoints == 1) { track.getCar(currentCarIndex).increaseWinPoints(); - }else if(newWinPoints == -1){ + } else if (newWinPoints == -1) { track.getCar(currentCarIndex).deductWinPoints(); } if (crashPosition != null) { @@ -253,7 +256,8 @@ public class Game implements GameSpecification { } /** - * This method implements the gameflow in a while loop. If there is a winner. The method will return its carid. + * This method is in charge of changing the players and checking if a winner is found if there is no winner null will be returned. + * If a winner is found the game will return the char of the winning player. * * @return the ID of the winning car return null if there is no winner. */ @@ -265,7 +269,7 @@ public class Game implements GameSpecification { Direction direction; direction = track.getCar(currentCarIndex).getMoveStrategy().nextMove(); if (direction == null) { - if(track.getCar(currentCarIndex).getMoveStrategy() instanceof UserMoveStrategy){ + if (track.getCar(currentCarIndex).getMoveStrategy() instanceof UserMoveStrategy) { quit = true; direction = Direction.NONE; } else { @@ -317,51 +321,6 @@ public class Game implements GameSpecification { return track.calculatePointsOnPath(startPosition, endPosition); } - - /** - * This method will check if a car is passing the finishline. - * If the car is passing the finishline in the wrong direction, the car will lose a winpoint. - * If the car is passing the finishline in the correct direction, the car will gain a winpoint. - * @param start the startposition of the car - * @param finish the expected finishpositon of the car after the move - */ - private void calculateWinner(PositionVector start, PositionVector finish, int carIndex) { - List path = calculatePath(start, finish); - for (PositionVector point : path) { - switch (track.getSpaceType(point)) { - case FINISH_UP: - if (start.getY() < finish.getY()) { - track.getCar(carIndex).increaseWinPoints(); - } else if (start.getY() > finish.getY()) { - track.getCar(carIndex).deductWinPoints(); - } - break; - case FINISH_DOWN: - if (start.getY() > finish.getY()) { - track.getCar(carIndex).increaseWinPoints(); - } else if (start.getY() < finish.getY()) { - track.getCar(carIndex).deductWinPoints(); - } - break; - case FINISH_RIGHT: - if (start.getX() < finish.getX()) { - track.getCar(carIndex).increaseWinPoints(); - } else if (start.getX() > finish.getX()) { - track.getCar(carIndex).deductWinPoints(); - } - break; - case FINISH_LEFT: - if (start.getX() > finish.getX()) { - track.getCar(carIndex).increaseWinPoints(); - } else if (start.getX() < finish.getX()) { - track.getCar(carIndex).increaseWinPoints(); - } - break; - } - } - } - - /** * Does indicate if a car would have a crash with a WALL space or another car at the given position. * @@ -374,6 +333,11 @@ public class Game implements GameSpecification { return track.willCrashAtPosition(carIndex, position); } + /** + * Checks if there is just one player left in the game being able to make moves. + * + * @return true if there is just one car left false there are more than one car left in game + */ public boolean onlyOneCarLeft() { int carsLeft = 0; for (int carIndex = 0; carIndex < track.getCarCount(); carIndex++) { @@ -384,6 +348,11 @@ public class Game implements GameSpecification { return !(carsLeft > 1); } + /** + * Checks if all cars have implemented the do not move strategy, so the game can determine it will end in a draw. + * + * @return true if all players have implemented do not move false otherwise + */ public boolean carsMoving() { for (int carIndex = 0; carIndex < track.getCarCount(); carIndex++) { if (!(track.getCar(carIndex).isCrashed() || track.getCar(carIndex).getMoveStrategy().getClass() == DoNotMoveStrategy.class)) { diff --git a/src/main/java/ch/zhaw/pm2/racetrack/InvalidFileFormatException.java b/src/main/java/ch/zhaw/pm2/racetrack/InvalidFileFormatException.java index f530593..ee9699e 100644 --- a/src/main/java/ch/zhaw/pm2/racetrack/InvalidFileFormatException.java +++ b/src/main/java/ch/zhaw/pm2/racetrack/InvalidFileFormatException.java @@ -1,10 +1,18 @@ package ch.zhaw.pm2.racetrack; /** - * Class for Exception when invalid Fileformat is used. + * Class for Exception when invalid file format is used. */ public class InvalidFileFormatException extends Exception { - public InvalidFileFormatException(){super();} + public InvalidFileFormatException() { + super(); + } + + /** + * Constructor that is used when an error message is given with the exception. + * + * @param errorMessage is the message to be displayed + */ public InvalidFileFormatException(String errorMessage) { super(errorMessage); } diff --git a/src/main/java/ch/zhaw/pm2/racetrack/InvalidTrackFormatException.java b/src/main/java/ch/zhaw/pm2/racetrack/InvalidTrackFormatException.java index fa24c25..4d102f9 100644 --- a/src/main/java/ch/zhaw/pm2/racetrack/InvalidTrackFormatException.java +++ b/src/main/java/ch/zhaw/pm2/racetrack/InvalidTrackFormatException.java @@ -7,6 +7,7 @@ public class InvalidTrackFormatException extends Exception { public InvalidTrackFormatException(String errorMessage) { super(errorMessage); } + public InvalidTrackFormatException() { super(); } From 77652705dcf852eb5ea5527aba365a6a001811b9 Mon Sep 17 00:00:00 2001 From: Andrin Fassbind Date: Fri, 25 Mar 2022 21:55:19 +0100 Subject: [PATCH 2/3] code cleanup --- .../racetrack/InvalidFileFormatException.java | 5 +- .../InvalidTrackFormatException.java | 1 + .../ch/zhaw/pm2/racetrack/PositionVector.java | 2 +- .../strategy/PathFinderMoveStrategy.java | 73 ++++++++++--------- 4 files changed, 45 insertions(+), 36 deletions(-) diff --git a/src/main/java/ch/zhaw/pm2/racetrack/InvalidFileFormatException.java b/src/main/java/ch/zhaw/pm2/racetrack/InvalidFileFormatException.java index 22b7126..62b672b 100644 --- a/src/main/java/ch/zhaw/pm2/racetrack/InvalidFileFormatException.java +++ b/src/main/java/ch/zhaw/pm2/racetrack/InvalidFileFormatException.java @@ -7,5 +7,8 @@ public class InvalidFileFormatException extends Exception { public InvalidFileFormatException(String errorMessage) { super(errorMessage); } - public InvalidFileFormatException(){super();} + + public InvalidFileFormatException() { + super(); + } } diff --git a/src/main/java/ch/zhaw/pm2/racetrack/InvalidTrackFormatException.java b/src/main/java/ch/zhaw/pm2/racetrack/InvalidTrackFormatException.java index fa24c25..4d102f9 100644 --- a/src/main/java/ch/zhaw/pm2/racetrack/InvalidTrackFormatException.java +++ b/src/main/java/ch/zhaw/pm2/racetrack/InvalidTrackFormatException.java @@ -7,6 +7,7 @@ public class InvalidTrackFormatException extends Exception { public InvalidTrackFormatException(String errorMessage) { super(errorMessage); } + public InvalidTrackFormatException() { super(); } diff --git a/src/main/java/ch/zhaw/pm2/racetrack/PositionVector.java b/src/main/java/ch/zhaw/pm2/racetrack/PositionVector.java index 4f3eafe..c059038 100644 --- a/src/main/java/ch/zhaw/pm2/racetrack/PositionVector.java +++ b/src/main/java/ch/zhaw/pm2/racetrack/PositionVector.java @@ -109,6 +109,6 @@ public final class PositionVector { @Override public String toString() { - return "(X:" + this.x + ", Y:" + this.y + ")"; + return "(X:" + this.x + ", Y:" + this.y + ")"; } } diff --git a/src/main/java/ch/zhaw/pm2/racetrack/strategy/PathFinderMoveStrategy.java b/src/main/java/ch/zhaw/pm2/racetrack/strategy/PathFinderMoveStrategy.java index 1442e76..cc3b6c7 100644 --- a/src/main/java/ch/zhaw/pm2/racetrack/strategy/PathFinderMoveStrategy.java +++ b/src/main/java/ch/zhaw/pm2/racetrack/strategy/PathFinderMoveStrategy.java @@ -9,7 +9,7 @@ import java.util.List; /** * Strategy which calculates the path automatically */ -public class PathFinderMoveStrategy implements MoveStrategy{ +public class PathFinderMoveStrategy implements MoveStrategy { private final Track track; private final int carIndex; private List moveList; @@ -36,17 +36,17 @@ public class PathFinderMoveStrategy implements MoveStrategy{ /** * Method to create a working moveList */ - private void createMoveList(){ + private void createMoveList() { // if Movelist is recreated next move will be the first move in moveList pointer = 0; calculatedStates = new ArrayList<>(); PossibleMove finishedMove = null; - List possibleMoves= new ArrayList<>(); + List possibleMoves = new ArrayList<>(); // create a PossibleMove object for each direction which doesn't end with a crash. - for(PositionVector.Direction direction : allDirections){ + for (PositionVector.Direction direction : allDirections) { PossibleMove newMove = new PossibleMove(null, direction); - if(! newMove.crashed()){ + if (!newMove.crashed()) { possibleMoves.add(newMove); } @@ -54,22 +54,22 @@ public class PathFinderMoveStrategy implements MoveStrategy{ // while no PossibleMove crosses the finishline // every PossibleMove will be accelerated in each direction to find a Move which finishes. - while(finishedMove == null){ + while (finishedMove == null) { List newMoves = new ArrayList<>(); - for(PossibleMove previousMove : possibleMoves){ - for(PositionVector.Direction direction : allDirections){ + for (PossibleMove previousMove : possibleMoves) { + for (PositionVector.Direction direction : allDirections) { PossibleMove newMove = new PossibleMove(previousMove, direction); State newState = new State(newMove.endPosition, newMove.endVelocity); - //only use the new created Possible Move if it doesn't crash, end State isn't in List of calculatedStates - // and if there is no move found yet which is finished. - if(! (newMove.crashed() || alreadyCalculated(newState) || finishedMove != null)){ - if(newMove.finished()){ - finishedMove = newMove; - } else { - calculatedStates.add(newState); - newMoves.add(newMove); - } + //only use the new created Possible Move if it doesn't crash, end State isn't in List of calculatedStates + // and if there is no move found yet which is finished. + if (!(newMove.crashed() || alreadyCalculated(newState) || finishedMove != null)) { + if (newMove.finished()) { + finishedMove = newMove; + } else { + calculatedStates.add(newState); + newMoves.add(newMove); } + } } } possibleMoves = newMoves; @@ -85,9 +85,9 @@ public class PathFinderMoveStrategy implements MoveStrategy{ * @param state the State which should be checked * @return true if it is in List, false if it isn't in List */ - private boolean alreadyCalculated(State state){ - for(State calculatedState: calculatedStates){ - if(state.equals(calculatedState)){ + private boolean alreadyCalculated(State state) { + for (State calculatedState : calculatedStates) { + if (state.equals(calculatedState)) { return true; } } @@ -97,26 +97,28 @@ public class PathFinderMoveStrategy implements MoveStrategy{ /** * Combination of position and velocity */ - public static class State{ + public static class State { final PositionVector position; final PositionVector velocity; /** * Constructor of State + * * @param position the PositionVector object with coordinates of the Position * @param velocity the PositionVector object with coordinates of the Velocity */ - public State(PositionVector position, PositionVector velocity){ + public State(PositionVector position, PositionVector velocity) { this.position = position; this.velocity = velocity; } /** * Checks if a state has the same Position and the same Velocity + * * @param compareState the State object to compare * @return true if it is equal, false if it is not equal */ - public boolean equals(State compareState){ + public boolean equals(State compareState) { return compareState.position.equals(position) && compareState.velocity.equals(velocity); } } @@ -136,21 +138,21 @@ public class PathFinderMoveStrategy implements MoveStrategy{ /** * Constructor of PossibleMove - * @param previousMove The move which must be executed bevor this move can be executed + * + * @param previousMove The move which must be executed bevor this move can be executed * @param nextDirection The direction of the move */ - public PossibleMove(PossibleMove previousMove, PositionVector.Direction nextDirection){ + public PossibleMove(PossibleMove previousMove, PositionVector.Direction nextDirection) { // Velocity of the car bevor the move is executed PositionVector startVelocity; directions = new ArrayList<>(); // check if there was a previousMove. - if(previousMove != null){ + if (previousMove != null) { directions.addAll(previousMove.directions); //copy the LIst of Directions from the previousMove startPosition = previousMove.endPosition; //use the endPosition from previousMove as startPosition startVelocity = previousMove.endVelocity; //use the endVelocity from previousMove as startVelocity - } - else { //if there was no previousMove + } else { //if there was no previousMove startPosition = track.getCarPos(carIndex); //use the current Position of the car from track as startPosition startVelocity = track.getCar(carIndex).getVelocity(); //use the current Velocity of the car from track as startVelocity } @@ -161,20 +163,22 @@ public class PathFinderMoveStrategy implements MoveStrategy{ /** * check if the finishline is crossed (in correct direction) if this move is executed + * * @return true if finishline will be crossed */ - public boolean finished(){ + public boolean finished() { return track.calculateNewWinPoints(startPosition, endPosition) == 1; } /** * checks if the car will crash or finishline will be crossed in wrong direction if this move is executed + * * @return true if car will crash */ public boolean crashed() { List points = track.calculatePointsOnPath(startPosition, endPosition); - for(PositionVector point : points) { - if (track.willCrashAtPosition(carIndex, point)){ + for (PositionVector point : points) { + if (track.willCrashAtPosition(carIndex, point)) { return true; } } @@ -187,6 +191,7 @@ public class PathFinderMoveStrategy implements MoveStrategy{ /** * Checks if the next Move in moveList will crash. If no crash next move in moveList will be executed. * If crash the moveList will be recreated. + * * @return the direction of acceleration which should be executed. */ @Override @@ -197,11 +202,11 @@ public class PathFinderMoveStrategy implements MoveStrategy{ PositionVector newVelocity = new PositionVector(currentVelocity.getX() + direction.vector.getX(), currentVelocity.getY() + direction.vector.getY()); PositionVector currentPosition = track.getCarPos(carIndex); PositionVector newPosition = new PositionVector(currentPosition.getX() + newVelocity.getX(), currentPosition.getY() + newVelocity.getY()); - for(PositionVector point : track.calculatePointsOnPath(currentPosition, newPosition)){ - if(track.willCrashAtPosition(carIndex, point)){ + for (PositionVector point : track.calculatePointsOnPath(currentPosition, newPosition)) { + if (track.willCrashAtPosition(carIndex, point)) { createMoveList(); pointer = 0; - direction = moveList.get(pointer); + direction = moveList.get(pointer); break; } } From d08ebc018770ab4f1429ebd872125a1027805876 Mon Sep 17 00:00:00 2001 From: Andrin Fassbind Date: Fri, 25 Mar 2022 21:58:23 +0100 Subject: [PATCH 3/3] code cleanup --- src/main/java/ch/zhaw/pm2/racetrack/PositionVector.java | 4 ++++ .../ch/zhaw/pm2/racetrack/strategy/DoNotMoveStrategy.java | 1 + .../zhaw/pm2/racetrack/strategy/PathFinderMoveStrategy.java | 2 ++ 3 files changed, 7 insertions(+) diff --git a/src/main/java/ch/zhaw/pm2/racetrack/PositionVector.java b/src/main/java/ch/zhaw/pm2/racetrack/PositionVector.java index c059038..a33302e 100644 --- a/src/main/java/ch/zhaw/pm2/racetrack/PositionVector.java +++ b/src/main/java/ch/zhaw/pm2/racetrack/PositionVector.java @@ -33,6 +33,7 @@ public final class PositionVector { /** * Adds two PositionVectors (e.g. car position and velocity vector or two velocity vectors). + * * @param vectorA A position or velocity vector * @param vectorB A position or velocity vector * @return A new PositionVector holding the result of the addition. If both @@ -45,6 +46,7 @@ public final class PositionVector { /** * Subtracts two PositionVectors (e.g. car position and velocity vector or two velocity vectors). + * * @param vectorA A position or velocity vector * @param vectorB A position or velocity vector * @return A new PositionVector holding the result of the addition. If both @@ -58,6 +60,7 @@ public final class PositionVector { /** * Calculates the scalar product (Skalarprodukt) of two 2D vectors. The scalar product * multiplies the lengths of the parallel components of the vectors. + * * @param vectorA A position or velocity vector * @param vectorB A position or velocity vector * @return The scalar product (vectorA * vectorB). Since vectorA and @@ -75,6 +78,7 @@ public final class PositionVector { /** * Copy constructor + * * @param other */ public PositionVector(final PositionVector other) { diff --git a/src/main/java/ch/zhaw/pm2/racetrack/strategy/DoNotMoveStrategy.java b/src/main/java/ch/zhaw/pm2/racetrack/strategy/DoNotMoveStrategy.java index ecfe157..ae9a050 100644 --- a/src/main/java/ch/zhaw/pm2/racetrack/strategy/DoNotMoveStrategy.java +++ b/src/main/java/ch/zhaw/pm2/racetrack/strategy/DoNotMoveStrategy.java @@ -11,6 +11,7 @@ public class DoNotMoveStrategy implements MoveStrategy { /** * This method will be used to return the next Direction for the car. + * * @return a NONE Direction */ @Override diff --git a/src/main/java/ch/zhaw/pm2/racetrack/strategy/PathFinderMoveStrategy.java b/src/main/java/ch/zhaw/pm2/racetrack/strategy/PathFinderMoveStrategy.java index cc3b6c7..c870b1f 100644 --- a/src/main/java/ch/zhaw/pm2/racetrack/strategy/PathFinderMoveStrategy.java +++ b/src/main/java/ch/zhaw/pm2/racetrack/strategy/PathFinderMoveStrategy.java @@ -23,6 +23,7 @@ public class PathFinderMoveStrategy implements MoveStrategy { /** * Constructor which initialises the needed variables and creates the MoveList + * * @param track track instance of the game * @param carIndex index of the car which owns this moveStrategy */ @@ -82,6 +83,7 @@ public class PathFinderMoveStrategy implements MoveStrategy { /** * Method to check if a State is already in List calculatedStates + * * @param state the State which should be checked * @return true if it is in List, false if it isn't in List */