diff options
Diffstat (limited to 'Week14 Route 66')
-rw-r--r-- | Week14 Route 66/nbproject/project.properties | 6 | ||||
-rw-r--r-- | Week14 Route 66/src/OO14route66/Car.java | 13 | ||||
-rw-r--r-- | Week14 Route 66/src/OO14route66/Direction.java | 15 | ||||
-rw-r--r-- | Week14 Route 66/src/OO14route66/Model.java | 85 | ||||
-rw-r--r-- | Week14 Route 66/src/OO14route66/RoadView.java | 12 | ||||
-rw-r--r-- | Week14 Route 66/src/com/camilstaps/route66/Crossing.java | 61 | ||||
-rw-r--r-- | Week14 Route 66/src/com/camilstaps/route66/Driver.java | 32 | ||||
-rw-r--r-- | Week14 Route 66/src/com/camilstaps/route66/Overviewer.java | 64 |
8 files changed, 206 insertions, 82 deletions
diff --git a/Week14 Route 66/nbproject/project.properties b/Week14 Route 66/nbproject/project.properties index faae679..93592ec 100644 --- a/Week14 Route 66/nbproject/project.properties +++ b/Week14 Route 66/nbproject/project.properties @@ -1,9 +1,10 @@ annotation.processing.enabled=true annotation.processing.enabled.in.editor=false -annotation.processing.processor.options= annotation.processing.processors.list= annotation.processing.run.all.processors=true annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=Week14 Route 66 +application.vendor=camilstaps build.classes.dir=${build.dir}/classes build.classes.excludes=**/*.java,**/*.form # This directory is removed when the project is cleaned: @@ -26,6 +27,7 @@ dist.archive.excludes= dist.dir=dist dist.jar=${dist.dir}/Week14_Route_66.jar dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= excludes= includes=** jar.compress=false @@ -53,7 +55,7 @@ javadoc.splitindex=true javadoc.use=true javadoc.version=false javadoc.windowtitle= -main.class=com.camilstaps.route66.Week14Route66 +main.class=OO14route66.Route66 manifest.file=manifest.mf meta.inf.dir=${src.dir}/META-INF mkdist.disabled=false diff --git a/Week14 Route 66/src/OO14route66/Car.java b/Week14 Route 66/src/OO14route66/Car.java index 97d7b33..c12291a 100644 --- a/Week14 Route 66/src/OO14route66/Car.java +++ b/Week14 Route 66/src/OO14route66/Car.java @@ -1,7 +1,6 @@ package OO14route66; import com.camilstaps.route66.Driver; -import com.camilstaps.route66.Overviewer; import java.awt.Color; import java.awt.Graphics; import java.util.Random; @@ -47,9 +46,8 @@ public class Car { direction = Direction.intToDirection(number); location = RoadView.WINDOWSIZE - 2 - (number/Model.DIRECTIONS) * (CARLENGTH + MINCARSPACE); colour = carColours[number % carColours.length]; - driver = new Driver(this); + driver = new Driver(this, model); this.model = model; - Overviewer.getInstance().hello(this); } /** @@ -97,8 +95,17 @@ public class Car { */ public void step() { location = getNewLocation(); + //System.err.println("Car "); model.update(); } + + public boolean isInFrontOfCrossing() { + return location < RoadView.getStartCrossing() && getNewLocation() >= RoadView.getStartCrossing(); + } + + public boolean isOnCrossing() { + return location > RoadView.getStartCrossing() && location - CARLENGTH < RoadView.getEndCrossing(); + } /** * Paint this car diff --git a/Week14 Route 66/src/OO14route66/Direction.java b/Week14 Route 66/src/OO14route66/Direction.java index b8c1636..14d7110 100644 --- a/Week14 Route 66/src/OO14route66/Direction.java +++ b/Week14 Route 66/src/OO14route66/Direction.java @@ -37,6 +37,21 @@ public enum Direction } } } + + /** + * Get the opposite of a direction + * @param direction + * @return + */ + public static Direction opposite(Direction direction) { + switch (direction) { + case North: return South; + case South: return North; + case East: return West; + case West: return East; + default: return direction; + } + } /** * override standard toString diff --git a/Week14 Route 66/src/OO14route66/Model.java b/Week14 Route 66/src/OO14route66/Model.java index c79aa4e..f4e725f 100644 --- a/Week14 Route 66/src/OO14route66/Model.java +++ b/Week14 Route 66/src/OO14route66/Model.java @@ -1,7 +1,10 @@ package OO14route66; +import com.camilstaps.route66.Crossing; import java.util.ArrayList; import java.util.Observable; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.swing.JFrame; /** @@ -12,13 +15,13 @@ import javax.swing.JFrame; */ public class Model extends Observable { - private final Car [] cars; - public static final int - DIRECTIONS = 2, + private final Car [] cars; + public static final int + DIRECTIONS = 4, NUMBEROFCARS = 5 * DIRECTIONS; // total number of cars in system - private final ArrayList<JFrame> views; - + private final ArrayList<JFrame> views; + private final Crossing crossing = new Crossing(this, Direction.North); /** * Constructor: create all cars @@ -55,9 +58,79 @@ public class Model extends Observable /** * repaint all views */ - public void update() { + 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) { + Car that_car = cars[car.getNumber() < DIRECTIONS ? car.getNumber() + NUMBEROFCARS - DIRECTIONS : car.getNumber() - DIRECTIONS]; + + boolean ok; + + System.err.println("Car " + car.getNumber() + " requests safety."); + + do { + ok = !(that_car.getLocation() > requested_location && + that_car.getLocation() < requested_location + Car.CARLENGTH + Car.MINCARSPACE); + +// if (!ok && that_car.getDriver().getWaitingToCross()) { +// crossing.doRequest(); +// } + + if (car.isInFrontOfCrossing() && !crossing.isAllowed(car.getDirection())) { + System.err.println("Requesting switch for car " + car.getNumber()); + ok = false; + //if (!car.getDriver().getWaitingToCross()) { + //car.getDriver().setWaitingToCross(true); + ok = crossing.doRequest(); + //car.getDriver().setWaitingToCross(!ok); + //} + } + + if (!ok) { + System.err.println("Car " + car.getNumber() + " waiting."); + try { + wait(); + } catch (InterruptedException ex) { + } + System.err.println("Car " + car.getNumber() + " acquired lock."); + } + } while (!ok); + + System.err.println("Car " + car.getNumber() + " has safe location."); + + return ok; + } + + public synchronized boolean isNoCarsOnCrossing() { + boolean ok = false; + while (!ok) { + ok = true; + for (Car car : cars) { + if (car.isOnCrossing()) { + System.err.println("Car " + car.getNumber() + " is on crossing."); + ok = false; + } + } + if (!ok) { + System.err.println("Checking crossing waiting"); + try { + wait(); + } catch (InterruptedException ex) { + } + System.err.println("Checking crossing"); + } + } + return true; } } diff --git a/Week14 Route 66/src/OO14route66/RoadView.java b/Week14 Route 66/src/OO14route66/RoadView.java index 1d53269..4495822 100644 --- a/Week14 Route 66/src/OO14route66/RoadView.java +++ b/Week14 Route 66/src/OO14route66/RoadView.java @@ -74,8 +74,8 @@ public class RoadView extends JFrame * @param g graphics to draw on */ private void paintRoad (Graphics g) { - final int left = (WINDOWSIZE / 2) - Car.CARWIDTH - 4; - final int width = 2 * Car.CARWIDTH + 8; + final int left = getStartCrossing(); + final int width = getEndCrossing() - left; g.setColor(Color.white); // background g.fillRect(0, 0, WINDOWSIZE, WINDOWSIZE); g.setColor(Color.darkGray); // streets @@ -84,4 +84,12 @@ public class RoadView extends JFrame g.fillRect(left, 0, width, WINDOWSIZE); } } + + public static int getStartCrossing() { + return (WINDOWSIZE / 2) - Car.CARWIDTH - 4; + } + + public static int getEndCrossing() { + return getStartCrossing() + 2 * Car.CARWIDTH + 8; + } } diff --git a/Week14 Route 66/src/com/camilstaps/route66/Crossing.java b/Week14 Route 66/src/com/camilstaps/route66/Crossing.java new file mode 100644 index 0000000..eba5bfe --- /dev/null +++ b/Week14 Route 66/src/com/camilstaps/route66/Crossing.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2015 Camil Staps + */ +package com.camilstaps.route66; + +import OO14route66.Direction; +import OO14route66.Model; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author camilstaps + */ +public class Crossing { + + private final Model model; + private Direction allowed; + private boolean waiting = false; + private int requests = 0; + + public Crossing(Model model, Direction allowed) { + this.model = model; + this.allowed = allowed; + } + + public Direction getAllowed() { + return allowed; + } + + public synchronized void doSwitch() { + waiting = true; + while (!model.isNoCarsOnCrossing()); + System.err.println("Switching"); + if (allowed == Direction.East || allowed == Direction.West) { + allowed = Direction.North; + } else { + allowed = Direction.East; + } + requests = 0; + System.err.println("Switched to " + allowed); + waiting = false; + //notifyAll(); + } + + public boolean isAllowed(Direction direction) { + return !waiting && (direction == allowed || Direction.opposite(direction) == allowed); + } + + public boolean doRequest() { + //if (++requests >= 2) { + if (waiting) { + return false; + } + doSwitch(); + return true; + //} + //return false; + } + +} diff --git a/Week14 Route 66/src/com/camilstaps/route66/Driver.java b/Week14 Route 66/src/com/camilstaps/route66/Driver.java index e2e5a7d..4a323cd 100644 --- a/Week14 Route 66/src/com/camilstaps/route66/Driver.java +++ b/Week14 Route 66/src/com/camilstaps/route66/Driver.java @@ -8,27 +8,46 @@ import OO14route66.Model; import java.util.Random; /** - * - * @author camilstaps + * A Driver takes care its car doesn't collide + * @author Camil Staps */ public class Driver implements Runnable { private final Car car; + private final Model model; private final Random r; - private boolean running; + private boolean running, waitingToCross = false; private int delay; - public Driver(Car car) { + public Driver(Car car, Model model) { this.car = car; + this.model = model; r = new Random(); } + /** + * Set running to false to disable driving altogether + * @param value + */ public void setRunning(boolean value) { running = value; } + public void setWaitingToCross(boolean value) { + waitingToCross = value; + } + + public boolean getWaitingToCross() { + return waitingToCross; + } + + /** + * Set some approximate delay for {@link Driver#pause()}. The actual delay + * is still pseudorandom. + * @param value + */ public void setDelay(int value) { delay = value; } @@ -38,7 +57,7 @@ public class Driver implements Runnable { public void run() { running = true; while (true) { - while (!running || !Overviewer.getInstance().isSafeLocation(car, car.getNewLocation())); + while (!running || !model.isSafeLocation(car, car.getNewLocation())); car.step(); @@ -46,6 +65,9 @@ public class Driver implements Runnable { } } + /** + * Pause for some pseudorandom time + */ protected void pause() { try { int bonus = 0; diff --git a/Week14 Route 66/src/com/camilstaps/route66/Overviewer.java b/Week14 Route 66/src/com/camilstaps/route66/Overviewer.java deleted file mode 100644 index 844f40c..0000000 --- a/Week14 Route 66/src/com/camilstaps/route66/Overviewer.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -package com.camilstaps.route66; - -import OO14route66.Car; -import OO14route66.Model; - -/** - * The Overviewer (always only one instance) tells Drivers when they can drive - * - * @author Camil Staps - */ -public class Overviewer { - - /** - * This is a singleton - */ - private static Overviewer instance; - - Car[] cars = new Car[Model.NUMBEROFCARS]; - - /** - * This is a singleton - * @return the instance - */ - public static Overviewer getInstance() { - if (instance == null) { - instance = new Overviewer(); - } - return instance; - } - - /** - * Add a car to the list of cars - * @param car - */ - public synchronized void hello(Car car) { - cars[car.getNumber()] = car; - } - - /** - * 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) { - for (Car that_car : cars) { - if (that_car != null && that_car != car && - that_car.getDirection() == car.getDirection() && - that_car.getLocation() > requested_location && - that_car.getLocation() < requested_location + Car.CARLENGTH + Car.MINCARSPACE) { - return false; - } - } - return true; - } - -} |