diff --git a/build.gradle b/build.gradle index 37dcb87..669126f 100644 --- a/build.gradle +++ b/build.gradle @@ -29,6 +29,7 @@ dependencies { // beryx uses SLF4J. To remove warning, we add the implementation "no operation" implementation 'org.slf4j:slf4j-nop:2.+' + implementation 'junit:junit:4.13.1' // Use JUnit Jupiter API for testing. testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' diff --git a/src/main/java/ch/zhaw/pm2/racetrack/Game.java b/src/main/java/ch/zhaw/pm2/racetrack/Game.java index 3e15501..c969298 100644 --- a/src/main/java/ch/zhaw/pm2/racetrack/Game.java +++ b/src/main/java/ch/zhaw/pm2/racetrack/Game.java @@ -145,6 +145,8 @@ public class Game implements GameSpecification { throw new UnsupportedOperationException(); } + + /** * Does indicate if a car would have a crash with a WALL space or another car at the given position. * @param carIndex The zero-based carIndex number @@ -153,7 +155,8 @@ public class Game implements GameSpecification { */ @Override public boolean willCarCrash(int carIndex, PositionVector position) { - // TODO: implementation - throw new UnsupportedOperationException(); + + + return true; } } diff --git a/src/main/java/ch/zhaw/pm2/racetrack/Track.java b/src/main/java/ch/zhaw/pm2/racetrack/Track.java index 61deadf..e89b960 100644 --- a/src/main/java/ch/zhaw/pm2/racetrack/Track.java +++ b/src/main/java/ch/zhaw/pm2/racetrack/Track.java @@ -1,9 +1,14 @@ package ch.zhaw.pm2.racetrack; +import ch.zhaw.pm2.racetrack.given.ConfigSpecification; import ch.zhaw.pm2.racetrack.given.TrackSpecification; import java.io.File; import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; /** * This class represents the racetrack board. @@ -56,6 +61,9 @@ public class Track implements TrackSpecification { public static final char CRASH_INDICATOR = 'X'; // TODO: Add necessary variables + private List track; + private List cars; + private List finishLine; /** * Initialize a Track from the given track file. @@ -65,8 +73,162 @@ public class Track implements TrackSpecification { * @throws InvalidTrackFormatException if the track file contains invalid data (no tracklines, ...) */ public Track(File trackFile) throws FileNotFoundException, InvalidTrackFormatException { - // TODO: implementation - throw new UnsupportedOperationException(); + track = new ArrayList<>(); + cars = new ArrayList<>(); + finishLine = new ArrayList<>(); + readFile(trackFile); + findFinish(); + addCars(); + } + + /** + * This method reads the File and saves it to the track ArrayList Line by Line + * + * @param trackFile the File where the track has been documented + * @throws FileNotFoundException if the FilePath is invalid. + */ + private void readFile(File trackFile) throws FileNotFoundException { + Scanner scanner = new Scanner(trackFile); + while (scanner.hasNextLine()) { + track.add(scanner.nextLine()); + } + } + + + private void addCars() throws InvalidTrackFormatException { + ConfigSpecification.SpaceType[] spaceTypes = ConfigSpecification.SpaceType.values(); + List allSpaceTypesAsChar = new ArrayList<>(); + List usedSymbolForCar = new ArrayList<>(); + + for (ConfigSpecification.SpaceType spaceType : spaceTypes) { + allSpaceTypesAsChar.add(spaceType.getValue()); + } + + + for (int j = 0; j < track.size(); j++) { + String line = track.get(j); + for (int i = 0; i < line.length(); i++) { + char possibleCarChar = line.charAt(i); + if (!allSpaceTypesAsChar.contains(possibleCarChar)) { + if (usedSymbolForCar.contains(possibleCarChar)) { + throw new InvalidTrackFormatException(); + } + usedSymbolForCar.add(possibleCarChar); + cars.add(new Car(possibleCarChar, new PositionVector(i, j))); + } + } + } + + } + + private void findFinish() throws InvalidTrackFormatException { + for (int i = 0; i < track.size(); i++) { + String line = track.get(i); + for (int j = 0; j < line.length(); j++) { + if (line.charAt(j) == ConfigSpecification.SpaceType.FINISH_LEFT.getValue() || + line.charAt(j) == ConfigSpecification.SpaceType.FINISH_RIGHT.getValue() || + line.charAt(j) == ConfigSpecification.SpaceType.FINISH_DOWN.getValue() || + line.charAt(j) == ConfigSpecification.SpaceType.FINISH_UP.getValue()) { + finishLine.add(new PositionVector(j, i)); + } + } + } + if (finishLine.size() == 0) { + throw new InvalidTrackFormatException(); + } + ConfigSpecification.SpaceType finishTyp = getSpaceType(finishLine.get(0)); + for (PositionVector positionVector : finishLine) { + if (getSpaceType(positionVector) != finishTyp) { + throw new InvalidTrackFormatException(); + } + } + } + + private PositionVector findChar(char symbol) { + PositionVector vector = null; + for (int i = 0; i < track.size(); i++) { + String line = track.get(i); + for (int j = 0; j < line.length(); j++) { + if (line.charAt(j) == symbol) { + vector = new PositionVector(j, i); + } + } + } + return vector; + } + + private void drawCharOnTrackIndicator(PositionVector positionVector, char symbol) { + String line = track.get(positionVector.getY()); + line = line.substring(0,positionVector.getX()) + symbol + line.substring(positionVector.getX()+1); + track.add(positionVector.getY(),line); + } + + /** + * @return all Cars + */ + public List getCars() { + return cars; + } + + /** + * @return finishLine + */ + public List getFinishLine() { + return finishLine; + } + + /** + * @return the track + */ + public List getTrack() { + return track; + } + + /** + * This Method will update the Car on the track + * and will make the Car move to the next position + * @param carIndex representing the current Car + */ + public void moveCar(int carIndex) { + makeCarMoveInTrack(carIndex); + //Change position of car + getCar(carIndex).move(); + } + + /** + * This class does change the Position of the car only in the track. + * @param carIndex + */ + private void makeCarMoveInTrack(int carIndex) { + PositionVector positionVector = findChar(getCarId(carIndex)); + //Removes the Car at Current Pos + drawCharOnTrackIndicator(positionVector,ConfigSpecification.SpaceType.TRACK.getValue()); + //Adds Car at new Position + positionVector = cars.get(carIndex).nextPosition(); + drawCharOnTrackIndicator(positionVector,cars.get(carIndex).getID()); + } + + /** + * This Method will check if the Car could crash at the specific position + * @param positionVector the position to check if the car could crash + * @return true if car would crash. Else false. + */ + public boolean willCrashAtPosition(PositionVector positionVector) { + char charAtPosition = track.get(positionVector.getY()).charAt(positionVector.getX()); + return charAtPosition != ConfigSpecification.SpaceType.TRACK.value; + } + + /** + * This Method will make the Car Crash. In Track and in the Car Object + * @param carIndex representing current Car + * @param positionVector where the Crash did happen + */ + public void carDoesCrash(int carIndex,PositionVector positionVector) { + Car car = cars.get(carIndex); + car.crash(); + makeCarMoveInTrack(carIndex); + drawCharOnTrackIndicator(new PositionVector(positionVector.getX()+1,positionVector.getY()),CRASH_INDICATOR); + } /** @@ -78,8 +240,17 @@ public class Track implements TrackSpecification { */ @Override public Config.SpaceType getSpaceType(PositionVector position) { - // TODO: implementation - throw new UnsupportedOperationException(); + + char charAtPosition = track.get(position.getY()).charAt(position.getX()); + + ConfigSpecification.SpaceType[] spaceTypes = ConfigSpecification.SpaceType.values(); + for (ConfigSpecification.SpaceType spaceType : spaceTypes) { + if (spaceType.getValue() == charAtPosition) { + return spaceType; + } + } + + return null; } /** @@ -89,8 +260,7 @@ public class Track implements TrackSpecification { */ @Override public int getCarCount() { - // TODO: implementation - throw new UnsupportedOperationException(); + return cars.size(); } /** @@ -101,8 +271,7 @@ public class Track implements TrackSpecification { */ @Override public Car getCar(int carIndex) { - // TODO: implementation - throw new UnsupportedOperationException(); + return cars.get(carIndex); } /** @@ -113,20 +282,19 @@ public class Track implements TrackSpecification { */ @Override public char getCarId(int carIndex) { - // TODO: implementation - throw new UnsupportedOperationException(); + return cars.get(carIndex).getID(); } /** * Get the position of the specified car. + * Returns Null if carIndex not valid * * @param carIndex The zero-based carIndex number * @return A PositionVector containing the car's current position */ @Override public PositionVector getCarPos(int carIndex) { - // TODO: implementation - throw new UnsupportedOperationException(); + return findChar(cars.get(carIndex).getID()); } /** @@ -137,8 +305,7 @@ public class Track implements TrackSpecification { */ @Override public PositionVector getCarVelocity(int carIndex) { - // TODO: implementation - throw new UnsupportedOperationException(); + return cars.get(carIndex).getVelocity(); } /** @@ -152,8 +319,16 @@ public class Track implements TrackSpecification { */ @Override public char getCharAtPosition(int y, int x, Config.SpaceType currentSpace) { - // TODO: implementation - throw new UnsupportedOperationException(); + char charAtPos = track.get(y).charAt(x); + for (Car car : cars) { + if(charAtPos == car.getID()) { + if(car.isCrashed()) { + return CRASH_INDICATOR; + } + return charAtPos; + } + } + return currentSpace.getValue(); } /** @@ -163,7 +338,10 @@ public class Track implements TrackSpecification { */ @Override public String toString() { - // TODO: implementation - throw new UnsupportedOperationException(); + String str = ""; + for (String line : track) { + str += line + "\n"; + } + return str; } } diff --git a/src/test/java/ch/zhaw/pm2/racetrack/TrackTest.java b/src/test/java/ch/zhaw/pm2/racetrack/TrackTest.java new file mode 100644 index 0000000..a4decfb --- /dev/null +++ b/src/test/java/ch/zhaw/pm2/racetrack/TrackTest.java @@ -0,0 +1,78 @@ +package ch.zhaw.pm2.racetrack; + +import ch.zhaw.pm2.racetrack.given.ConfigSpecification; +import org.junit.Before; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.List; + + +public class TrackTest { + Track trackObj; + + @BeforeEach + void setup() { + File file = new File("C:\\Studium\\Semester2\\PM2\\Projekt1\\racetrack\\tracks\\challenge.txt"); + try { + trackObj = new Track(file); + + } catch (Exception e) { + System.err.println("Error in Test compareTrack" + e.getMessage()); + } + } + + @Test + void canReadFile() { + File file = new File("C:\\Studium\\Semester2\\PM2\\Projekt1\\racetrack\\tracks\\challenge.txt"); + Assertions.assertThrows(FileNotFoundException.class,() -> new Track(file)); + } + + /** + * Dirty test... + */ + @Test + void printOutTrack() { + System.out.println(trackObj); + } + + @Test + void getSpaceTyp() { + Assertions.assertEquals(ConfigSpecification.SpaceType.FINISH_RIGHT,trackObj.getSpaceType(new PositionVector(22,24))); + } + + //TODO: + @Test + void addCarAtInit() { + try { + trackObj.addCar(); + } catch (InvalidTrackFormatException e) { + e.printStackTrace(); + } + + } + + @Test + void findFinish() { + List expected = new ArrayList<>(); + expected.add(new PositionVector(22,22)); + expected.add(new PositionVector(22,23)); + expected.add(new PositionVector(22,24)); + Assertions.assertEquals(expected,trackObj.getFinishLine()); + } + + @Test + void makeTrackObj() { + try { + Track t1 = new Track(new File("C:\\Studium\\Semester2\\PM2\\Projekt1\\racetrack\\tracks\\challenge.txt")); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (InvalidTrackFormatException e) { + e.printStackTrace(); + } + } +}