Javadoc in PathFinderMoveStrategy.java
This commit is contained in:
parent
483d800484
commit
ff41150e44
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue