Javadoc in PathFinderMoveStrategy.java

This commit is contained in:
romanschenk37 2022-03-25 10:52:32 +01:00
parent 483d800484
commit ff41150e44
1 changed files with 84 additions and 20 deletions

View File

@ -4,30 +4,49 @@ 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;
// List of directions to reach final line
private List<PositionVector.Direction> moveList;
// the index of the next move in moveList
private int pointer;
private List<PositionVector.Direction> 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<State> 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<PossibleMove> 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 +54,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<PossibleMove> 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 +79,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 +97,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 +128,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<PositionVector.Direction> 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 +179,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<PositionVector> points = track.calculatePointsOnPath(startPosition, endPosition);
for(PositionVector point : points) {
@ -139,10 +199,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() { //TODO check for crash and recreate movelist if crash
pointer += 1;
public PositionVector.Direction nextMove() {
if (pointer < moveList.size()) {
PositionVector.Direction direction = moveList.get(pointer);
PositionVector currentVelocity = track.getCarVelocity(carIndex);
@ -155,12 +218,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;
}