diff --git a/README.md b/README.md
index 340f147..e448534 100644
--- a/README.md
+++ b/README.md
@@ -38,7 +38,7 @@ And every other character represents a car.
The winner gets determined automatically.
The car that first passes the finish line (doing a complete round) is given the win, if all car except one crash the surviving car will be crowned as the winner.
The game will inform you of this, and you will have the option to quit the game or play another match.
## Branching Model
-We choose a simple branching model where all starting features got a branch and where merged into the main branch, some branches who needed unfinished code to be completed where taken from the game branch but merged into the main at the end as well.
Since there was just one end product we abstained from using a development branch and merges where done straight into main branch.
+We choose a simple branching model where all starting features got a branch and where merged into the main branch, some branches who needed unfinished code to be completed where taken from the game branch but merged into the main at the end as well.
Since there was just one end product we abstained from using a development branch and merges where done straight into main branch.
Commits which contain only documentation and doesn't change any functionality are committed directly into the Main branch.
## Class Diagramm
![Classdiagramm of this program](/Klassendiagramm.drawio)
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 2b42b5b..1fc056f 100644
--- a/src/main/java/ch/zhaw/pm2/racetrack/strategy/PathFinderMoveStrategy.java
+++ b/src/main/java/ch/zhaw/pm2/racetrack/strategy/PathFinderMoveStrategy.java
@@ -4,30 +4,46 @@ import ch.zhaw.pm2.racetrack.PositionVector;
import ch.zhaw.pm2.racetrack.Track;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
+/**
+ * Strategy which calculates the path automatically
+ */
public class PathFinderMoveStrategy implements MoveStrategy{
private Track track;
private int carIndex;
private List moveList;
+ // the index of the next move in moveList
private int pointer;
- private List allDirections;
+ // all Directions which can be used for acceleration
+ private PositionVector.Direction[] allDirections;
+ // List of all States (combination of Position and Velocity) which are already reached with a calculated move.
private List calculatedStates;
+ /**
+ * 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
+ */
public PathFinderMoveStrategy(Track track, int carIndex) {
this.track = track;
this.carIndex = carIndex;
- allDirections = Arrays.asList(PositionVector.Direction.values());
+ allDirections = PositionVector.Direction.values();
createMoveList();
}
+ /**
+ * Method to create a working moveList
+ */
private void createMoveList(){
- pointer = -1;
+ // 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<>();
+
+ // create a PossibleMove object for each direction which doesn't end with a crash.
for(PositionVector.Direction direction : allDirections){
PossibleMove newMove = new PossibleMove(null, direction);
if(! newMove.crashed()){
@@ -35,12 +51,17 @@ 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){
List newMoves = new ArrayList<>();
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 doen'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;
@@ -55,12 +76,15 @@ public class PathFinderMoveStrategy implements MoveStrategy{
}
-
+ // if a finished Move is found save it's directions as moveList
moveList = finishedMove.directions;
-
-
}
+ /**
+ * 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
+ */
private boolean alreadyCalculated(State state){
for(State calculatedState: calculatedStates){
if(state.equals(calculatedState)){
@@ -70,15 +94,28 @@ public class PathFinderMoveStrategy implements MoveStrategy{
return false;
}
+ /**
+ * Combination of position and velocity
+ */
public class State{
PositionVector position;
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){
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){
if(compareState.position.equals(position) && compareState.velocity.equals(velocity)){
return true;
@@ -88,32 +125,48 @@ public class PathFinderMoveStrategy implements MoveStrategy{
}
}
-
+ /**
+ * PossibleMove represents a move which can be done by the player.
+ */
public class PossibleMove {
+ // List of all directions used for the previous moves and the direction of the current move (the highest Index).
List directions;
+ // Position of the car bevor the move is executed
PositionVector startPosition;
+ // Position of the car after the move is executed
PositionVector endPosition;
+ // Velocity of the car after the move is executed
PositionVector endVelocity;
-
+ /**
+ * Constructor of PossibleMove
+ * @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){
+ // Velocity of the car bevor the move is executed
PositionVector startVelocity;
directions = new ArrayList<>();
+ // check if there was a previousMove.
if(previousMove != null){
- directions.addAll(previousMove.directions);
- startPosition = previousMove.endPosition;
- startVelocity = previousMove.endVelocity;
+ 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 {
- startPosition = track.getCarPos(carIndex);
- startVelocity = track.getCar(carIndex).getVelocity();
+ 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
}
directions.add(nextDirection);
endVelocity = new PositionVector(startVelocity.getX() + nextDirection.vector.getX(), startVelocity.getY() + nextDirection.vector.getY());
endPosition = new PositionVector(startPosition.getX() + endVelocity.getX(), startPosition.getY() + endVelocity.getY());
}
+ /**
+ * check if the finishline is crossed (in correct direction) if this move is executed
+ * @return true if finishline will be crossed
+ */
public boolean finished(){
if(track.calculateNewWinPoints(startPosition, endPosition) == 1){
return true;
@@ -123,6 +176,10 @@ public class PathFinderMoveStrategy implements MoveStrategy{
}
}
+ /**
+ * 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) {
@@ -139,10 +196,13 @@ 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
public PositionVector.Direction nextMove() {
- pointer += 1;
if (pointer < moveList.size()) {
PositionVector.Direction direction = moveList.get(pointer);
PositionVector currentVelocity = track.getCarVelocity(carIndex);
@@ -155,12 +215,13 @@ public class PathFinderMoveStrategy implements MoveStrategy{
if(track.willCrashAtPosition(carIndex, point)){
createMoveList();
pointer = 0;
+ direction = moveList.get(pointer);
break;
}
}
-
- return moveList.get(pointer);
+ pointer += 1;
+ return direction;
}
return null;
}