diff options
author | Camil Staps | 2015-05-29 13:17:53 +0200 |
---|---|---|
committer | Camil Staps | 2015-05-29 13:17:53 +0200 |
commit | 3ccaa674fdbd3408d4cbea3ed9abb02c14433b9c (patch) | |
tree | c51dbe974566b4c437500fbf6894b626b203d265 /Week14 Route 66/src/com/camilstaps/route66/Model.java | |
parent | Hack to make it seem to be working (diff) |
licensing; reorganisation; javadoc; cleanup
Diffstat (limited to 'Week14 Route 66/src/com/camilstaps/route66/Model.java')
-rw-r--r-- | Week14 Route 66/src/com/camilstaps/route66/Model.java | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/Week14 Route 66/src/com/camilstaps/route66/Model.java b/Week14 Route 66/src/com/camilstaps/route66/Model.java new file mode 100644 index 0000000..6e43e29 --- /dev/null +++ b/Week14 Route 66/src/com/camilstaps/route66/Model.java @@ -0,0 +1,189 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 Camil Staps <info@camilstaps.nl> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.camilstaps.route66; + +import java.util.ArrayList; +import java.util.Observable; +import javax.swing.JFrame; + +/** + * Route 66 model with crossing + * + * The class model holds all cars in the simulation. + * + * @author Pieter Koopman, Camil Staps + */ +public class Model extends Observable { + + private final Car [] cars; + public static final int + DIRECTIONS = 4, + NUMBEROFCARS = 5 * DIRECTIONS; // total number of cars in system + + private final ArrayList<JFrame> views; + + /** + * Crossing attributes: + * + * allowed - which direction is currently allowed; if East is allowed, West + * is also allowed, etc. + * crossingWaiting - whether or not the crossing is waiting for cars to + * leave the crossing to switch (i.e. orange) + * lastCrossingChange - when the crossing switched the last time + * MIN_CROSS_TIME - the minimum time the crossing should wait before + * switching again after the last switch + */ + private Direction allowed = Direction.East; + private boolean crossingWaiting = false; + private long lastCrossingChange = 0; + private static final int MIN_CROSS_TIME = 1000; + + /** + * Constructor: create all cars + */ + public Model() { + views = new ArrayList<>(); + cars = new Car [NUMBEROFCARS]; + for (int c = 0; c < NUMBEROFCARS; c += 1) { + cars[c] = new Car(c, this); + } + } + + /** + * add the view to this model. It will be repainted upon an update + * @param view + */ + public void addView(JFrame view) { + views.add(view); + } + + public Car[] getCars() { + return cars; + } + + /** + * Get a car from the model + * @param i numbers of required car + * @return the car itself (not a copy) + */ + public Car getCar(int i) { + return cars[i]; + } + + /** + * Repaint all views, and notify all drivers to reconsider driving + */ + public synchronized void update() { + for (JFrame view: views) { + view.repaint(); + } + notifyAll(); + } + + /** + * Check if a location is safe for a car to go to. This should always be + * checked by a driver before actually driving. + * @param car + * @param requested_location + * @return + */ + public synchronized boolean isSafeLocation(Car car, int requested_location) { + // Check that we don't collide with the car in front of us + Car that_car = cars[car.getNumber() < DIRECTIONS ? car.getNumber() + NUMBEROFCARS - DIRECTIONS : car.getNumber() - DIRECTIONS]; + boolean ok = !(that_car.getLocation() > requested_location && + that_car.getLocation() < requested_location + Car.CARLENGTH + Car.MINCARSPACE); + + // If we have to wait for the crossing... well, do that. + if (car.isInFrontOfCrossing() && !isCrossingAllowed(car.getDirection())) { + ok = doCrossingRequest(); + } + + if (!ok) { + try { + wait(); + } catch (InterruptedException ex) {} + } + + return ok; + } + + /** + * Check if there are any cars on the crossing + * @return + */ + public synchronized boolean isCarsOnCrossing() { + for (Car car : cars) { + if (car.isOnCrossing()) { + return true; + } + } + return false; + } + + /** + * Switch the crossing + */ + public synchronized void doSwitchCrossing() { + crossingWaiting = true; + + while (isCarsOnCrossing()) { + try { + wait(); + } catch (InterruptedException ex) { + } + } + + if (allowed == Direction.East || allowed == Direction.West) { + allowed = Direction.North; + } else { + allowed = Direction.East; + } + + crossingWaiting = false; + lastCrossingChange = System.currentTimeMillis(); + } + + /** + * Check if crossing in some direction is allowed + * @param direction + * @return + */ + public synchronized boolean isCrossingAllowed(Direction direction) { + return !crossingWaiting && (direction == allowed || Direction.opposite(direction) == allowed); + } + + /** + * Try to switch the crossing + * This may return false without even trying to switch, if it's too early to + * ask (see {@link Model#MIN_CROSS_TIME}) or if a request has been made already. + * @return + */ + public synchronized boolean doCrossingRequest() { + if (crossingWaiting || System.currentTimeMillis() - lastCrossingChange < MIN_CROSS_TIME) { + return false; + } + doSwitchCrossing(); + return true; + } +} |