package model; /** * Represent a car in the game. The car can be either horizontal or vertical. * Also manage movement for that car. * For horizontal cars the front is to the right, for vertical cars it is to the bottom of the matrix. */ public class Car { private int number; private Position front, back; private Orientation orientation; /** * Create a new car. Front and back are switched if necessary so that the from is to the right and the bottom. */ public Car(int number, Position front, Position back, Orientation orientation) { this.number = number; this.orientation = orientation; if (orientation == Orientation.HORIZONTAL) { if (back.getX() < front.getX()) { this.back = back; this.front = front; } else { this.back = front; this.front = back; } } else { if (back.getY() < front.getY()) { this.back = back; this.front = front; } else { this.back = front; this.front = back; } } } /** * Move the car forward * * @param board the board on which apply the changes * @param nbSteps the number of steps this car will move * @throws RuntimeException If the number of steps is too high */ public void moveForward(int[][] board, int nbSteps) throws RuntimeException { if (!canMoveForward(board, nbSteps)) throw new RuntimeException("Illegal number of steps!"); if (orientation == Orientation.HORIZONTAL) { for (int i = 0; i < nbSteps; i++) { board[front.getX() + i + 1][front.getY()] = this.number; board[back.getX() + i][back.getY()] = -1; } front.setX(front.getX() + nbSteps); back.setX(back.getX() + nbSteps); } else { for (int i = 0; i < nbSteps; i++) { board[front.getX()][front.getY() + i + 1] = this.number; board[back.getX()][back.getY() + i] = -1; } front.setY(front.getY() + nbSteps); back.setY(back.getY() + nbSteps); } } /** * Move the car backwards * * @param board the board on which apply the changes * @param nbSteps the number of steps this car will move * @throws RuntimeException If the number of steps is too high */ public void moveBackwards(int[][] board, int nbSteps) throws RuntimeException { if (!canMoveBackwards(board, nbSteps)) throw new RuntimeException("Illegal number of steps!"); if (orientation == Orientation.HORIZONTAL) { for (int i = 0; i < nbSteps; i++) { board[back.getX() - i - 1][back.getY()] = this.number; board[front.getX() - i][front.getY()] = -1; } front.setX(front.getX() - nbSteps); back.setX(back.getX() - nbSteps); } else { for (int i = 0; i < nbSteps; i++) { board[back.getX()][back.getY() - i - 1] = this.number; board[front.getX()][front.getY() - i] = -1; } front.setY(front.getY() - nbSteps); back.setY(back.getY() - nbSteps); } } /** * @param board The game board. * @return How many tiles the car can move forward */ public int getNbStepsForward(int[][] board) { int result = 0; if (this.orientation == Orientation.HORIZONTAL) for (int x = this.front.getX() + 1; (x < board.length) && (board[x][this.front.getY()] == -1); x++) result++; else for (int y = this.front.getY() + 1; (y < board.length) && (board[this.front.getX()][y] == -1); y++) result++; return result; } /** * @param board The game board. * @return How many tiles the car can move backwards */ public int getNbStepsBackwards(int[][] board) { int result = 0; if (this.orientation == Orientation.HORIZONTAL) for (int x = this.back.getX() - 1; (x > 0) && (board[x][this.back.getY()] == -1); x--) result++; else for (int y = this.back.getY() - 1; (y > 0) && (board[this.back.getX()][y] == -1); y--) result++; return result; } /** * Tell if the car can move forward that many steps * * @param board The game board * @param nbSteps The number of steps */ public boolean canMoveForward(int[][] board, int nbSteps) { if (this.orientation == Orientation.HORIZONTAL) { if (this.front.getX() + nbSteps >= board.length) return false; for (int x = this.front.getX() + 1; x - this.front.getX() <= nbSteps; x++) if (board[x][this.front.getY()] != -1) return false; return true; } else { if (this.front.getY() + nbSteps >= board.length) return false; for (int y = this.front.getY() + 1; y - this.front.getY() <= nbSteps; y++) if (board[this.front.getX()][y] != -1) return false; return true; } } /** * Tell if the car can move backwards that many steps * * @param board The game board * @param nbSteps The number of steps */ public boolean canMoveBackwards(int[][] board, int nbSteps) { if (this.orientation == Orientation.HORIZONTAL) { if (this.back.getX() - nbSteps < 0) return false; for (int x = this.back.getX() - 1; this.back.getX() - x <= nbSteps; x--) if (board[x][this.back.getY()] != -1) return false; return true; } else { if (this.back.getY() - nbSteps < 0) return false; for (int y = this.back.getY() - 1; this.back.getY() - y <= nbSteps; y--) if (board[this.back.getX()][y] != -1) return false; return true; } } public Position getFront() { return front; } public Position getBack() { return back; } public Orientation getOrientation() { return orientation; } public int getNumber() { return number; } public static enum Orientation { HORIZONTAL, VERTICAL; } }