Merge remote-tracking branch 'origin/main'
This commit is contained in:
		
						commit
						d038132055
					
				| 
						 | 
				
			
			@ -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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<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.
 | 
			
		||||
     *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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());
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue