Merge remote-tracking branch 'origin/main'

# Conflicts:
#	src/main/java/ch/zhaw/pm2/racetrack/Game.java
#	src/main/java/ch/zhaw/pm2/racetrack/Track.java
This commit is contained in:
Andrin Fassbind 2022-03-24 16:57:00 +01:00
commit 80b07111de
10 changed files with 129 additions and 82 deletions

View File

@ -3,14 +3,12 @@ package ch.zhaw.pm2.racetrack;
import ch.zhaw.pm2.racetrack.given.CarSpecification;
import ch.zhaw.pm2.racetrack.strategy.MoveStrategy;
import java.util.Vector;
/**
* Class representing a car on the racetrack.
* Uses {@link PositionVector} to store current position on the track grid and current velocity vector.
* Each car has an identifier character which represents the car on the racetrack board.
* Also keeps the state, if the car is crashed (not active anymore). The state can not be changed back to uncrashed.
* The velocity is changed by providing an acelleration vector.
* The velocity is changed by providing an acceleration vector.
* The car is able to calculate the endpoint of its next position and on request moves to it.
*/
public class Car implements CarSpecification {
@ -46,6 +44,7 @@ public class Car implements CarSpecification {
/**
* Constructor for class Car
*
* @param id unique Car identification
* @param position initial position of the Car
*/
@ -83,6 +82,7 @@ public class Car implements CarSpecification {
public PositionVector getVelocity() {
return velocity;
}
/**
* Set this Car position directly, regardless of current position and velocity.
* This should only be used by the game controller in rare cases to set the crash or winning position.
@ -95,8 +95,7 @@ public class Car implements CarSpecification {
public void setPosition(final PositionVector position) {
if (position.getX() < 0 || position.getY() < 0) {
throw new IllegalArgumentException();
}
else {
} else {
this.position = position;
}
}
@ -126,8 +125,7 @@ public class Car implements CarSpecification {
if (acceleration.vector.getX() < -1 || acceleration.vector.getX() > 1 ||
acceleration.vector.getY() < -1 || acceleration.vector.getY() > 1) {
throw new IllegalArgumentException();
}
else {
} else {
velocity = new PositionVector(velocity.getX() + acceleration.vector.getX(),
velocity.getY() + acceleration.vector.getY());
}
@ -161,6 +159,7 @@ public class Car implements CarSpecification {
/**
* Set move strategy
*
* @param moveStrategy Strategy to be implemented
*/
public void setMoveStrategy(MoveStrategy moveStrategy) {
@ -169,6 +168,7 @@ public class Car implements CarSpecification {
/**
* Get current move strategy
*
* @return MoveStrategy
*/
public MoveStrategy getMoveStrategy() {

View File

@ -18,8 +18,7 @@ public class Main {
String winnerText;
if (winner == null) {
winnerText = "There was no winner.";
}
else {
} else {
winnerText = "The Winner was Car " + winner;
}
int selectedOption = userInterface.selectOption(winnerText + "\nStart new Game?", optionsNewGame);
@ -27,8 +26,7 @@ public class Main {
userInterface.quit("Thank you and goodbye\npress enter to close the application.");
break;
}
}
else {
} else {
userInterface.quit("The initialisation of the game failed. Press enter to close the application.");
break;
}

View File

@ -7,8 +7,8 @@ package ch.zhaw.pm2.racetrack;
* Created by mach 21.01.2020
*/
public final class PositionVector {
private int x; // horizontal component (position / velocity)
private int y; // vertical component (position / velocity)
private final int x; // horizontal component (position / velocity)
private final int y; // vertical component (position / velocity)
/**
* Enum representing a direction on the track grid.

View File

@ -3,7 +3,10 @@ package ch.zhaw.pm2.racetrack;
import ch.zhaw.pm2.racetrack.given.ConfigSpecification;
import ch.zhaw.pm2.racetrack.given.TrackSpecification;
import java.io.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
@ -57,8 +60,8 @@ import java.util.Scanner;
public class Track implements TrackSpecification {
public static final char CRASH_INDICATOR = 'X';
private List<String> track;
private List<Car> cars;
private final List<String> track;
private final List<Car> cars;
private final List<PositionVector> finishLine;
private ConfigSpecification.SpaceType finishTyp;
@ -85,13 +88,17 @@ public class Track implements TrackSpecification {
* @throws FileNotFoundException if the FilePath is invalid.
*/
private void readFile(File trackFile) throws FileNotFoundException {
Scanner scanner = new Scanner(new FileInputStream(trackFile),"UTF-8");
Scanner scanner = new Scanner(new FileInputStream(trackFile), StandardCharsets.UTF_8);
while (scanner.hasNextLine()) {
track.add(scanner.nextLine());
}
}
/**
* Goes through the track ArrayList and determines the locations of each cars and initializes them at the location.
*
* @throws InvalidTrackFormatException is thrown if a car is found more than once inside the track.
*/
private void addCars() throws InvalidTrackFormatException {
ConfigSpecification.SpaceType[] spaceTypes = ConfigSpecification.SpaceType.values();
List<Character> allSpaceTypesAsChar = new ArrayList<>();
@ -101,23 +108,26 @@ public class Track implements TrackSpecification {
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);
for (int yPosition = 0; yPosition < track.size(); yPosition++) {
String line = track.get(yPosition);
for (int xPosition = 0; xPosition < line.length(); xPosition++) {
char possibleCarChar = line.charAt(xPosition);
if (!allSpaceTypesAsChar.contains(possibleCarChar)) {
if (usedSymbolForCar.contains(possibleCarChar)) {
throw new InvalidTrackFormatException();
}
usedSymbolForCar.add(possibleCarChar);
cars.add(new Car(possibleCarChar, new PositionVector(i, j)));
cars.add(new Car(possibleCarChar, new PositionVector(xPosition, yPosition)));
}
}
}
}
//TODO: THIS
/**
*
* @throws InvalidTrackFormatException
*/
private void findFinish() throws InvalidTrackFormatException {
for (int i = 0; i < track.size(); i++) {
String line = track.get(i);
@ -141,6 +151,12 @@ public class Track implements TrackSpecification {
}
}
/**
* Method to find the PositionVector of a chosen character
*
* @param symbol char that we are looking for on the track
* @return the PositionVector of the desired char
*/
private PositionVector findChar(char symbol) {
PositionVector vector = null;
for (int i = 0; i < track.size(); i++) {
@ -154,12 +170,27 @@ public class Track implements TrackSpecification {
return vector;
}
/**
* Method that places a character at a chosen position
*
* @param positionVector position where char will be placed
* @param symbol char that should be placed at desired position
*/
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.remove(positionVector.getY());
track.add(positionVector.getY(), line);
}
//TODO: check if this method is okay and needed
/**
* Determines if a location is valid PositionVector inside the track
*
* @param positionVector of location that has to be checked
* @throws PositionVectorNotValid if the PositionVector does not lie on the track.
*/
private void isPositionVectorOnTrack(PositionVector positionVector) throws PositionVectorNotValid {
try {
private void isPositionVectorOnTrack(PositionVector positionVector) throws PositionVectorNotValidException {
try{
@ -169,22 +200,20 @@ public class Track implements TrackSpecification {
}
}
/**
* @return all Cars
*/
public List<Car> getCars() {
return cars;
}
/**
* @return finishLine
* Method that returns the finishline as a List
*
* @return finishLine List
*/
public List<PositionVector> getFinishLine() {
return finishLine;
}
/**
* @return the track
* Returns the whole Track as List of Strings
*
* @return track as List of Strings
*/
public List<String> getTrack() {
return track;
@ -203,7 +232,7 @@ public class Track implements TrackSpecification {
}
/**
* This class does change the Position of the car only in the track.
* This Method does change the Position of the car inside the track object.
*
* @param carIndex of the current car
*/
@ -225,10 +254,10 @@ public class Track implements TrackSpecification {
}
/**
* This Method will check if the Car could crash at the specific position
* This Method will check if the Car would crash at the specific position
*
* @param positionVector the position to check if the car could crash
* @return true if car would crash. Else false.
* @param positionVector the position to check if the car would crash
* @return true if crash otherwise false
*/
public boolean willCrashAtPosition(int carIndex, PositionVector positionVector) throws PositionVectorNotValidException {
isPositionVectorOnTrack(positionVector); //TODO: remove this line? Or Method?
@ -242,10 +271,10 @@ public class Track implements TrackSpecification {
}
/**
* This Method will make the Car Crash. In Track and in the Car Object
* This Method will mark the Car as crashed inside the track and the car Object.
*
* @param carIndex representing current Car
* @param crashPositionVector where the Crash did happen
* @param carIndex of car that will be marked as crashed
* @param crashPositionVector of the location of the crash
*/
public void carDoesCrash(int carIndex, PositionVector crashPositionVector) throws PositionVectorNotValidException {
isPositionVectorOnTrack(crashPositionVector); //TODO: remove this line? and Method?
@ -262,10 +291,11 @@ public class Track implements TrackSpecification {
* If the location is outside the track bounds, it is considered a wall.
*
* @param position The coordinates of the position to examine
* @return The type of track position at the given location
* @return The type of space at the desired position
*/
@Override
public Config.SpaceType getSpaceType(PositionVector position) {
//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) {
@ -277,9 +307,9 @@ public class Track implements TrackSpecification {
}
/**
* Return the number of cars.
* Return the number of cars that are located in a track
*
* @return Number of cars
* @return number of cars as int
*/
@Override
public int getCarCount() {
@ -353,6 +383,13 @@ public class Track implements TrackSpecification {
return currentSpace.getValue();
}
/**
* Determines all points that lie between the two position vectors including the endpoint VectorPosition using the Bresenham algorithm.
*
* @param startPosition PositionVector of the finish coordinate
* @param endPosition PositionVector of the start coordinate
* @return ArrayList containing PositionVectors of all position that are between the start and finish including the finish position.
*/
public ArrayList<PositionVector> calculatePointsOnPath(PositionVector startPosition, PositionVector endPosition) {
ArrayList<PositionVector> pathList = new ArrayList<>();
// Use Bresenham's algorithm to determine positions.

View File

@ -6,13 +6,20 @@ import org.beryx.textio.TextTerminal;
import java.util.List;
/**
* Class representing the Userinterface.
* Used to get inputs from users via textio.
*
* @author Roman Schenk
*/
public class UserInterface {
private final TextIO textIO;
private final TextTerminal<?> textTerminal;
/**
* Opens a new Terminal Window and prints the welcome Text
* Opens a new Terminal Window and prints the welcome Text.
*
* @param welcomeText The Text which will be printed after the windows is opened.
*/
public UserInterface(String welcomeText) {
@ -24,6 +31,7 @@ public class UserInterface {
/**
* Prints the given Text in textTerminal
*
* @param text The Text which should be printed.
*/
public void printInformation(String text) {
@ -31,8 +39,9 @@ public class UserInterface {
}
/**
* asks the user to choose one of the options given.
* @param text Text which is printed befor the options are printed. Example: "Select Track file:"
* Method which asks the user to choose one of the options given.
*
* @param text Text which is printed before the options are printed. Example: "Select Track file:"
* @param options List with the options which can be selected.
* @return the list index of the selected option
*/
@ -45,7 +54,8 @@ public class UserInterface {
}
/**
* gives information which player's turn it is and asks for the direction to accelerate
* Gives information which player is at turn and asks for the direction to accelerate or quit the game.
*
* @param playingCarIndex the index of the player
* @param playingCarID the ID of the player
* @return the direction which is selected by the player. If null -> quit game
@ -70,7 +80,8 @@ public class UserInterface {
}
/**
* returns the the associated direction Object
* Method which returns the associated direction Object.
*
* @param number the number which was typed by the user
* @return the associated direction. If null -> unknown number
*/
@ -90,7 +101,8 @@ public class UserInterface {
}
/**
* prints the given Track in the terminal
* Method to print the given Track in the terminal
*
* @param track the track which should be printed
*/
public void printTrack(Track track) {
@ -98,14 +110,12 @@ public class UserInterface {
}
/**
* Method to dispose the Textterminal
* @param text OUtput Text
* Method to dispose of the Textterminal
*
* @param text Output Text
*/
public void quit(String text) {
textIO.newStringInputReader().withMinLength(0).read(text);
textTerminal.dispose();
}
}

View File

@ -5,13 +5,14 @@ import ch.zhaw.pm2.racetrack.PositionVector.Direction;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class MoveListStrategy implements MoveStrategy {
private List<Direction> moveList;
private final List<Direction> moveList;
private int pointer;
public MoveListStrategy(String path) throws FileNotFoundException{
@ -21,7 +22,7 @@ public class MoveListStrategy implements MoveStrategy {
}
private void readFile(File trackFile) throws FileNotFoundException {
Scanner scanner = new Scanner(new FileInputStream(trackFile), "UTF-8");
Scanner scanner = new Scanner(new FileInputStream(trackFile), StandardCharsets.UTF_8);
Direction[] directions = Direction.values();
while (scanner.hasNextLine()) {
String line = scanner.nextLine();

View File

@ -6,6 +6,7 @@ import ch.zhaw.pm2.racetrack.PositionVector.Direction;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Scanner;
@ -25,7 +26,7 @@ public class PathFollowerMoveStrategy implements MoveStrategy {
/**
* List of all points on the path.
*/
private ArrayList<PositionVector> pointList;
private final ArrayList<PositionVector> pointList;
/**
* The index of the next point on the path.
*/
@ -51,7 +52,7 @@ public class PathFollowerMoveStrategy implements MoveStrategy {
* @throws FileNotFoundException If the file with the given path does not exist.
*/
public void readFile(File trackFile) throws FileNotFoundException {
Scanner scanner = new Scanner(new FileInputStream(trackFile), "UTF-8");
Scanner scanner = new Scanner(new FileInputStream(trackFile), StandardCharsets.UTF_8);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] coordinates = line.split("(\\(X:|, Y:|\\))");

View File

@ -7,9 +7,9 @@ import ch.zhaw.pm2.racetrack.UserInterface;
* Let the user decide the next move.
*/
public class UserMoveStrategy implements MoveStrategy {
private UserInterface userInterface;
private int carIndex;
private char carID;
private final UserInterface userInterface;
private final int carIndex;
private final char carID;
public UserMoveStrategy(UserInterface userInterface, int carIndex, char carID) {
this.userInterface = userInterface;

View File

@ -101,7 +101,7 @@ class CarTest {
@Test
void movement() {
// add all possible directions in a List
List<PositionVector.Direction> directions = Arrays.asList(PositionVector.Direction.values());
PositionVector.Direction[] directions = PositionVector.Direction.values();
//position shouldn't be changed because velocity should be 0.
car.move();

View File

@ -21,9 +21,9 @@ class GameTest {
private Game game;
private Track track;
private String TRACK_FILE_PATH = ".\\tracks\\challenge.txt";
private int CAR_INDEX_ONE = 0;
private int CAR_INDEX_TWO = 1;
private final String TRACK_FILE_PATH = ".\\tracks\\challenge.txt";
private final int CAR_INDEX_ONE = 0;
private final int CAR_INDEX_TWO = 1;
/**
* This nested Class tests if the game gets initiatet correctly