Merge pull request #31 from PM2-IT21bWIN-ruiz-mach-krea/Strategy

Strategy
This commit is contained in:
romanschenk37 2022-03-25 09:24:21 +01:00 committed by GitHub Enterprise
commit 483d800484
4 changed files with 237 additions and 13 deletions

View File

@ -54,6 +54,7 @@ public class Game implements GameSpecification {
moveStrategies.add("User Move Strategy"); moveStrategies.add("User Move Strategy");
moveStrategies.add("Move List Strategy"); moveStrategies.add("Move List Strategy");
moveStrategies.add("Path Follow Move Strategy"); moveStrategies.add("Path Follow Move Strategy");
moveStrategies.add("Path Finder Move Strategy");
for (int i = 0; i < track.getCarCount(); i++) { for (int i = 0; i < track.getCarCount(); i++) {
Car car = track.getCar(i); Car car = track.getCar(i);
MoveStrategy moveStrategy = null; MoveStrategy moveStrategy = null;
@ -61,14 +62,14 @@ public class Game implements GameSpecification {
String filePath; String filePath;
int moveStrategie = userInterface.selectOption( int moveStrategie = userInterface.selectOption(
"Select Strategy for Car " + i + " (" + track.getCarId(i) + ")", moveStrategies); "Select Strategy for Car " + i + " (" + track.getCarId(i) + ")", moveStrategies);
switch (moveStrategie + 1) { switch (moveStrategie) {
case 1: case 0:
moveStrategy = new DoNotMoveStrategy(); moveStrategy = new DoNotMoveStrategy();
break; break;
case 2: case 1:
moveStrategy = new UserMoveStrategy(userInterface, i, track.getCarId(i)); moveStrategy = new UserMoveStrategy(userInterface, i, track.getCarId(i));
break; break;
case 3: case 2:
filePath = ".\\moves\\" + selectedTrack.getName().split("\\.")[0] + "-car-" + track.getCar(i).getID() + ".txt"; filePath = ".\\moves\\" + selectedTrack.getName().split("\\.")[0] + "-car-" + track.getCar(i).getID() + ".txt";
try { try {
moveStrategy = new MoveListStrategy(filePath); moveStrategy = new MoveListStrategy(filePath);
@ -76,7 +77,7 @@ public class Game implements GameSpecification {
userInterface.printInformation("There is no Move-List implemented. Choose another Strategy!"); userInterface.printInformation("There is no Move-List implemented. Choose another Strategy!");
} }
break; break;
case 4: case 3:
filePath = ".\\follower\\" + selectedTrack.getName().split("\\.")[0] + "_points.txt"; filePath = ".\\follower\\" + selectedTrack.getName().split("\\.")[0] + "_points.txt";
try { try {
moveStrategy = new PathFollowerMoveStrategy(filePath, track.getCarPos(i)); moveStrategy = new PathFollowerMoveStrategy(filePath, track.getCarPos(i));
@ -84,6 +85,9 @@ public class Game implements GameSpecification {
userInterface.printInformation("There is no Point-List implemented. Choose another Strategy!"); userInterface.printInformation("There is no Point-List implemented. Choose another Strategy!");
} }
break; break;
case 4:
moveStrategy = new PathFinderMoveStrategy(track, i);
break;
} }
} }
selectMoveStrategy(car, moveStrategy); selectMoveStrategy(car, moveStrategy);
@ -165,14 +169,14 @@ public class Game implements GameSpecification {
*/ */
@Override @Override
public int getWinner() { public int getWinner() {
if (onlyOneCarLeft()) {
return currentCarIndex;
}
for (int i = 0; i < track.getCarCount(); i++) { for (int i = 0; i < track.getCarCount(); i++) {
if (track.getCar(i).getWinPoints() == 1) { if (track.getCar(i).getWinPoints() == 1) {
return i; return i;
} }
} }
if (onlyOneCarLeft()) {
return currentCarIndex;
}
return NO_WINNER; return NO_WINNER;
} }
@ -217,10 +221,15 @@ public class Game implements GameSpecification {
break; break;
} }
} }
int newWinPoints = track.calculateNewWinPoints(track.getCarPos(currentCarIndex), track.getCar(currentCarIndex).nextPosition());
if(newWinPoints == 1){
track.getCar(currentCarIndex).increaseWinPoints();
}else if(newWinPoints == -1){
track.getCar(currentCarIndex).deductWinPoints();
}
if (crashPosition != null) { if (crashPosition != null) {
track.carDoesCrash(currentCarIndex, crashPosition); track.carDoesCrash(currentCarIndex, crashPosition);
} else { } else {
calculateWinner(track.getCarPos(currentCarIndex), track.getCar(currentCarIndex).nextPosition(), currentCarIndex);
track.moveCar(currentCarIndex); track.moveCar(currentCarIndex);
} }
} }

View File

@ -123,6 +123,7 @@ public class Track implements TrackSpecification {
} }
} }
//TODO: THIS
/** /**
* Determines the finish line and saves it in a list, throws an Exception if none is found. * Determines the finish line and saves it in a list, throws an Exception if none is found.
@ -276,8 +277,6 @@ public class Track implements TrackSpecification {
*/ */
@Override @Override
public Config.SpaceType getSpaceType(PositionVector position) { public Config.SpaceType getSpaceType(PositionVector position) {
//TODO: TO BE DELETED??
//isPositionVectorOnTrack(position); Should be used but we are not allowed to change method head. We don't use function anyway
char charAtPosition = track.get(position.getY()).charAt(position.getX()); char charAtPosition = track.get(position.getY()).charAt(position.getX());
ConfigSpecification.SpaceType[] spaceTypes = ConfigSpecification.SpaceType.values(); ConfigSpecification.SpaceType[] spaceTypes = ConfigSpecification.SpaceType.values();
for (ConfigSpecification.SpaceType spaceType : spaceTypes) { for (ConfigSpecification.SpaceType spaceType : spaceTypes) {
@ -286,7 +285,7 @@ public class Track implements TrackSpecification {
} }
} }
return null; return ConfigSpecification.SpaceType.WALL;
} }
/** /**
@ -432,6 +431,53 @@ public class Track implements TrackSpecification {
return pathList; return pathList;
} }
/**
* 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
* @return Number of new Winpoints for the current player.
*/
public int calculateNewWinPoints(PositionVector start, PositionVector finish) {
List<PositionVector> path = calculatePointsOnPath(start, finish);
for (PositionVector point : path) {
switch (getSpaceType(point)) {
case FINISH_UP:
if (start.getY() > finish.getY()) {
return 1;
} else if (start.getY() < finish.getY()) {
return -1;
}
break;
case FINISH_DOWN:
if (start.getY() < finish.getY()) {
return 1;
} else if (start.getY() > finish.getY()) {
return -1;
}
break;
case FINISH_RIGHT:
if (start.getX() < finish.getX()) {
return 1;
} else if (start.getX() > finish.getX()) {
return -1;
}
break;
case FINISH_LEFT:
if (start.getX() > finish.getX()) {
return 1;
} else if (start.getX() < finish.getX()) {
return -1;
}
break;
}
}
return 0;
}
/** /**
* Return a String representation of the track, including the car locations. * Return a String representation of the track, including the car locations.
* *

View File

@ -0,0 +1,169 @@
package ch.zhaw.pm2.racetrack.strategy;
import ch.zhaw.pm2.racetrack.PositionVector;
import ch.zhaw.pm2.racetrack.Track;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class PathFinderMoveStrategy implements MoveStrategy{
private Track track;
private int carIndex;
private List<PositionVector.Direction> moveList;
private int pointer;
private List<PositionVector.Direction> allDirections;
private List<State> calculatedStates;
public PathFinderMoveStrategy(Track track, int carIndex) {
this.track = track;
this.carIndex = carIndex;
allDirections = Arrays.asList(PositionVector.Direction.values());
createMoveList();
}
private void createMoveList(){
pointer = -1;
calculatedStates = new ArrayList<>();
PossibleMove finishedMove = null;
List<PossibleMove> possibleMoves= new ArrayList<>();
for(PositionVector.Direction direction : allDirections){
PossibleMove newMove = new PossibleMove(null, direction);
if(! newMove.crashed()){
possibleMoves.add(newMove);
}
}
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);
if(! (newMove.crashed() || alreadyCalculated(newState) || finishedMove != null)){
if(newMove.finished()){
finishedMove = newMove;
} else {
calculatedStates.add(newState);
newMoves.add(newMove);
}
}
}
}
possibleMoves = newMoves;
}
moveList = finishedMove.directions;
}
private boolean alreadyCalculated(State state){
for(State calculatedState: calculatedStates){
if(state.equals(calculatedState)){
return true;
}
}
return false;
}
public class State{
PositionVector position;
PositionVector velocity;
public State(PositionVector position, PositionVector velocity){
this.position = position;
this.velocity = velocity;
}
public boolean equals(State compareState){
if(compareState.position.equals(position) && compareState.velocity.equals(velocity)){
return true;
} else{
return false;
}
}
}
public class PossibleMove {
List<PositionVector.Direction> directions;
PositionVector startPosition;
PositionVector endPosition;
PositionVector endVelocity;
public PossibleMove(PossibleMove previousMove, PositionVector.Direction nextDirection){
PositionVector startVelocity;
directions = new ArrayList<>();
if(previousMove != null){
directions.addAll(previousMove.directions);
startPosition = previousMove.endPosition;
startVelocity = previousMove.endVelocity;
}
else {
startPosition = track.getCarPos(carIndex);
startVelocity = track.getCar(carIndex).getVelocity();
}
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());
}
public boolean finished(){
if(track.calculateNewWinPoints(startPosition, endPosition) == 1){
return true;
}
else{
return false;
}
}
public boolean crashed() {
List<PositionVector> points = track.calculatePointsOnPath(startPosition, endPosition);
for(PositionVector point : points) {
if (track.willCrashAtPosition(carIndex, point)){
return true;
}
}
if(track.calculateNewWinPoints(startPosition, endPosition) == -1){
return true;
}
return false;
}
}
@Override
public PositionVector.Direction nextMove() { //TODO check for crash and recreate movelist if crash
pointer += 1;
if (pointer < moveList.size()) {
PositionVector.Direction direction = moveList.get(pointer);
PositionVector currentVelocity = track.getCarVelocity(carIndex);
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());
System.out.println("currentVelocity:" + currentVelocity.getX()+ ","+ currentVelocity.getY());
System.out.println("newVelocity:" + newVelocity.getX()+ ","+ newVelocity.getY());
for(PositionVector point : track.calculatePointsOnPath(currentPosition, newPosition)){
if(track.willCrashAtPosition(carIndex, point)){
createMoveList();
pointer = 0;
break;
}
}
return moveList.get(pointer);
}
return null;
}
}

View File

@ -178,7 +178,7 @@ class GameTest {
@Test @Test
void crashA() { void crashA() {
game = new Game(new interFace("Test",new Integer[]{0,1,1},new PositionVector.Direction[]{UP})); game = new Game(new interFace("Test",new Integer[]{0,1,0},new PositionVector.Direction[]{UP}));
game.initPhase(); game.initPhase();
Assertions.assertEquals("b",game.gamePhase()); Assertions.assertEquals("b",game.gamePhase());
} }