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