diff --git a/src/main/java/ch/zhaw/pm2/racetrack/Game.java b/src/main/java/ch/zhaw/pm2/racetrack/Game.java index b7715fa..7530831 100644 --- a/src/main/java/ch/zhaw/pm2/racetrack/Game.java +++ b/src/main/java/ch/zhaw/pm2/racetrack/Game.java @@ -54,6 +54,7 @@ public class Game implements GameSpecification { moveStrategies.add("User Move Strategy"); moveStrategies.add("Move List Strategy"); moveStrategies.add("Path Follow Move Strategy"); + moveStrategies.add("Path Finder Move Strategy"); for (int i = 0; i < track.getCarCount(); i++) { Car car = track.getCar(i); MoveStrategy moveStrategy = null; @@ -61,14 +62,14 @@ public class Game implements GameSpecification { String filePath; int moveStrategie = userInterface.selectOption( "Select Strategy for Car " + i + " (" + track.getCarId(i) + ")", moveStrategies); - switch (moveStrategie + 1) { - case 1: + switch (moveStrategie) { + case 0: moveStrategy = new DoNotMoveStrategy(); break; - case 2: + case 1: moveStrategy = new UserMoveStrategy(userInterface, i, track.getCarId(i)); break; - case 3: + case 2: filePath = ".\\moves\\" + selectedTrack.getName().split("\\.")[0] + "-car-" + track.getCar(i).getID() + ".txt"; try { moveStrategy = new MoveListStrategy(filePath); @@ -76,7 +77,7 @@ public class Game implements GameSpecification { userInterface.printInformation("There is no Move-List implemented. Choose another Strategy!"); } break; - case 4: + case 3: filePath = ".\\follower\\" + selectedTrack.getName().split("\\.")[0] + "_points.txt"; try { 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!"); } break; + case 4: + moveStrategy = new PathFinderMoveStrategy(track, i); + break; } } selectMoveStrategy(car, moveStrategy); @@ -165,14 +169,14 @@ public class Game implements GameSpecification { */ @Override public int getWinner() { - if (onlyOneCarLeft()) { - return currentCarIndex; - } for (int i = 0; i < track.getCarCount(); i++) { if (track.getCar(i).getWinPoints() == 1) { return i; } } + if (onlyOneCarLeft()) { + return currentCarIndex; + } return NO_WINNER; } @@ -217,10 +221,15 @@ public class Game implements GameSpecification { 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) { track.carDoesCrash(currentCarIndex, crashPosition); } else { - calculateWinner(track.getCarPos(currentCarIndex), track.getCar(currentCarIndex).nextPosition(), currentCarIndex); track.moveCar(currentCarIndex); } } diff --git a/src/main/java/ch/zhaw/pm2/racetrack/Track.java b/src/main/java/ch/zhaw/pm2/racetrack/Track.java index 0f36149..0be8237 100644 --- a/src/main/java/ch/zhaw/pm2/racetrack/Track.java +++ b/src/main/java/ch/zhaw/pm2/racetrack/Track.java @@ -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. @@ -276,8 +277,6 @@ public class Track implements TrackSpecification { */ @Override 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()); ConfigSpecification.SpaceType[] spaceTypes = ConfigSpecification.SpaceType.values(); 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; } + /** + * 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 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. * diff --git a/src/main/java/ch/zhaw/pm2/racetrack/strategy/PathFinderMoveStrategy.java b/src/main/java/ch/zhaw/pm2/racetrack/strategy/PathFinderMoveStrategy.java new file mode 100644 index 0000000..4148124 --- /dev/null +++ b/src/main/java/ch/zhaw/pm2/racetrack/strategy/PathFinderMoveStrategy.java @@ -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 moveList; + private int pointer; + private List allDirections; + private List 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 possibleMoves= new ArrayList<>(); + for(PositionVector.Direction direction : allDirections){ + PossibleMove newMove = new PossibleMove(null, direction); + if(! newMove.crashed()){ + possibleMoves.add(newMove); + } + + } + 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); + 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 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 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; + } + + +} diff --git a/src/test/java/ch/zhaw/pm2/racetrack/GameTest.java b/src/test/java/ch/zhaw/pm2/racetrack/GameTest.java index 77b9148..2156708 100644 --- a/src/test/java/ch/zhaw/pm2/racetrack/GameTest.java +++ b/src/test/java/ch/zhaw/pm2/racetrack/GameTest.java @@ -178,7 +178,7 @@ class GameTest { @Test 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(); Assertions.assertEquals("b",game.gamePhase()); }