package class7_2_Exceptions_Tourists_start.mobileEntities; import class7_2_Exceptions_Tourists_start.CityMap; import javafx.geometry.Point2D; import javafx.scene.image.Image; import java.util.HashSet; import java.util.Random; import java.util.Set; public class Car extends MobileEntity { private static final Image CAR_IMAGE = new Image(CityMap.class.getResource("img/car.png").toString()); private static final int PLATE_LENGTH = 5; public static final int NUM_LETTERS = 26; private static Set plates = new HashSet<>(); private static Random random = new Random(); private String plate; public Car(CityMap cityMap) { super(cityMap, CAR_IMAGE); initializeName(); } public Car(CityMap cityMap, double carX, double carY) { super(cityMap, CAR_IMAGE, carX, carY); initializeName(); stopCar(); } /** Gives the car a unique name */ private void initializeName() { String putativePlate = findUniquePlate(); plate = putativePlate; setName("Car "+ MobileEntity.instanceCount + ": " + plate); } /** Set velocity to zero */ private void stopCar() { stepSize = new Point2D(0,0); } /** * If all plates are generated, starts generating random plates with duplicates... * @return a new unique plate, unless all plates are used. */ private String findUniquePlate() { String putativePlate; { putativePlate = generatePlate(); } while(plates.contains(putativePlate) && // -10 margin to reduce risk of floating-point error leading to infinite loop. plates.size()< (int)Math.pow(NUM_LETTERS, PLATE_LENGTH)-10); plates.add(putativePlate); return putativePlate; } /** * Generates random, possibly not-unique plate. * @return The plate generated. */ private String generatePlate() { StringBuilder plate = new StringBuilder(); for(int i = 0; i < PLATE_LENGTH; i++) { plate.append((char)('A'+random.nextInt(NUM_LETTERS))); } return plate.toString(); } @Override protected void step() { // Randomly turn right with equal probability during each time-step. // // I'm using the theory of exponential distributions [1] // in naming the variable MEAN_DISTANCE_BEFORE_TURN. // // Because the probability density function has a density of $\lambda$ at time zero, and a // of $1/\lambda$, we can say that since the probability of the event occurring is // mean of 1/MEAN_NUMBER_OF_STEPS, then (on average) we will go MEAN_NUMBER_OF_STEPS // before an event occurs. This approximation is valid only when MEAN_NUMBER_OF_STEPS // is small. // // [1] https://en.wikipedia.org/wiki/Exponential_distribution super.step(); double randNum = Math.random(); if( randNum < (Math.hypot(stepSize.getX(),stepSize.getY())/MEAN_DISTANCE_BEFORE_TURN)) { turnRight(); } // else no turn needed! } }