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 ch.zhaw.pm2.racetrack.Track;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
/**
* Strategy which calculates the path automatically
*/
public class PathFinderMoveStrategy implements MoveStrategy{ public class PathFinderMoveStrategy implements MoveStrategy{
private Track track; private Track track;
private int carIndex; private int carIndex;
// List of directions to reach final line
private List<PositionVector.Direction> moveList; private List<PositionVector.Direction> moveList;
// the index of the next move in moveList
private int pointer; 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; 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) { public PathFinderMoveStrategy(Track track, int carIndex) {
this.track = track; this.track = track;
this.carIndex = carIndex; this.carIndex = carIndex;
allDirections = Arrays.asList(PositionVector.Direction.values()); allDirections = PositionVector.Direction.values();
createMoveList(); createMoveList();
} }
/**
* Method to create a working moveList
*/
private void createMoveList(){ private void createMoveList(){
pointer = -1; // if Movelist is recreated next move will be the first move in moveList
pointer = 0;
calculatedStates = new ArrayList<>(); calculatedStates = new ArrayList<>();
PossibleMove finishedMove = null; PossibleMove finishedMove = null;
List<PossibleMove> possibleMoves= new ArrayList<>(); List<PossibleMove> 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); PossibleMove newMove = new PossibleMove(null, direction);
if(! newMove.crashed()){ 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){ while(finishedMove == null){
List<PossibleMove> newMoves = new ArrayList<>(); List<PossibleMove> newMoves = new ArrayList<>();
for(PossibleMove previousMove : possibleMoves){ for(PossibleMove previousMove : possibleMoves){
for(PositionVector.Direction direction : allDirections){ for(PositionVector.Direction direction : allDirections){
PossibleMove newMove = new PossibleMove(previousMove, direction); PossibleMove newMove = new PossibleMove(previousMove, direction);
State newState = new State(newMove.endPosition, newMove.endVelocity); 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.crashed() || alreadyCalculated(newState) || finishedMove != null)){
if(newMove.finished()){ if(newMove.finished()){
finishedMove = newMove; 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; 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){ private boolean alreadyCalculated(State state){
for(State calculatedState: calculatedStates){ for(State calculatedState: calculatedStates){
if(state.equals(calculatedState)){ if(state.equals(calculatedState)){
@ -70,15 +97,28 @@ public class PathFinderMoveStrategy implements MoveStrategy{
return false; return false;
} }
/**
* Combination of position and velocity
*/
public class State{ public class State{
PositionVector position; PositionVector position;
PositionVector velocity; 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.position = position;
this.velocity = velocity; 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){
if(compareState.position.equals(position) && compareState.velocity.equals(velocity)){ if(compareState.position.equals(position) && compareState.velocity.equals(velocity)){
return true; 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 { 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; List<PositionVector.Direction> directions;
// Position of the car bevor the move is executed
PositionVector startPosition; PositionVector startPosition;
// Position of the car after the move is executed
PositionVector endPosition; PositionVector endPosition;
// Velocity of the car after the move is executed
PositionVector endVelocity; 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){ public PossibleMove(PossibleMove previousMove, PositionVector.Direction nextDirection){
// Velocity of the car bevor the move is executed
PositionVector startVelocity; PositionVector startVelocity;
directions = new ArrayList<>(); directions = new ArrayList<>();
// check if there was a previousMove.
if(previousMove != null){ if(previousMove != null){
directions.addAll(previousMove.directions); directions.addAll(previousMove.directions); //copy the LIst of Directions from the previousMove
startPosition = previousMove.endPosition; startPosition = previousMove.endPosition; //use the endPosition from previousMove as startPosition
startVelocity = previousMove.endVelocity; startVelocity = previousMove.endVelocity; //use the endVelocity from previousMove as startVelocity
} }
else { else { //if there was no previousMove
startPosition = track.getCarPos(carIndex); startPosition = track.getCarPos(carIndex); //use the current Position of the car from track as startPosition
startVelocity = track.getCar(carIndex).getVelocity(); startVelocity = track.getCar(carIndex).getVelocity(); //use the current Velocity of the car from track as startVelocity
} }
directions.add(nextDirection); directions.add(nextDirection);
endVelocity = new PositionVector(startVelocity.getX() + nextDirection.vector.getX(), startVelocity.getY() + nextDirection.vector.getY()); endVelocity = new PositionVector(startVelocity.getX() + nextDirection.vector.getX(), startVelocity.getY() + nextDirection.vector.getY());
endPosition = new PositionVector(startPosition.getX() + endVelocity.getX(), startPosition.getY() + endVelocity.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(){ public boolean finished(){
if(track.calculateNewWinPoints(startPosition, endPosition) == 1){ if(track.calculateNewWinPoints(startPosition, endPosition) == 1){
return true; 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() { public boolean crashed() {
List<PositionVector> points = track.calculatePointsOnPath(startPosition, endPosition); List<PositionVector> points = track.calculatePointsOnPath(startPosition, endPosition);
for(PositionVector point : points) { 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 @Override
public PositionVector.Direction nextMove() { //TODO check for crash and recreate movelist if crash public PositionVector.Direction nextMove() {
pointer += 1;
if (pointer < moveList.size()) { if (pointer < moveList.size()) {
PositionVector.Direction direction = moveList.get(pointer); PositionVector.Direction direction = moveList.get(pointer);
PositionVector currentVelocity = track.getCarVelocity(carIndex); PositionVector currentVelocity = track.getCarVelocity(carIndex);
@ -155,12 +218,13 @@ public class PathFinderMoveStrategy implements MoveStrategy{
if(track.willCrashAtPosition(carIndex, point)){ if(track.willCrashAtPosition(carIndex, point)){
createMoveList(); createMoveList();
pointer = 0; pointer = 0;
direction = moveList.get(pointer);
break; break;
} }
} }
pointer += 1;
return moveList.get(pointer); return direction;
} }
return null; return null;
} }