diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..4840edb0 Binary files /dev/null and b/.DS_Store differ diff --git a/.classpath b/.classpath new file mode 100644 index 00000000..f319b0ab --- /dev/null +++ b/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 00000000..79140616 Binary files /dev/null and b/src/.DS_Store differ diff --git a/src/edu/.DS_Store b/src/edu/.DS_Store new file mode 100644 index 00000000..a716f3f6 Binary files /dev/null and b/src/edu/.DS_Store differ diff --git a/src/edu/nd/.DS_Store b/src/edu/nd/.DS_Store new file mode 100644 index 00000000..f40c4712 Binary files /dev/null and b/src/edu/nd/.DS_Store differ diff --git a/src/edu/nd/se2018/.DS_Store b/src/edu/nd/se2018/.DS_Store new file mode 100644 index 00000000..fe429f16 Binary files /dev/null and b/src/edu/nd/se2018/.DS_Store differ diff --git a/src/edu/nd/se2018/homework/.DS_Store b/src/edu/nd/se2018/homework/.DS_Store new file mode 100644 index 00000000..747a5521 Binary files /dev/null and b/src/edu/nd/se2018/homework/.DS_Store differ diff --git a/src/edu/nd/se2018/homework/hwk1/Question1.java b/src/edu/nd/se2018/homework/hwk1/Question1.java index d990b3b1..013e688e 100644 --- a/src/edu/nd/se2018/homework/hwk1/Question1.java +++ b/src/edu/nd/se2018/homework/hwk1/Question1.java @@ -1,10 +1,27 @@ package edu.nd.se2018.homework.hwk1; +import java.util.*; public class Question1 { public Question1(){} public int getSumWithoutDuplicates(int[] numbers){ - return 0; + int total = 0; + Set set = new HashSet(); + for (int i = 0; i < numbers.length; i++) { + if (!set.contains(numbers[i])) { + set.add(numbers[i]); + total += numbers[i]; + } + + } + return total; + } + + public static void main(String[] args) { + int[] nums = {3, 3, 5, 5, 2}; + Question1 getSum = new Question1(); + int result = getSum.getSumWithoutDuplicates(nums); + System.out.println("The answer is:" + result); } } diff --git a/src/edu/nd/se2018/homework/hwk1/Question2.java b/src/edu/nd/se2018/homework/hwk1/Question2.java index b04a7f86..d9f81eb3 100644 --- a/src/edu/nd/se2018/homework/hwk1/Question2.java +++ b/src/edu/nd/se2018/homework/hwk1/Question2.java @@ -1,10 +1,56 @@ package edu.nd.se2018.homework.hwk1; +import java.util.*; public class Question2 { public Question2(){} public String getMostFrequentWord(String input, String stopwords){ - return ""; + HashMap map = new HashMap<>(); + Set set = new HashSet(); + for (String stop : stopwords.split(" ")) { + if (!set.contains(stop)) { + set.add(stop); + } + } + for (String word : input.split(" ")) { + if (map.containsKey(word)) { + Integer n = map.get(word); + map.put(word, n + 1); + } + else { + if (!set.contains(word)) { + map.put(word, 1); + } + } + } + int max = 0; + String word = ""; + Boolean duplicate = false; + for (Map.Entry w : map.entrySet()) { + if (w.getValue() > max) { + max = w.getValue(); + duplicate = false; + word = w.getKey(); + } + else if (w.getValue() == max) { + duplicate = true; + } + } + if (duplicate == false) { + return word; + } + else { + return null; + } } + + public static void main(String[] args) { + String inputString2 = "giraffe elephant giraffe tiger tiger"; + String stopWords = "and a hes the of up but with"; + Question2 mostFrequentWord = new Question2(); + String result = mostFrequentWord.getMostFrequentWord(inputString2, stopWords); + System.out.println("The answer is:" + result); + } + } diff --git a/src/edu/nd/se2018/homework/hwk1/Question3.java b/src/edu/nd/se2018/homework/hwk1/Question3.java index 740d282c..3754ceeb 100644 --- a/src/edu/nd/se2018/homework/hwk1/Question3.java +++ b/src/edu/nd/se2018/homework/hwk1/Question3.java @@ -4,6 +4,31 @@ public class Question3 { public Question3(){} public int getMirrorCount(int[] numbers){ - return 0; + if (numbers.length == 0) { + return 0; + } + int count = 0; + for (int i = 0; i < numbers.length; i++) { + int num = (numbers.length) - 1 - i; + + if (numbers[i] == numbers[num]) { + count++; + } + else { + count = 0; + } + } + if (count == 0) { + return 1; + } + else { + return count; + } + } + + public static void main(String[] args) { + Question3 mirrorCount = new Question3(); + int result = mirrorCount.getMirrorCount(new int[] {1,2,3,4,5}); + System.out.println("The answer is:" + result); } } diff --git a/src/edu/nd/se2018/homework/hwk2/EarlySprint.java b/src/edu/nd/se2018/homework/hwk2/EarlySprint.java new file mode 100644 index 00000000..4190fa94 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk2/EarlySprint.java @@ -0,0 +1,20 @@ +package edu.nd.se2018.homework.hwk2; + +public class EarlySprint implements RaceStrategy { + @Override + public double runStrategy(double position, double maxSpeed) { + double p; + if (position <= 2) { + p = position + maxSpeed; + } + else if (position < 10) { + p = position + (0.75 * maxSpeed); + } + else { + p = 10; + } + return p; + + } + +} diff --git a/src/edu/nd/se2018/homework/hwk2/HW2 Reflection.pdf b/src/edu/nd/se2018/homework/hwk2/HW2 Reflection.pdf new file mode 100644 index 00000000..85e00371 Binary files /dev/null and b/src/edu/nd/se2018/homework/hwk2/HW2 Reflection.pdf differ diff --git a/src/edu/nd/se2018/homework/hwk2/HW2-uml.pdf b/src/edu/nd/se2018/homework/hwk2/HW2-uml.pdf new file mode 100644 index 00000000..63e0b354 Binary files /dev/null and b/src/edu/nd/se2018/homework/hwk2/HW2-uml.pdf differ diff --git a/src/edu/nd/se2018/homework/hwk2/Horse.java b/src/edu/nd/se2018/homework/hwk2/Horse.java new file mode 100644 index 00000000..0262cd00 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk2/Horse.java @@ -0,0 +1,46 @@ +package edu.nd.se2018.homework.hwk2; +import java.text.DecimalFormat; + +import edu.nd.se2018.homework.hwk2.RaceStrategy; + +public class Horse { + private static DecimalFormat df2 = new DecimalFormat(".##"); + + RaceStrategy raceStrategy; + public String name; + public int number; + public double position; + public double maxSpeed; + + public Horse(RaceStrategy strategy, String n, int num, double p, double s) { + this.raceStrategy = strategy; + this.name = n; + this.number = num; + this.position = p; + this.maxSpeed = s; + } + + public void run() { + double p = raceStrategy.runStrategy(this.position, this.maxSpeed); + this.position = p; + } + + public void setStrategy(RaceStrategy strategy) { + this.raceStrategy = strategy; + + } + + public boolean done() { + if (position >= 10) { + return true; + } + else { + return false; + } + } + + public void display() { + System.out.println(name + " is at position: " + df2.format(position)); + } + +} diff --git a/src/edu/nd/se2018/homework/hwk2/Main.java b/src/edu/nd/se2018/homework/hwk2/Main.java new file mode 100644 index 00000000..99918489 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk2/Main.java @@ -0,0 +1,15 @@ +package edu.nd.se2018.homework.hwk2; + +public class Main { + + public static void main(String[] args) { + Race race = new Race(); + race.enrollHorse(new SteadyRun(), "Joe", 1, 0, 1); + race.enrollHorse(new EarlySprint(), "Mary", 2, 0, 1); + race.enrollHorse(new SlowStart(), "Spirit", 3, 0, 1); + race.enrollHorse(new EarlySprint(), "DingDing", 4, 0, 1); + race.enrollHorse(new SlowStart(), "Kelly", 5, 0, 1); + race.run(); + + } +} diff --git a/src/edu/nd/se2018/homework/hwk2/Race.java b/src/edu/nd/se2018/homework/hwk2/Race.java new file mode 100644 index 00000000..4b5a905b --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk2/Race.java @@ -0,0 +1,33 @@ +package edu.nd.se2018.homework.hwk2; + +public class Race { + public Horse[] horseArray = new Horse[5]; + public int count = 0; + int miles = 10; + boolean done = false; + String winner = ""; + + public void enrollHorse(RaceStrategy rs, String n, int num, double p, double ms) { + this.horseArray[this.count] = new Horse(rs, n, num, p, ms); + this.count = this.count + 1; + + } + + public Race() {} + + public void run() { + while (!done) { + for (int i = 0; i < this.count; i++ ) { + this.horseArray[i].run(); + this.horseArray[i].display(); + if (this.horseArray[i].done()) { + winner = this.horseArray[i].name; + done = true; + } + } + } + System.out.println("The winner is: " + winner); + } + + +} diff --git a/src/edu/nd/se2018/homework/hwk2/RaceStrategy.java b/src/edu/nd/se2018/homework/hwk2/RaceStrategy.java new file mode 100644 index 00000000..d387c6ed --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk2/RaceStrategy.java @@ -0,0 +1,6 @@ +package edu.nd.se2018.homework.hwk2; + +public interface RaceStrategy { + public double runStrategy(double position, double maxSpeed); + +} diff --git a/src/edu/nd/se2018/homework/hwk2/RaceTest.java b/src/edu/nd/se2018/homework/hwk2/RaceTest.java new file mode 100644 index 00000000..0f2913bb --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk2/RaceTest.java @@ -0,0 +1,36 @@ +package edu.nd.se2018.homework.hwk2; +import org.junit.Test; + +public class RaceTest { + @Test + public void test() { // Same strategies, different max speeds + Race race = new Race(); + race.enrollHorse(new SteadyRun(), "A1", 1, 0, 1); + race.enrollHorse(new SteadyRun(), "B1", 2, 0, 1.2); + race.enrollHorse(new SteadyRun(), "C1", 3, 0, 1.4); + race.run(); + assert(race.winner == "C1"); + } + + @Test + public void test2() { // Same strategies, different max speeds + Race race2 = new Race(); + race2.enrollHorse(new SteadyRun(), "A2", 1, 0, 1); + race2.enrollHorse(new EarlySprint(), "B2", 1, 0, 1); + race2.enrollHorse(new SlowStart(), "C2", 3, 0, 1); + race2.run(); + assert(race2.winner == "C2"); + } + + @Test + public void test3() { + Race race3 = new Race(); + race3.enrollHorse(new SteadyRun(), "A3", 1, 0, 2); + race3.enrollHorse(new SlowStart(), "B3", 2, 0, 1); + race3.enrollHorse(new EarlySprint(), "C3", 3, 0, 1.1); + race3.enrollHorse(new SlowStart(), "D3", 4, 0, 0.8); + race3.enrollHorse(new SteadyRun(), "E3", 5, 0, 0.9); + race3.run(); + assert(race3.winner == "A3"); + } +} diff --git a/src/edu/nd/se2018/homework/hwk2/SlowStart.java b/src/edu/nd/se2018/homework/hwk2/SlowStart.java new file mode 100644 index 00000000..038b7660 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk2/SlowStart.java @@ -0,0 +1,21 @@ +package edu.nd.se2018.homework.hwk2; + +public class SlowStart implements RaceStrategy { + public double runStrategy(double position, double maxSpeed) { + double p = position; + if (position <= 6) { + p = position + (0.75 * maxSpeed); + } + else if (position <= 1) { + p = position + (0.9 * maxSpeed); + } + else if (position < 10){ + p = position + maxSpeed; + } + else { + position = 10; + } + return p; + } + +} diff --git a/src/edu/nd/se2018/homework/hwk2/SteadyRun.java b/src/edu/nd/se2018/homework/hwk2/SteadyRun.java new file mode 100644 index 00000000..39864390 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk2/SteadyRun.java @@ -0,0 +1,15 @@ +package edu.nd.se2018.homework.hwk2; + +public class SteadyRun implements RaceStrategy { + public double runStrategy(double position, double maxSpeed) { + double p; + if (position < 10) { + p = position + (0.8 * maxSpeed); + } + else { + p = 10; + } + return p; + } + +} diff --git a/src/edu/nd/se2018/homework/hwk3/.DS_Store b/src/edu/nd/se2018/homework/hwk3/.DS_Store new file mode 100644 index 00000000..4db9c59a Binary files /dev/null and b/src/edu/nd/se2018/homework/hwk3/.DS_Store differ diff --git a/src/edu/nd/se2018/homework/hwk3/.classpath b/src/edu/nd/se2018/homework/hwk3/.classpath new file mode 100644 index 00000000..ac37fb2e --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk3/.classpath @@ -0,0 +1,5 @@ + + + + + diff --git a/src/edu/nd/se2018/homework/hwk3/.project b/src/edu/nd/se2018/homework/hwk3/.project new file mode 100644 index 00000000..f94d3c17 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk3/.project @@ -0,0 +1,17 @@ + + + hwk3 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/src/edu/nd/se2018/homework/hwk3/HW3 Reflection.pdf b/src/edu/nd/se2018/homework/hwk3/HW3 Reflection.pdf new file mode 100644 index 00000000..3240f09b Binary files /dev/null and b/src/edu/nd/se2018/homework/hwk3/HW3 Reflection.pdf differ diff --git a/src/edu/nd/se2018/homework/hwk3/HW3-uml.png b/src/edu/nd/se2018/homework/hwk3/HW3-uml.png new file mode 100644 index 00000000..cfdb1a58 Binary files /dev/null and b/src/edu/nd/se2018/homework/hwk3/HW3-uml.png differ diff --git a/src/edu/nd/se2018/homework/hwk3/OceanExplorer.java b/src/edu/nd/se2018/homework/hwk3/OceanExplorer.java new file mode 100644 index 00000000..167a4bd8 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk3/OceanExplorer.java @@ -0,0 +1,95 @@ +package edu.nd.se2018.homework.hwk3; +import javafx.application.Application; +import javafx.event.EventHandler; +import javafx.scene.Scene; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.input.KeyEvent; +import javafx.scene.layout.AnchorPane; +import javafx.stage.Stage; +import edu.nd.se2018.homework.hwk3.OceanMap; + +public class OceanExplorer extends Application { + AnchorPane root; + Scene scene; + OceanMap oceanMap; + ImageView shipImageView, pirateImageView; + Image shipImage, pirateImage; + Ship shipObject; + PirateShip pirateShip; + + + @Override + public void start(Stage oceanStage) throws Exception { + AnchorPane root = new AnchorPane(); + Scene scene = new Scene(root, 500, 500); + oceanMap = new OceanMap(); + + oceanMap.setIslands(); + oceanMap.drawMap(root.getChildren(), 50); + + // Load Images + shipImage = new Image("/images/Train.PNG", 50, 50, true, true); + shipImageView = new ImageView(shipImage); + shipImageView.setX(oceanMap.getShipLocation()[0]*50); + shipImageView.setY(oceanMap.getShipLocation()[1]*50); + root.getChildren().add(shipImageView); + + pirateImage = new Image("/images/pirateship.gif", 50, 50, true, true); + pirateImageView = new ImageView(pirateImage); + pirateImageView.setX(oceanMap.getPirateLocation()[0]*50); + pirateImageView.setY(oceanMap.getPirateLocation()[1]*50); + root.getChildren().add(pirateImageView); + + shipObject = oceanMap.ship; + pirateShip = oceanMap.pirateShip; + + oceanStage.setScene(scene); + oceanStage.setTitle("Ocean"); + oceanStage.show(); + + shipObject.addObserver(pirateShip); + + startSailing(scene); + } + + private void startSailing(Scene scene) { + scene.setOnKeyPressed(new EventHandler() { + + @Override + public void handle(KeyEvent ke) { + switch(ke.getCode()){ + case RIGHT: + shipObject.goEast(); + break; + case LEFT: + shipObject.goWest(); + break; + case UP: + shipObject.goNorth(); + break; + case DOWN: + shipObject.goSouth(); + break; + default: + break; + } + + shipImageView.setX(shipObject.getLocation()[0]*50); + shipImageView.setY(shipObject.getLocation()[1]*50); + + pirateImageView.setX(pirateShip.getLocation()[0]*50); + pirateImageView.setY(pirateShip.getLocation()[1]*50); + + } + + }); + + } + + public static void main(String[] args) { + launch(args); + + + } +} diff --git a/src/edu/nd/se2018/homework/hwk3/OceanMap.java b/src/edu/nd/se2018/homework/hwk3/OceanMap.java new file mode 100644 index 00000000..4a89e9c1 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk3/OceanMap.java @@ -0,0 +1,60 @@ +package edu.nd.se2018.homework.hwk3; + +import javafx.collections.ObservableList; +import javafx.scene.Node; +import javafx.scene.paint.Color; +import javafx.scene.shape.Rectangle; + +import java.util.Random; + +import edu.nd.se2018.homework.hwk3.Ship; + +public class OceanMap { + public int[][] oceanGrid = new int[25][25]; + final int dimensions = 25; + public Ship ship = new Ship(oceanGrid); + public PirateShip pirateShip = new PirateShip(oceanGrid); + + + public void setIslands( ) { + Random random = new Random(); + for (int i = 0; i < 10; i++) { + int xIsland = random.ints(0, 10).findFirst().getAsInt(); + int yIsland = random.ints(0, 10).findFirst().getAsInt(); + while ((xIsland == 0) && (yIsland == 0) || (xIsland == 5) && (yIsland == 7)) { + xIsland = random.ints(0, 10).findFirst().getAsInt(); + yIsland = random.ints(0, 10).findFirst().getAsInt(); + } + oceanGrid[xIsland][yIsland]= 1; + } + } + public void drawMap(ObservableList root, int scale) { + for (int x = 0; x < dimensions; x++) { + for (int y = 0; y < dimensions; y++) { + Rectangle rect = new Rectangle(x*scale, y*scale, scale, scale); + rect.setStroke(Color.BLACK); + if (oceanGrid[x][y] == 1) { + rect.setFill(Color.GREEN); + } + else { + rect.setFill(Color.PALETURQUOISE); + oceanGrid[x][y] = 0; + } + root.add(rect); + } + } + } + + public int[] getShipLocation() { + int[] location = new int[2]; + location = ship.getLocation(); + return(location); + } + + public int[] getPirateLocation() { + int[] location = new int[2]; + location = pirateShip.getLocation(); + oceanGrid[location[0]][location[1]] = 2; + return(location); + } +} diff --git a/src/edu/nd/se2018/homework/hwk3/PirateShip.java b/src/edu/nd/se2018/homework/hwk3/PirateShip.java new file mode 100644 index 00000000..20b1effe --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk3/PirateShip.java @@ -0,0 +1,92 @@ +package edu.nd.se2018.homework.hwk3; + +import java.util.Observable; +import java.util.Observer; + +public class PirateShip implements Observer { + public int x = 5; + public int y = 7; + int[][] oceanMap; + int[] shipPosition = new int[2]; + + public PirateShip(int[][] map) { + oceanMap = map; + + } + + public int[] getLocation() { + int[] location = new int[2]; + location[0] = x; + location[1] = y; + return (location); + } + + public void goEast() { + int[] l = getLocation(); + if (l[0] <= 8) { + if (oceanMap[l[0] + 1][l[1]] == 0) { + x += 1; + } + } + + } + + public void goWest() { + int[] l = getLocation(); + if (l[0] >= 1) { + if (oceanMap[l[0] - 1][l[1]] == 0) { + x -= 1; + } + } + } + + public void goSouth() { + int[] l = getLocation(); + if (l[1] <= 8) { + if (oceanMap[l[0]][l[1] + 1] == 0) { + y += 1; + } + } + } + + public void goNorth() { + int[] l = getLocation(); + if (l[1] >= 1) { + if (oceanMap[l[0]][l[1] - 1] == 0) { + y -= 1; + } + } + } + + public void movePirate() { + int xdist = x - shipPosition[0]; + int ydist = y - shipPosition[1]; + + if (Math.abs(xdist) > Math.abs(ydist)) { + if (xdist <= 0) { + this.goEast(); + } + else { + this.goWest(); + } + } + else { + if(ydist > 0) { + this.goNorth(); + } + else { + this.goSouth(); + } + + } + } + + @Override + public void update(Observable o, Object arg) { + if (o instanceof Ship) { + shipPosition = ((Ship) o).getLocation(); + this.movePirate(); + } + + } +} diff --git a/src/edu/nd/se2018/homework/hwk3/Ship.java b/src/edu/nd/se2018/homework/hwk3/Ship.java new file mode 100644 index 00000000..34a52f67 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk3/Ship.java @@ -0,0 +1,66 @@ +package edu.nd.se2018.homework.hwk3; + +import java.util.Observable; + +public class Ship extends Observable { + public int x = 0; + public int y = 0; + int[][] oceanMap; + + public Ship(int[][] map) { + oceanMap = map; + + } + + public int[] getLocation() { + int[] location = new int[2]; + location[0] = x; + location[1] = y; + return(location); + } + + public void goEast() { + int[] l = getLocation(); + if (l[0] <= 8) { + if (oceanMap[l[0] + 1][l[1]] == 0) { + x += 1; + } + } + setChanged(); + notifyObservers(); + } + + public void goWest() { + int[] l = getLocation(); + if (l[0] >= 1) { + if (oceanMap[l[0] - 1][l[1]] == 0) { + x -= 1; + } + } + setChanged(); + notifyObservers(); + } + + public void goSouth() { + int[] l = getLocation(); + if (l[1] <= 8) { + if (oceanMap[l[0]][l[1] + 1] == 0) { + y += 1; + } + } + setChanged(); + notifyObservers(); + } + + public void goNorth() { + int[] l = getLocation(); + if (l[1] >= 1) { + if (oceanMap[l[0]][l[1] - 1] == 0) { + y -= 1; + } + } + setChanged(); + notifyObservers(); + } + +} diff --git a/src/edu/nd/se2018/homework/hwk4/HW4 Reflection.pdf b/src/edu/nd/se2018/homework/hwk4/HW4 Reflection.pdf new file mode 100644 index 00000000..74d79a70 Binary files /dev/null and b/src/edu/nd/se2018/homework/hwk4/HW4 Reflection.pdf differ diff --git a/src/edu/nd/se2018/homework/hwk4/Simulation.java b/src/edu/nd/se2018/homework/hwk4/Simulation.java new file mode 100644 index 00000000..5ac3d255 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk4/Simulation.java @@ -0,0 +1,112 @@ +package edu.nd.se2018.homework.hwk4; + +import java.util.ArrayList; +import java.util.Collection; + +import edu.nd.se2018.homework.hwk4.model.infrastructure.Direction; +import edu.nd.se2018.homework.hwk4.model.infrastructure.MapBuilder; +import edu.nd.se2018.homework.hwk4.model.infrastructure.RailwayTracks; +import edu.nd.se2018.homework.hwk4.model.infrastructure.Road; +import edu.nd.se2018.homework.hwk4.model.infrastructure.gate.CrossingGate; +import edu.nd.se2018.homework.hwk4.model.vehicles.Car; +import edu.nd.se2018.homework.hwk4.model.vehicles.Train; +import edu.nd.se2018.homework.hwk4.view.MapDisplay; +import javafx.animation.AnimationTimer; +import javafx.application.Application; +import javafx.scene.Scene; +import javafx.scene.layout.Pane; +import javafx.stage.Stage; + +public class Simulation extends Application{ + + private Pane root; + private Scene scene; + private MapBuilder mapBuilder; + private MapDisplay mapDisplay; + + @Override + public void start(Stage stage) throws Exception { + + root = new Pane(); + + // Build infrastructure + mapBuilder = new MapBuilder(); + mapDisplay = new MapDisplay(root, mapBuilder.getRoads(), mapBuilder.getTracks(),mapBuilder.getAllGates()); + mapDisplay.drawTracks(); + mapDisplay.drawRoad(); + mapDisplay.drawGate(); + + scene = new Scene(root,1200,1000); + stage.setTitle("Railways"); + stage.setScene(scene); + stage.show(); + + // Train + RailwayTracks track = mapBuilder.getTrack("Royal"); + Train train = new Train(track.getEndX()+100,track.getEndY()-25, Direction.WEST); + root.getChildren().add(train.getImageView()); + + RailwayTracks track2 = mapBuilder.getTrack("New"); + + Train train2 = new Train(track2.getStartX()-100,track2.getStartY()-25, Direction.EAST); + root.getChildren().add(train2.getImageView()); + + for(CrossingGate gate: mapBuilder.getAllGates()) { + train.addObserver(gate); + train2.addObserver(gate); + } + + // Sets up a repetitive loop i.e., in handle that runs the actual simulation + new AnimationTimer(){ + + @Override + public void handle(long now) { + + createCar(); + train.move(); + train2.move(); + + for(CrossingGate gate: mapBuilder.getAllGates()) + gate.operateGate(); + + if (train.offScreen()) + train.reset(); + + if (train2.offScreen()) + train2.reset(); + + clearCars(); + } + }.start(); + } + + // Clears cars as they leave the simulation + private void clearCars(){ + Collection roads = mapBuilder.getRoads(); + for(Road road: roads){ + if (road.getCarFactory()!= null){ + ArrayList junkCars = road.getCarFactory().removeOffScreenCars(); + mapDisplay.removeCarImages(junkCars); + } + } + } + + private void createCar(){ + Collection roads = mapBuilder.getRoads(); + for(Road road: roads){ + if (road.getCarFactory() != null){ + if ((int)(Math.random() * 100) == 15){ + Car car = road.getCarFactory().buildCar(); + if (car != null){ + root.getChildren().add(car.getImageView()); + } + } + } + } + } + + public static void main(String[] args){ + launch(args); + } +} + diff --git a/src/edu/nd/se2018/homework/hwk4/model/infrastructure/Direction.java b/src/edu/nd/se2018/homework/hwk4/model/infrastructure/Direction.java new file mode 100644 index 00000000..8fc5532a --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk4/model/infrastructure/Direction.java @@ -0,0 +1,9 @@ +package edu.nd.se2018.homework.hwk4.model.infrastructure; + +public enum Direction { + NORTH, + SOUTH, + EAST, + WEST, + CUSTOM; +} diff --git a/src/edu/nd/se2018/homework/hwk4/model/infrastructure/MapBuilder.java b/src/edu/nd/se2018/homework/hwk4/model/infrastructure/MapBuilder.java new file mode 100644 index 00000000..ea3e994a --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk4/model/infrastructure/MapBuilder.java @@ -0,0 +1,71 @@ +package edu.nd.se2018.homework.hwk4.model.infrastructure; + +import java.awt.Point; +import java.util.Collection; +import java.util.HashMap; + +import edu.nd.se2018.homework.hwk4.model.infrastructure.gate.CrossingGate; + +/** + * Creates all infrastructure for the simulation + * + */ +public class MapBuilder { + HashMap roads; + HashMap gates; + HashMap tracks; + + public MapBuilder(){ + roads = new HashMap(); + gates = new HashMap(); + tracks = new HashMap(); + buildRoads(); + buildCrossingGates(); + buildTracks(); + assignGatesToRoads(); + buildCarFactories(); + } + + private void buildRoads(){ + roads.put("Western Highway",new Road(new Point(800,0),new Point (800,1000),Direction.SOUTH,true,false)); + roads.put("Skyway",new Road(new Point(400,0),new Point (400,1000),Direction.SOUTH,true,false)); + roads.put("EastWest",new Road(new Point(415,300),new Point (785,300),Direction.EAST,false,false)); + } + + private void buildCrossingGates(){ + gates.put("Gate1", new CrossingGate(780,480, "Gate1")); + gates.put("Gate2", new CrossingGate(380,480, "Gate2")); + } + + private void buildTracks(){ + tracks.put("Royal", new RailwayTracks(new Point(0,500),new Point(1200,500))); + tracks.put("New", new RailwayTracks(new Point(0,520),new Point(1200,520))); + } + + private void assignGatesToRoads(){ + roads.get("Western Highway").assignGate(gates.get("Gate1")); + roads.get("Western Highway").assignGate(gates.get("Gate2")); + roads.get("Skyway").assignGate(gates.get("Gate2")); + } + + private void buildCarFactories(){ + roads.get("Western Highway").addCarFactory(); + roads.get("Skyway").addCarFactory(); + } + + public Collection getAllGates(){ + return gates.values(); + } + + public Collection getTracks(){ + return tracks.values(); + } + + public Collection getRoads(){ + return roads.values(); + } + + public RailwayTracks getTrack(String name){ + return tracks.get(name); + } +} diff --git a/src/edu/nd/se2018/homework/hwk4/model/infrastructure/RailwayTracks.java b/src/edu/nd/se2018/homework/hwk4/model/infrastructure/RailwayTracks.java new file mode 100644 index 00000000..49963615 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk4/model/infrastructure/RailwayTracks.java @@ -0,0 +1,45 @@ +package edu.nd.se2018.homework.hwk4.model.infrastructure; + +import java.awt.Point; + +/** + * Railway Tracks (Entity Object) + * + */ +public class RailwayTracks { + + private int startX; + private int endX; + private int startY; + private int endY; + + public RailwayTracks(){} + + public RailwayTracks(Point startPoint, Point endPoint){ + startX = startPoint.x; + startY = startPoint.y; + endX = endPoint.x; + endY = endPoint.y; + } + + public int getStartX(){ + return startX; + } + + public int getEndX(){ + return endX; + } + + public int getStartY(){ + return startY; + } + + public int getEndY(){ + return endY; + } + + @Override + public String toString(){ + return "Tracks from (" + startX + "," + startY + ") to (" + endX + "," + endY + ")"; + } +} \ No newline at end of file diff --git a/src/edu/nd/se2018/homework/hwk4/model/infrastructure/Road.java b/src/edu/nd/se2018/homework/hwk4/model/infrastructure/Road.java new file mode 100644 index 00000000..8be0c9d5 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk4/model/infrastructure/Road.java @@ -0,0 +1,94 @@ +package edu.nd.se2018.homework.hwk4.model.infrastructure; + +import java.awt.Point; +import java.util.Collection; +import java.util.Vector; + +import edu.nd.se2018.homework.hwk4.model.infrastructure.gate.CrossingGate; +import edu.nd.se2018.homework.hwk4.model.vehicles.CarFactory; + +/** + * Represents a single road + * + */ +public class Road { + private int startX; + private int endX; + private int startY; + private int endY; + private CarFactory carFactory; + Direction direction; + Collection gates; + boolean clearEnds = false; + int roadSize; + int roadNum; + + public Road(){} + + public Road(Point start, Point end, Direction direction, boolean buildCarFactory, boolean clearEnds){ + startX = start.x; + startY = start.y; + endX = end.x; + endY = end.y; + roadSize = 18; + + if (startX == 400) { + roadNum = 0; + } + + if (startX == 800) { + roadNum = 1; + } + + this.direction = direction; + gates = new Vector(); + this.clearEnds = clearEnds; + + } + + // Adds a gate to a road + // In case a new gate is added after the factory is assigned, we reassign factory + // The factory needs to know all gates on the road in order to register each car as an observer. + public void assignGate(CrossingGate gate){ + gates.add(gate); + if (carFactory != null) + carFactory = new CarFactory(direction, new Point(startX-roadSize/2,startY), gates, roadNum); // allows additional gates. Needs fixing + } + + public void addCarFactory(){ + if (carFactory == null) // We only allow one + carFactory = new CarFactory(direction, new Point(startX-roadSize/2,startY), gates, roadNum); + } + + public CarFactory getCarFactory(){ + return carFactory; + } + + public int getStartX(){ + return startX; + } + + public int getEndX(){ + return endX; + } + + public int getStartY(){ + return startY; + } + + public int getEndY(){ + return endY; + } + + public Direction getDirection(){ + return direction; + } + + public boolean getClearEnds(){ + return clearEnds; + } + + public int getRoadWidth(){ + return roadSize; + } +} \ No newline at end of file diff --git a/src/edu/nd/se2018/homework/hwk4/model/infrastructure/gate/CrossingGate.java b/src/edu/nd/se2018/homework/hwk4/model/infrastructure/gate/CrossingGate.java new file mode 100644 index 00000000..9ba5bc41 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk4/model/infrastructure/gate/CrossingGate.java @@ -0,0 +1,155 @@ +package edu.nd.se2018.homework.hwk4.model.infrastructure.gate; + +import java.util.Observable; +import java.util.Observer; + +import edu.nd.se2018.homework.hwk4.model.infrastructure.Direction; +import edu.nd.se2018.homework.hwk4.model.vehicles.Train; +import javafx.scene.layout.Pane; +import javafx.scene.paint.Color; +import javafx.scene.shape.Line; + +/** + * Context class for Crossing Gate + * + */ +public class CrossingGate extends Observable implements Observer{ + + // Crossing Gate location and its trigger & exit points + private int anchorX; + private int anchorY; + private int movingX; + private int movingY; + private int triggerPoint1; + private int triggerPoint2; + private int exitPoint1; + private int exitPoint2; + private Boolean train1, train2; + + private IGateState gateClosed; + private IGateState gateOpen; + private IGateState gateClosing; + private IGateState gateOpening; + private IGateState currentGateState; + private Line line; + private Pane root; + + public String gateName; + + public CrossingGate(){} + + public CrossingGate(int xPosition, int yPosition, String crossingGate){ + anchorX = xPosition; + anchorY = yPosition; + movingX = anchorX; + movingY = anchorY-60; + triggerPoint1 = anchorX+250; + triggerPoint2 = anchorX-250; + exitPoint1 = anchorX-250; + exitPoint2 = anchorX+250; + train1 = false; + train2 = false; + + // Gate elements + line = new Line(anchorX, anchorY,movingX,movingY); + line.setStroke(Color.RED); + line.setStrokeWidth(10); + + // Gate States + gateClosed = new GateClosed(this); + gateOpen = new GateOpen(this); + gateOpening = new GateOpening(this); + gateClosing = new GateClosing(this); + currentGateState = gateOpen; + gateName = crossingGate; + } + + public Line getGateLine(){ + return line; + } + + public void operateGate(){ + currentGateState.operate(); + } + + public void close(){ + if (movingYanchorX){ + movingX-=1; + movingY-=1; + line.setStartX(anchorX); + line.setStartY(anchorY); + line.setEndX(movingX); + line.setEndY(movingY); + } else { + currentGateState.gateFinishedOpening(); + } + } + + // State getters and setters + public IGateState getGateClosedState(){ + return gateClosed; + } + public IGateState getGateOpenState(){ + return gateOpen; + } + public IGateState getGateClosingState(){ + return gateClosing; + } + public IGateState getGateOpeningState(){ + return gateOpening; + } + + public void setGateState(IGateState newState){ + currentGateState = newState; + setChanged(); + notifyObservers(); + } + + public String getTrafficCommand(){ + return currentGateState.getTrafficAction(); + } + + @Override + public void update(Observable o, Object arg) { + if (o instanceof Train){ + Train train = (Train)o; + if (train.getDirection() == Direction.WEST) { + if (train.getVehicleX() < exitPoint1) { + if (train2 == false) { + currentGateState.leaveStation(); + } + train1 = false; + } + else if(train.getVehicleX() < triggerPoint1) { //|| train.getVehicleX() < triggerPoint2) { + currentGateState.approachStation(); + train1 = true; + } + } + else if (train.getDirection() == Direction.EAST) { + if (train.getVehicleX() > exitPoint2) { + if (train1 == false) { + currentGateState.leaveStation(); + } + train2 = false; + } + else if (train.getVehicleX() > triggerPoint2) { //|| train.getVehicleX() < triggerPoint1) { + currentGateState.approachStation(); + train2 = true; + } + } + } + } +} diff --git a/src/edu/nd/se2018/homework/hwk4/model/infrastructure/gate/GateClosed.java b/src/edu/nd/se2018/homework/hwk4/model/infrastructure/gate/GateClosed.java new file mode 100644 index 00000000..d99a37c2 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk4/model/infrastructure/gate/GateClosed.java @@ -0,0 +1,48 @@ +package edu.nd.se2018.homework.hwk4.model.infrastructure.gate; + +/** + * Gate in CLOSED state + * + */ +public class GateClosed implements IGateState { + + private CrossingGate gate; + + protected GateClosed(CrossingGate gate){ + this.gate = gate; + } + + @Override + public void approachStation() { + // Do nothing. Gate is already closed. + // IF there were two tracks we would have to keep track of how many trains were in the station! + } + + @Override + public void leaveStation() { + gate.setGateState(gate.getGateOpeningState()); + } + + @Override + public void gateFinishedOpening() { + // not applicable + } + + @Override + public void gateFinishedClosing() { + // not applicable. Gate is already closed. + } + + @Override + public void operate() { + // Flash lights + + } + + @Override + public String getTrafficAction() { + return "STOP"; + } + + +} diff --git a/src/edu/nd/se2018/homework/hwk4/model/infrastructure/gate/GateClosing.java b/src/edu/nd/se2018/homework/hwk4/model/infrastructure/gate/GateClosing.java new file mode 100644 index 00000000..7d678d03 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk4/model/infrastructure/gate/GateClosing.java @@ -0,0 +1,49 @@ +package edu.nd.se2018.homework.hwk4.model.infrastructure.gate; + +/** + * Gate in closing state + * + */ +public class GateClosing implements IGateState{ + + private CrossingGate gate; + + protected GateClosing(CrossingGate gate){ + this.gate = gate; + } + + @Override + public void approachStation() { + // Gate is already closing + } + + @Override + public void leaveStation() { + // This was an unwanted event. The gate wasn't fully closed when the train was in the station. + // Nevertheless we will open the gate. + gate.setGateState(gate.getGateOpeningState()); + } + + @Override + public void gateFinishedOpening() { + // n/a + } + + @Override + public void gateFinishedClosing() { + gate.setGateState(gate.getGateClosedState()); + } + + @Override + public void operate() { + gate.close(); + // flash lights + } + + @Override + public String getTrafficAction() { + return "STOP"; + } + + +} diff --git a/src/edu/nd/se2018/homework/hwk4/model/infrastructure/gate/GateOpen.java b/src/edu/nd/se2018/homework/hwk4/model/infrastructure/gate/GateOpen.java new file mode 100644 index 00000000..b65553a3 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk4/model/infrastructure/gate/GateOpen.java @@ -0,0 +1,45 @@ +package edu.nd.se2018.homework.hwk4.model.infrastructure.gate; + +/** + * Gate in open state + * + */ +public class GateOpen implements IGateState { + + private CrossingGate gate; + + protected GateOpen(CrossingGate gate){ + this.gate = gate; + } + + @Override + public void approachStation() { + gate.setGateState(gate.getGateClosingState()); + } + + @Override + public void leaveStation() { + // n/a gate already open + } + + @Override + public void gateFinishedOpening() { + // n/a gate already open + } + + @Override + public void gateFinishedClosing() { + // n/a can't be closing and opened. + } + + @Override + public void operate() { + // Normal operation. Do nothing. + } + + @Override + public String getTrafficAction() { + return "GO"; + } + +} diff --git a/src/edu/nd/se2018/homework/hwk4/model/infrastructure/gate/GateOpening.java b/src/edu/nd/se2018/homework/hwk4/model/infrastructure/gate/GateOpening.java new file mode 100644 index 00000000..adb4352e --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk4/model/infrastructure/gate/GateOpening.java @@ -0,0 +1,48 @@ +package edu.nd.se2018.homework.hwk4.model.infrastructure.gate; + +/** + * Gate in opening state + * @author jane + * + */ +public class GateOpening implements IGateState{ + + CrossingGate gate; + + protected GateOpening(CrossingGate gate){ + this.gate = gate; + } + + @Override + public void approachStation() { + gate.setGateState(gate.getGateClosingState()); + } + + @Override + public void leaveStation() { + // Already opening. + } + + @Override + public void gateFinishedOpening() { + gate.setGateState(gate.getGateOpenState()); + } + + @Override + public void gateFinishedClosing() { + // not reachable except through error. + // Raise an alarm!! + } + + @Override + public void operate() { + gate.open(); + // Flash lights.. + } + + @Override + public String getTrafficAction() { + return "STOP"; + } + +} diff --git a/src/edu/nd/se2018/homework/hwk4/model/infrastructure/gate/IGateState.java b/src/edu/nd/se2018/homework/hwk4/model/infrastructure/gate/IGateState.java new file mode 100644 index 00000000..3ad398fd --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk4/model/infrastructure/gate/IGateState.java @@ -0,0 +1,14 @@ +package edu.nd.se2018.homework.hwk4.model.infrastructure.gate; + +/** + * Declares all operations that GateState classes must implement + * + */ +public interface IGateState { + public void approachStation(); + public void leaveStation(); + public void gateFinishedOpening(); + public void gateFinishedClosing(); + public void operate(); + public String getTrafficAction(); +} diff --git a/src/edu/nd/se2018/homework/hwk4/model/vehicles/Car.java b/src/edu/nd/se2018/homework/hwk4/model/vehicles/Car.java new file mode 100644 index 00000000..55407701 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk4/model/vehicles/Car.java @@ -0,0 +1,137 @@ +package edu.nd.se2018.homework.hwk4.model.vehicles; + +import java.util.Observable; +import java.util.Observer; + +import edu.nd.se2018.homework.hwk4.model.infrastructure.gate.CrossingGate; +import edu.nd.se2018.homework.hwk4.view.CarImageSelector; +import javafx.scene.Node; +import javafx.scene.image.ImageView; + +/** + * Represents Car object + * + */ +public class Car extends Observable implements IVehicle, Observer{ + private ImageView ivCar; + private double currentX = 0; + private double currentY = 0; + private double originalY = 0; + private boolean gateDown = false; + private double leadCarY = -1; // Current Y position of car directly infront of this one + private double speed = 0.5; + public boolean turn = false; + + /** + * Constructor + * @param x initial x coordinate of car + * @param y initial y coordinate of car + */ + public Car(int x, int y){ + this.currentX = x; + this.currentY = y; + originalY = y; + ivCar = new ImageView(CarImageSelector.getImage()); + ivCar.setX(getVehicleX()); + ivCar.setY(getVehicleY()); + } + + @Override + public Node getImageView() { + return ivCar; + } + + public boolean gateIsClosed(){ + return gateDown; + } + + public double getVehicleX(){ + return currentX; + } + public double getVehicleY(){ + return currentY; + } + + public void move(){ + boolean canMove = true; + + // First case. Car is at the front of the stopping line. + if (gateDown && getVehicleY() < 430 && getVehicleY()> 390) + canMove = false; + + // Second case. Car is too close too other car. + if (leadCarY != -1 && getDistanceToLeadCar() < 50) + canMove = false; + + if (canMove){ + if (turn == false) { + currentY+=speed; + ivCar.setY(currentY); + } + else { + if (currentY >= 282 && currentY <= 300) { + if (currentX < 800 && currentX > 400) { + currentX -= speed; + ivCar.setX(currentX); + } + else { + currentY+=speed; + ivCar.setY(currentY); + } + + } + else { + currentY+=speed; + ivCar.setY(currentY); + } + } + setChanged(); + notifyObservers(); + } + } + + public void setSpeed(double speed){ + this.speed = speed; + } + + public void setGateDownFlag(boolean gateDown){ + this.gateDown = gateDown; + } + + public boolean offScreen(){ + if (currentY > 1020) + return true; + else + return false; + } + + public void reset(){ + currentY = originalY; + } + + public double getDistanceToLeadCar(){ + return Math.abs(leadCarY-getVehicleY()); + } + + public void removeLeadCar(){ + leadCarY = -1; + } + + @Override + public void update(Observable o, Object arg1) { + if (o instanceof Car){ + leadCarY = (((Car)o).getVehicleY()); + if (leadCarY > 1020) + leadCarY = -1; + } + + if (o instanceof CrossingGate){ + CrossingGate gate = (CrossingGate)o; + if(gate.getTrafficCommand()=="STOP") + gateDown = true; + else + gateDown = false; + + } + } +} diff --git a/src/edu/nd/se2018/homework/hwk4/model/vehicles/CarFactory.java b/src/edu/nd/se2018/homework/hwk4/model/vehicles/CarFactory.java new file mode 100644 index 00000000..cda6fe8e --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk4/model/vehicles/CarFactory.java @@ -0,0 +1,121 @@ +package edu.nd.se2018.homework.hwk4.model.vehicles; + +import java.awt.Point; +import java.util.ArrayList; +import java.util.Collection; + +import edu.nd.se2018.homework.hwk4.model.infrastructure.Direction; +import edu.nd.se2018.homework.hwk4.model.infrastructure.gate.CrossingGate; + + +/** + * Very basic car factory. Creates the car and registers it with the crossing gate and the car infront of it. + * + */ +public class CarFactory { + + private Collection gates = null; + private Car previousCar = null; + private ArrayList cars = new ArrayList(); + Direction direction; + Point location; + int roadNum; + + public CarFactory(){} + + public CarFactory(Direction direction, Point location, Collection gates, int road){ + this.direction = direction; + this.location = location; + this.gates = gates; + this.roadNum = road; + } + + + // Most code here is to create random speeds + public Car buildCar(){ + if (previousCar == null || location.y < previousCar.getVehicleY()-100){ + Car car = new Car(location.x,location.y); + double speedVariable = (Math.random() * 10)/10; + car.setSpeed((2-speedVariable)*1.5); + if (Math.floor(speedVariable * 10) % 4 == 0) { + car.turn = true; + } + + // All cars created by this factory must be aware of crossing gates in the road + if (roadNum == 0) { + for(CrossingGate gate: gates){ + if (gate.gateName == "Gate2") { + gate.addObserver(car); + } + if(gate != null && gate.getTrafficCommand()=="STOP") { + car.setGateDownFlag(false); + } + } + } + else if (roadNum == 1) { + if (car.turn == false) { + for(CrossingGate gate: gates){ + if (gate.gateName == "Gate1") { + gate.addObserver(car); + } + if(gate != null && gate.getTrafficCommand()=="STOP") { + car.setGateDownFlag(false); + } + } + } + else { + for(CrossingGate gate: gates){ + if (gate.gateName == "Gate2") { + gate.addObserver(car); + } + if(gate != null && gate.getTrafficCommand()=="STOP") { + car.setGateDownFlag(false); + } + } + } + } + /*else { + for(CrossingGate gate: gates){ + if (gate.gateName == "Gate1") { + gate.addObserver(car); + } + if(gate != null && gate.getTrafficCommand()=="STOP") { + car.setGateDownFlag(false); + } + } + }*/ + /*for(CrossingGate gate: gates){ + //gate.addObserver(car); + if(gate != null && gate.getTrafficCommand()=="STOP") + car.setGateDownFlag(false); + }*/ + + // Each car must observe the car infront of it so it doesn't collide with it. + if (previousCar != null && previousCar.turn == false) + previousCar.addObserver(car); + previousCar = car; + + cars.add(car); + return car; + } else + return null; + } + + // We will get a concurrency error if we try to delete cars whilst iterating through the array list + // so we perform this in two stages. + // 1. Loop through the list and identify which cars are off the screen. Add them to 'toDelete' array. + // 2. Iterate through toDelete and remove the cars from the original arrayList. + public ArrayList removeOffScreenCars() { + // Removing cars from the array list. + ArrayList toDelete = new ArrayList(); + for(Car car: cars){ + car.move(); + if (car.offScreen()) + toDelete.add(car); + + } + for (Car car: toDelete) + cars.remove(car); + return toDelete; + } +} diff --git a/src/edu/nd/se2018/homework/hwk4/model/vehicles/IVehicle.java b/src/edu/nd/se2018/homework/hwk4/model/vehicles/IVehicle.java new file mode 100644 index 00000000..90d10968 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk4/model/vehicles/IVehicle.java @@ -0,0 +1,13 @@ +package edu.nd.se2018.homework.hwk4.model.vehicles; + +import javafx.scene.Node; + + +public interface IVehicle { + public Node getImageView(); + public double getVehicleX(); + public double getVehicleY(); + public void move(); + public boolean offScreen(); + public void reset(); +} diff --git a/src/edu/nd/se2018/homework/hwk4/model/vehicles/Train.java b/src/edu/nd/se2018/homework/hwk4/model/vehicles/Train.java new file mode 100644 index 00000000..c09b7478 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk4/model/vehicles/Train.java @@ -0,0 +1,85 @@ +package edu.nd.se2018.homework.hwk4.model.vehicles; + +import java.util.Observable; + +import edu.nd.se2018.homework.hwk4.model.infrastructure.Direction; +import javafx.scene.Node; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; + +/** + * Represents the train entity object + * + */ +public class Train extends Observable implements IVehicle{ + private double currentX = 0; + private double currentY = 0; + private double originalX = 0; + private Image img; + private ImageView imgView; + private int trainLength = 35; + Direction direction; + + public Train(int x, int y, Direction d){ + this.currentX = x; + this.currentY = y; + originalX = x; + this.direction = d; + img = new Image("/images/Train.PNG" ,120,trainLength,false,false); + imgView = new ImageView(img); + if (d == Direction.EAST) { + imgView.setScaleX(-1); + } + imgView.setX(currentX); + imgView.setY(currentY); + } + + public Direction getDirection() { + return this.direction; + } + + public double getVehicleX(){ + return currentX; + } + + public double getVehicleY(){ + return currentY; + } + + public void move(){ + if (direction == Direction.WEST) { + currentX-=2; + } + else { + currentX+=2; + } + imgView.setX(currentX); + setChanged(); + notifyObservers(); + } + + public boolean offScreen(){ + if (direction == Direction.WEST) { + if (currentX < -200) + return true; + else + return false; + } + else { + if (currentX > 1600) + return true; + else + return false; + + } + } + + public void reset(){ + currentX = originalX; + } + + //@Override + public Node getImageView() { + return imgView; + } +} \ No newline at end of file diff --git a/src/edu/nd/se2018/homework/hwk4/view/CarImageSelector.java b/src/edu/nd/se2018/homework/hwk4/view/CarImageSelector.java new file mode 100644 index 00000000..fefc5be8 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk4/view/CarImageSelector.java @@ -0,0 +1,23 @@ +package edu.nd.se2018.homework.hwk4.view; + +import javafx.scene.image.Image; + +public class CarImageSelector { + + + public static Image getImage(){ + int imageSize = 20; + int pickNum = (int)(Math.random() * 4); + Image img; + switch(pickNum){ + case 0: img = new Image("/images/bluecar.PNG",imageSize,imageSize,false,true); + break; + case 2: img = new Image("/images/graycar.PNG",imageSize,imageSize,false,true); + break; + case 3: img = new Image("/images/greencar.PNG",imageSize,imageSize,false,true); + break; + default: img = new Image("/images/redcar.PNG",imageSize,imageSize,false,true); + } + return img; + } +} \ No newline at end of file diff --git a/src/edu/nd/se2018/homework/hwk4/view/IDisplay.java b/src/edu/nd/se2018/homework/hwk4/view/IDisplay.java new file mode 100644 index 00000000..d0efbde7 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk4/view/IDisplay.java @@ -0,0 +1,5 @@ +package edu.nd.se2018.homework.hwk4.view; + +public interface IDisplay { + public void draw(); +} diff --git a/src/edu/nd/se2018/homework/hwk4/view/MapDisplay.java b/src/edu/nd/se2018/homework/hwk4/view/MapDisplay.java new file mode 100644 index 00000000..a10879fb --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk4/view/MapDisplay.java @@ -0,0 +1,52 @@ +package edu.nd.se2018.homework.hwk4.view; + +import java.util.ArrayList; +import java.util.Collection; + +import edu.nd.se2018.homework.hwk4.model.infrastructure.RailwayTracks; +import edu.nd.se2018.homework.hwk4.model.infrastructure.Road; +import edu.nd.se2018.homework.hwk4.model.infrastructure.gate.CrossingGate; +import edu.nd.se2018.homework.hwk4.model.vehicles.Car; +import javafx.scene.layout.Pane; + +/** + * Called by JavaFX main UI thread to help display elements on the UI + * + */ +public class MapDisplay { + Pane root; + IDisplay roadDisplay, tracksDisplay; + Collection roads; + Collection track; + Collection gates; + + + public MapDisplay(Pane root, Collection roads, Collection tracks, Collection gates){ + this.root = root; + this.roads= roads; + this.track = tracks; + this.gates = gates; + roadDisplay = new RoadDisplay(roads,root); + tracksDisplay = new TracksDisplay(tracks,root); + } + + public void drawTracks(){ + tracksDisplay.draw(); + } + + public void drawRoad(){ + roadDisplay.draw(); + } + + public void drawGate(){ + for (CrossingGate gate: gates) + root.getChildren().add(gate.getGateLine()); + } + + + public void removeCarImages(ArrayList junkCars) { + for(Car car: junkCars) + root.getChildren().remove(car.getImageView()); + + } +} diff --git a/src/edu/nd/se2018/homework/hwk4/view/RoadDisplay.java b/src/edu/nd/se2018/homework/hwk4/view/RoadDisplay.java new file mode 100644 index 00000000..1fb18d5b --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk4/view/RoadDisplay.java @@ -0,0 +1,50 @@ +package edu.nd.se2018.homework.hwk4.view; + +import java.util.Collection; + +import edu.nd.se2018.homework.hwk4.model.infrastructure.Direction; +import edu.nd.se2018.homework.hwk4.model.infrastructure.Road; +import javafx.scene.layout.Pane; +import javafx.scene.paint.Color; +import javafx.scene.shape.Line; + + +/** + * Draws a road + * + */ +public class RoadDisplay implements IDisplay { + Pane root; + Collection roads; + int roadSize; + + + public RoadDisplay(Collection roads, Pane root){ + this.root = root; + this.roads = roads; + + } + + @Override + public void draw() { + for(Road road: roads){ + roadSize = road.getRoadWidth(); + if (road.getDirection() == Direction.NORTH || road.getDirection() == Direction.SOUTH) { + root.getChildren().add(new Line(road.getStartX()-roadSize,road.getStartY(),road.getEndX()-roadSize,road.getEndY())); + root.getChildren().add(new Line(road.getStartX()+roadSize,road.getStartY(),road.getEndX()+roadSize,road.getEndY())); + } else { + root.getChildren().add(new Line(road.getStartX(),road.getStartY()-roadSize,road.getEndX(),road.getEndY()-roadSize)); + root.getChildren().add(new Line(road.getStartX(),road.getStartY()+roadSize,road.getEndX(),road.getEndY()+roadSize)); + if (road.getClearEnds()){ + Line line = new Line(road.getStartX(),road.getStartY()-roadSize,road.getStartX(),road.getStartY()+roadSize); + line.setStroke(Color.WHITE); + root.getChildren().add(line); + Line line2 = new Line(road.getEndX(),road.getEndY()-roadSize,road.getEndX(),road.getEndY()+roadSize); + line2.setStroke(Color.WHITE); + root.getChildren().add(line2); + } + } + } + } +} + diff --git a/src/edu/nd/se2018/homework/hwk4/view/TracksDisplay.java b/src/edu/nd/se2018/homework/hwk4/view/TracksDisplay.java new file mode 100644 index 00000000..bc0290c0 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk4/view/TracksDisplay.java @@ -0,0 +1,34 @@ +package edu.nd.se2018.homework.hwk4.view; + +import java.util.Collection; + +import edu.nd.se2018.homework.hwk4.model.infrastructure.RailwayTracks; +import javafx.scene.layout.Pane; +import javafx.scene.shape.Line; + + +/** + * Draws a track + * + */ +public class TracksDisplay implements IDisplay { + Pane root; + Collection tracks; + int trackSize = 16; + + public TracksDisplay(Collection tracks, Pane root){ + this.root = root; + this.tracks = tracks; + } + + @Override + public void draw() { + for(RailwayTracks track: tracks){ + root.getChildren().add(new Line(track.getStartX(),track.getStartY()-trackSize,track.getEndX(),track.getEndY()-trackSize)); + root.getChildren().add(new Line(track.getStartX(),track.getStartY()+trackSize,track.getEndX(),track.getEndY()+trackSize)); + for(int j = track.getStartX()+(trackSize/2); j < track.getEndX(); j+=trackSize){ + root.getChildren().add(new Line(j,track.getStartY()-trackSize - 2,j,track.getEndY()+trackSize+2)); + } + } + } +} diff --git a/src/edu/nd/se2018/homework/hwk6/Chips Challenge Reflection.pdf b/src/edu/nd/se2018/homework/hwk6/Chips Challenge Reflection.pdf new file mode 100644 index 00000000..21e97aac Binary files /dev/null and b/src/edu/nd/se2018/homework/hwk6/Chips Challenge Reflection.pdf differ diff --git a/src/edu/nd/se2018/homework/hwk6/ChipsChallenge-FinalUMLpng.png b/src/edu/nd/se2018/homework/hwk6/ChipsChallenge-FinalUMLpng.png new file mode 100644 index 00000000..bcb23558 Binary files /dev/null and b/src/edu/nd/se2018/homework/hwk6/ChipsChallenge-FinalUMLpng.png differ diff --git a/src/edu/nd/se2018/homework/hwk6/First Deliverable/Chip's Challenge - 1st deliverable.pdf b/src/edu/nd/se2018/homework/hwk6/First Deliverable/Chip's Challenge - 1st deliverable.pdf new file mode 100644 index 00000000..70eb86e8 Binary files /dev/null and b/src/edu/nd/se2018/homework/hwk6/First Deliverable/Chip's Challenge - 1st deliverable.pdf differ diff --git a/src/edu/nd/se2018/homework/hwk6/First Deliverable/ChipsChallenge-UML.png b/src/edu/nd/se2018/homework/hwk6/First Deliverable/ChipsChallenge-UML.png new file mode 100644 index 00000000..54bf1621 Binary files /dev/null and b/src/edu/nd/se2018/homework/hwk6/First Deliverable/ChipsChallenge-UML.png differ diff --git a/src/edu/nd/se2018/homework/hwk6/First Deliverable/Screen Shot 2018-09-30 at 7.46.56 PM.png b/src/edu/nd/se2018/homework/hwk6/First Deliverable/Screen Shot 2018-09-30 at 7.46.56 PM.png new file mode 100644 index 00000000..41d7c1ef Binary files /dev/null and b/src/edu/nd/se2018/homework/hwk6/First Deliverable/Screen Shot 2018-09-30 at 7.46.56 PM.png differ diff --git a/src/edu/nd/se2018/homework/hwk6/Main.java b/src/edu/nd/se2018/homework/hwk6/Main.java new file mode 100644 index 00000000..5ed7defa --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk6/Main.java @@ -0,0 +1,104 @@ +package edu.nd.se2018.homework.hwk6; +import javafx.animation.AnimationTimer; +import javafx.application.Application; +import javafx.event.EventHandler; +import javafx.scene.Scene; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; +import javafx.scene.layout.AnchorPane; +import javafx.stage.Stage; +import edu.nd.se2018.homework.hwk6.controller.ChipController; +import edu.nd.se2018.homework.hwk6.controller.MonsterController; +import edu.nd.se2018.homework.hwk6.controller.MoveHorizontal; +import edu.nd.se2018.homework.hwk6.controller.MoveVertical; +import edu.nd.se2018.homework.hwk6.model.MonsterModel; +import edu.nd.se2018.homework.hwk6.view.*; + +public class Main extends Application { + AnchorPane root; + Scene scene; + MapDisplay gameMap; + ImageView[][] tiles; + Image tileImage; + int scale = 20; + ChipView chipView; + ChipController chipController; + MonsterController monsterController1, monsterController2; + MonsterModel monster1, monster2; + int level = 1; + + @Override + public void start(Stage gameStage) throws Exception { + root = new AnchorPane(); + Scene scene = new Scene(root, 500, 500); + gameMap = new MapDisplay(); + + gameMap.setBlocks(); + gameMap.setLevel(level); + gameMap.drawMap(root.getChildren(), 20); + + + chipController = new ChipController(gameMap); + monsterController1 = new MonsterController(gameMap, new MoveVertical(), 20, 10); + monsterController2 = new MonsterController(gameMap, new MoveHorizontal(), 10, 15); + + monster1 = monsterController1.getModel(); + monster1.addObserver(chipController.getModel()); + + monster2 = monsterController2.getModel(); + monster2.addObserver(chipController.getModel()); + + root.getChildren().add(chipController.getImageView()); + root.getChildren().add(monsterController1.getImageView()); + root.getChildren().add(monsterController2.getImageView()); + + gameStage.setScene(scene); + gameStage.setTitle("Chip's Challenge"); + gameStage.show(); + + gameStage.addEventHandler(KeyEvent.KEY_RELEASED, (KeyEvent event) -> { + if (event.getCode() == KeyCode.ESCAPE) { + gameStage.close(); + } + }); + + startGame(scene); + + new AnimationTimer(){ + //@Override + int count = 0; + public void handle(long now) { + if (count % 10 == 0) { + monsterController1.runStrategy(); + monsterController2.runStrategy(); + } + count++; + + if (gameMap.getStatus() == true) { + root.getChildren().add(chipController.getImageView()); + root.getChildren().add(monsterController1.getImageView()); + root.getChildren().add(monsterController2.getImageView()); + gameMap.resetStatus(); + } + } + }.start(); + } + + private void startGame(Scene scene) { + scene.setOnKeyPressed(new EventHandler() { + + public void handle(KeyEvent event) { + chipController.moveEvent(event); + } + }); + } + + public static void main(String[] args) { + launch(args); + + } + + +} diff --git a/src/edu/nd/se2018/homework/hwk6/controller/ChipController.java b/src/edu/nd/se2018/homework/hwk6/controller/ChipController.java new file mode 100644 index 00000000..596cbfda --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk6/controller/ChipController.java @@ -0,0 +1,187 @@ +package edu.nd.se2018.homework.hwk6.controller; + +import edu.nd.se2018.homework.hwk6.model.ChipModel; +import edu.nd.se2018.homework.hwk6.view.ChipView; +import edu.nd.se2018.homework.hwk6.view.MapDisplay; +import javafx.scene.Node; +import javafx.scene.input.KeyEvent; + +public class ChipController { + public ChipModel chip; + public ChipView chipView; + public MapDisplay gameMap; + public int[] pos; + public int [][] map; + public int keys; + boolean update = false; + int x; + int y; + boolean allChips = false; + + public ChipController(MapDisplay gMap) { + gameMap = gMap; + map = gameMap.getMap(); + keys = gameMap.getLevel()*5; + + chip = new ChipModel(0, 0, map, keys); + chipView = new ChipView(chip); + chip.attachView(chipView); + pos = chip.getPosition(); + } + + public void moveEvent(KeyEvent ke) { + + if (update == true) { + gameMap.removeKey(x, y); + allChips = chip.allKeysCollected(); + } + + switch(ke.getCode()){ + case RIGHT: + moveRight(); + break; + case LEFT: + moveLeft(); + break; + case UP: + moveUp(); + break; + case DOWN: + moveDown(); + break; + default: + break; + } + + } + + public Node getImageView() { + return chipView.view; + } + + public ChipModel getModel() { + return chip; + } + + public void moveRight() { + int[] pos = new int[2]; + pos = chip.getPosition(); + x = pos[0]; + y = pos[1]; + if (x + 1 < 25) { + if (map[x + 1][y] != 1) { + x++; + if (map[x][y] == 2) { + gameMap.setMap(x, y, 0); + chip.addKey(); + update = true; + } + else { + update = false; + } + } + if (allChips == true) { + if (map[x][y] == 4) { + gameMap.setMap(x, y, 0); + levelWon(); + + } + } + } + this.chip.setPosition(x, y); + } + + public void moveLeft() { + int[] pos = new int[2]; + pos = chip.getPosition(); + x = pos[0]; + y = pos[1]; + if (x - 1 >= 0) { + if (map[x - 1][y] != 1) { + x--; + if (map[x][y] == 2) { + gameMap.setMap(x, y, 0); + chip.addKey(); + update = true; + } + else { + update = false; + } + } + if (allChips == true) { + if (map[x][y] == 4) { + gameMap.setMap(x, y, 0); + levelWon();; + } + } + } + this.chip.setPosition(x, y); + } + + public void moveUp() { + int[] pos = new int[2]; + pos = chip.getPosition(); + x = pos[0]; + y = pos[1]; + if (y - 1 >= 0) { + if (map[x][y - 1] != 1) { + y--; + if (map[x][y] == 2) { + gameMap.setMap(x, y, 0); + chip.addKey(); + update = true; + } + else { + update = false; + } + } + if (allChips == true) { + if (map[x][y] == 4) { + gameMap.setMap(x, y, 0); + levelWon(); + } + } + } + this.chip.setPosition(x, y); + } + + public void moveDown() { + int[] pos = new int[2]; + pos = chip.getPosition(); + x = pos[0]; + y = pos[1]; + if (y + 1 < 25) { + if (map[x][y + 1] != 1) { + y++; + if (map[x][y] == 2 ) { + gameMap.setMap(x, y, 0); + chip.addKey(); + update = true; + } + else { + update = false; + } + } + if (allChips == true) { + if (map[x][y] == 4) { + gameMap.setMap(x, y, 0); + levelWon(); + + } + } + } + this.chip.setPosition(x, y); + } + + public void levelWon() { + System.out.println("level won"); + gameMap.reset(); + //chip.setPosition(0, 0); + //chip = new ChipModel(0, 0, map, keys); + chipView = new ChipView(chip); + chip.attachView(chipView); + chip.setPosition(0, 0); + pos = chip.getPosition(); + } + +} diff --git a/src/edu/nd/se2018/homework/hwk6/controller/MonsterController.java b/src/edu/nd/se2018/homework/hwk6/controller/MonsterController.java new file mode 100644 index 00000000..b32a4370 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk6/controller/MonsterController.java @@ -0,0 +1,46 @@ +package edu.nd.se2018.homework.hwk6.controller; + +import edu.nd.se2018.homework.hwk6.model.MonsterModel; +import edu.nd.se2018.homework.hwk6.view.MapDisplay; +import edu.nd.se2018.homework.hwk6.view.MonsterView; +import javafx.scene.Node; + +public class MonsterController { + public MonsterModel monster; + public MonsterView monsterView; + public MapDisplay gameMap; + public int[] pos; + public int [][] map; + int x; + int y; + MoveStrategy strategy; + + public MonsterController(MapDisplay gMap, MoveStrategy s, int x, int y) { + gameMap = gMap; + map = gameMap.getMap(); + + monster = new MonsterModel(x, y); + monsterView = new MonsterView(monster); + monster.attachView(monsterView); + pos = monster.getPosition(); + + strategy = s; + } + + public Node getImageView() { + return monsterView.view; + } + + public MonsterModel getModel() { + return monster; + } + + public void runStrategy() { + pos = monster.getPosition(); + x = pos[0]; + y = pos[1]; + pos = strategy.move(x, y); + monster.setPosition(pos[0], pos[1]); + } + +} diff --git a/src/edu/nd/se2018/homework/hwk6/controller/MoveHorizontal.java b/src/edu/nd/se2018/homework/hwk6/controller/MoveHorizontal.java new file mode 100644 index 00000000..07cf7fff --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk6/controller/MoveHorizontal.java @@ -0,0 +1,25 @@ +package edu.nd.se2018.homework.hwk6.controller; + +public class MoveHorizontal implements MoveStrategy { + public int direction = 1; + + public int[] move(int xPos, int yPos) { + int x = xPos; + int y = yPos; + int[] pos = new int[2]; + + if ((x < 15) && (x > 5)) { + x = x + direction; + } + else { + direction = direction * -1; + x = x + direction; + } + + pos[0] = x; + pos[1] = y; + + return(pos); + + } +} diff --git a/src/edu/nd/se2018/homework/hwk6/controller/MoveStrategy.java b/src/edu/nd/se2018/homework/hwk6/controller/MoveStrategy.java new file mode 100644 index 00000000..a5f3f74c --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk6/controller/MoveStrategy.java @@ -0,0 +1,6 @@ +package edu.nd.se2018.homework.hwk6.controller; + +public interface MoveStrategy { + public int[] move(int xPos, int yPos); + +} diff --git a/src/edu/nd/se2018/homework/hwk6/controller/MoveVertical.java b/src/edu/nd/se2018/homework/hwk6/controller/MoveVertical.java new file mode 100644 index 00000000..8d5395d0 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk6/controller/MoveVertical.java @@ -0,0 +1,26 @@ +package edu.nd.se2018.homework.hwk6.controller; + +public class MoveVertical implements MoveStrategy { + public int direction = 1; + + public int[] move(int xPos, int yPos) { + int x = xPos; + int y = yPos; + int[] pos = new int[2]; + + if ((y < 15) && (y > 5)) { + y = y + direction; + } + else { + direction = direction * -1; + y = y + direction; + } + + pos[0] = x; + pos[1] = y; + + return(pos); + + } + +} diff --git a/src/edu/nd/se2018/homework/hwk6/model/AllChips.java b/src/edu/nd/se2018/homework/hwk6/model/AllChips.java new file mode 100644 index 00000000..381cd45a --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk6/model/AllChips.java @@ -0,0 +1,29 @@ +package edu.nd.se2018.homework.hwk6.model; + +public class AllChips implements GameState { + + private ChipModel chip; + + protected AllChips(ChipModel chip) { + this.chip = chip; + } + + @Override + public void allChipsCollected() { + // TODO Auto-generated method stub + + } + + @Override + public void levelWon() { + chip.setGameState(chip.getGameWonState()); + + } + + @Override + public void running() { + // TODO Auto-generated method stub + + } + +} diff --git a/src/edu/nd/se2018/homework/hwk6/model/ChipModel.java b/src/edu/nd/se2018/homework/hwk6/model/ChipModel.java new file mode 100644 index 00000000..701bb8ca --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk6/model/ChipModel.java @@ -0,0 +1,101 @@ +package edu.nd.se2018.homework.hwk6.model; + +import java.util.Observable; +import java.util.Observer; + +import edu.nd.se2018.homework.hwk6.view.ChipView; + +public class ChipModel extends Observable implements Observer { + int keys; + int x; + int y; + int[] position = new int[2]; + int[][] gameMap; + boolean allKeys = false; + int [] monsterPos = new int[2]; + + private GameState gameRunning; + private GameState chipsCollected; + private GameState gameWon; + private GameState currentState; + + public ChipModel(int xPos, int yPos, int[][] map, int k) { + x = xPos; + y = yPos; + this.keys = k; + gameMap = map; + + gameRunning = new GameRunning(this); + chipsCollected = new AllChips(this); + gameWon = new GameWon(this); + + currentState = gameRunning; + currentState.running(); + } + + public int[] getPosition() { + position[0] = this.x; + position[1] = this.y; + return(position); + } + + public int getKeys() { + return(this.keys); + } + + public void setPosition(int xPos, int yPos) { + if (gameMap[xPos][yPos] == 0) { + this.x = xPos; + this.y = yPos; + } + setChanged(); + notifyObservers(); + } + + public void addKey() { + this.keys--; + if (keys == 0) { + this.allKeys = true; + currentState.allChipsCollected(); + } + } + + public void attachView(ChipView view) { + addObserver(view); + } + + public boolean allKeysCollected() { + return(allKeys); + } + + public void setGameState(GameState newState){ + currentState = newState; + } + + public GameState getAllChipsState() { + return chipsCollected; + } + + public GameState getRunningState() { + return gameRunning; + } + + public GameState getGameWonState() { + return gameWon; + } + + public void levelWon() { + currentState.levelWon(); + } + + @Override + public void update(Observable o, Object arg) { + monsterPos = ((MonsterModel)o).getPosition(); + if ((monsterPos[0] == x) && (monsterPos[1] == y)) { + setPosition(0,0); + } + + + } + +} diff --git a/src/edu/nd/se2018/homework/hwk6/model/GameRunning.java b/src/edu/nd/se2018/homework/hwk6/model/GameRunning.java new file mode 100644 index 00000000..0f6a35e1 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk6/model/GameRunning.java @@ -0,0 +1,27 @@ +package edu.nd.se2018.homework.hwk6.model; + +public class GameRunning implements GameState { + private ChipModel chip; + + protected GameRunning(ChipModel chip) { + this.chip = chip; + } + + @Override + public void allChipsCollected() { + chip.setGameState(chip.getAllChipsState()); + } + + @Override + public void levelWon() { + // TODO Auto-generated method stub + + } + + @Override + public void running() { + // TODO Auto-generated method stub + + } + +} diff --git a/src/edu/nd/se2018/homework/hwk6/model/GameState.java b/src/edu/nd/se2018/homework/hwk6/model/GameState.java new file mode 100644 index 00000000..b9db5768 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk6/model/GameState.java @@ -0,0 +1,8 @@ +package edu.nd.se2018.homework.hwk6.model; + +public interface GameState { + public void allChipsCollected(); + public void levelWon(); + public void running(); + +} diff --git a/src/edu/nd/se2018/homework/hwk6/model/GameWon.java b/src/edu/nd/se2018/homework/hwk6/model/GameWon.java new file mode 100644 index 00000000..d3f0d2ab --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk6/model/GameWon.java @@ -0,0 +1,29 @@ +package edu.nd.se2018.homework.hwk6.model; + +public class GameWon implements GameState { + + private ChipModel chip; + + protected GameWon(ChipModel chip) { + this.chip = chip; + } + + @Override + public void allChipsCollected() { + // TODO Auto-generated method stub + + } + + @Override + public void levelWon() { + // TODO Auto-generated method stub + + } + + @Override + public void running() { + chip.setGameState(chip.getRunningState()); + + } + +} diff --git a/src/edu/nd/se2018/homework/hwk6/model/MonsterModel.java b/src/edu/nd/se2018/homework/hwk6/model/MonsterModel.java new file mode 100644 index 00000000..1ec90799 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk6/model/MonsterModel.java @@ -0,0 +1,38 @@ +package edu.nd.se2018.homework.hwk6.model; + +import java.util.Observable; + +import edu.nd.se2018.homework.hwk6.view.MonsterView; + +public class MonsterModel extends Observable { + + int[] position = new int[2]; + int[][] gameMap; + int x, y; + + + public MonsterModel(int xPos, int yPos) { + x = xPos; + y = yPos; + position[0] = x; + position[1] = y; + + } + + public void setPosition(int xPos, int yPos) { + position[0] = xPos; + position[1] = yPos; + setChanged(); + notifyObservers(); + + } + + public int[] getPosition() { + return(this.position); + } + + public void attachView(MonsterView view) { + addObserver(view); + } + +} diff --git a/src/edu/nd/se2018/homework/hwk6/view/ChipView.java b/src/edu/nd/se2018/homework/hwk6/view/ChipView.java new file mode 100644 index 00000000..5975960a --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk6/view/ChipView.java @@ -0,0 +1,41 @@ +package edu.nd.se2018.homework.hwk6.view; + +import java.util.Observable; +import java.util.Observer; + +import edu.nd.se2018.homework.hwk6.model.ChipModel; +import javafx.scene.Node; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; + +public class ChipView implements Observer { + public ImageView view; + private Image chipImage; + + + public ChipView(ChipModel chip) { + chipImage = new Image("/images/chip/textures/chipDown.png", 50, 50, true, true); + view = new ImageView(chipImage); + view.setFitHeight(20); + view.setFitWidth(20); + int[] pos = new int[2]; + pos = chip.getPosition(); + view.setX(pos[0]); + view.setY(pos[1]); + } + + public Node getView() { + return(view); + + } + + @Override + public void update(Observable o, Object arg) { + int[] pos = new int[2]; + pos = ((ChipModel)o).getPosition(); + view.setX(pos[0] * 20); + view.setY(pos[1] * 20); + + } + +} diff --git a/src/edu/nd/se2018/homework/hwk6/view/MapDisplay.java b/src/edu/nd/se2018/homework/hwk6/view/MapDisplay.java new file mode 100644 index 00000000..fdf0d66f --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk6/view/MapDisplay.java @@ -0,0 +1,149 @@ +package edu.nd.se2018.homework.hwk6.view; +import javafx.collections.ObservableList; +import javafx.scene.Node; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; + +import javafx.scene.paint.Color; +import javafx.scene.shape.Rectangle; +import java.util.Random; + + +public class MapDisplay { + public int[][] map = new int[25][25]; + final int dimensions = 25; + ImageView tileImageView, keyImageView, doorImageView; + Image tileImage, keyImage, doorImage; + public int level = 1; + ObservableList root; + int scale; + boolean newLevel = false; + + public void setBlocks( ) { + Random random = new Random(); + for (int i = 0; i < 25; i++) { + int x = random.ints(0, 24).findFirst().getAsInt(); + int y = random.ints(0, 24).findFirst().getAsInt(); + while (((x == 0) && (y == 0)) || ((x == 24) && (y == 10)) || (x == 20) || (y == 15)) { + x = random.ints(0, 24).findFirst().getAsInt(); + y = random.ints(0, 24).findFirst().getAsInt(); + } + this.map[x][y] = 1; + } + + this.map[24][10] = 4; + } + + public void setLevel(int l) { + level = l; + int chips = level*5; + Random random = new Random(); + for (int i = 0; i < chips; i++) { + int x = random.ints(0, 24).findFirst().getAsInt(); + int y = random.ints(0, 24).findFirst().getAsInt(); + while ((x == 0) && (y == 0) && (map[x][y] == 1) && (map[x][y] == 4)) { + x = random.ints(0, 24).findFirst().getAsInt(); + y = random.ints(0, 24).findFirst().getAsInt(); + } + this.map[x][y] = 2; + } + + + } + + public void drawMap(ObservableList r, int s) { + root = r; + scale = s; + for (int x = 0; x < dimensions; x++) { + for (int y = 0; y < dimensions; y++) { + Rectangle rect = new Rectangle(x*scale, y*scale, scale, scale); + rect.setStroke(Color.BLACK); + + tileImage = new Image("/images/chip/textures/BlankTile.png", 50, 50, true, true); + tileImageView = new ImageView(tileImage); + tileImageView.setX(x * scale); + tileImageView.setY(y * scale); + root.add(tileImageView); + + if (map[x][y] == 2) { + keyImage = new Image("/images/chip/textures/chipItem.png", 50, 50, true, true); + keyImageView = new ImageView(keyImage); + keyImageView.setFitHeight(20); + keyImageView.setFitWidth(20); + keyImageView.setX(x * scale); + keyImageView.setY(y * scale); + root.add(keyImageView); + + } + + if (map[x][y] == 4) { + doorImage = new Image("/images/chip/textures/blueKeyWall.png", 50, 50, true, true); + doorImageView = new ImageView(doorImage); + doorImageView.setFitHeight(20); + doorImageView.setFitWidth(20); + doorImageView.setX(x * scale); + doorImageView.setY(y * scale); + root.add(doorImageView); + } + + if (map[x][y] == 1) { + rect.setFill(Color.BROWN); + root.add(rect); + } + + + else if ((map[x][y] != 2) && (map[x][y] != 4)) { + this.map[x][y] = 0; + } + } + } + } + + public int[][] getMap() { + return(this.map); + } + + public void setMap(int x, int y, int value) { + this.map[x][y] = value; + } + + public void removeKey(int x, int y) { + //root.remove(keyImageView); + tileImage = new Image("/images/chip/textures/BlankTile.png", 50, 50, true, true); + tileImageView = new ImageView(tileImage); + tileImageView.setFitHeight(20); + tileImageView.setFitWidth(20); + tileImageView.setX(x * scale); + tileImageView.setY(y * scale); + root.add(tileImageView); + } + + public int getLevel() { + return(this.level); + } + + public void reset() { + this.level++; + root.clear(); + for (int i = 0; i < 25; i++) { + for (int j = 0; j < 25; j++) { + setMap(i, j, 0); + } + } + + setBlocks(); + setLevel(level); + drawMap(root, scale); + + newLevel = true; + } + + public boolean getStatus() { + return newLevel; + } + + public void resetStatus() { + newLevel = false; + } + +} diff --git a/src/edu/nd/se2018/homework/hwk6/view/MonsterView.java b/src/edu/nd/se2018/homework/hwk6/view/MonsterView.java new file mode 100644 index 00000000..74fa6961 --- /dev/null +++ b/src/edu/nd/se2018/homework/hwk6/view/MonsterView.java @@ -0,0 +1,40 @@ +package edu.nd.se2018.homework.hwk6.view; + +import java.util.Observable; +import java.util.Observer; + +import edu.nd.se2018.homework.hwk6.model.MonsterModel; +import javafx.scene.Node; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; + +public class MonsterView implements Observer { + public ImageView view; + private Image monsterImage; + + public MonsterView(MonsterModel monster) { + monsterImage = new Image("/images/chip/textures/bugUp.png", 50, 50, true, true); + view = new ImageView(monsterImage); + view.setFitHeight(20); + view.setFitWidth(20); + int[] pos = new int[2]; + pos = monster.getPosition(); + view.setX(pos[0] * 20); + view.setY(pos[1] * 20); + } + + public Node getView() { + return(view); + + } + + @Override + public void update(Observable o, Object arg) { + int[] pos = new int[2]; + pos = ((MonsterModel)o).getPosition(); + view.setX(pos[0] * 20); + view.setY(pos[1] * 20); + + } + +} diff --git a/src/images/chip/textures/BlankTile.png b/src/images/chip/textures/BlankTile.png new file mode 100644 index 00000000..c594f20d Binary files /dev/null and b/src/images/chip/textures/BlankTile.png differ diff --git a/src/images/chip/textures/blueKey.png b/src/images/chip/textures/blueKey.png new file mode 100644 index 00000000..2c6b249b Binary files /dev/null and b/src/images/chip/textures/blueKey.png differ diff --git a/src/images/chip/textures/blueKeyWall.png b/src/images/chip/textures/blueKeyWall.png new file mode 100644 index 00000000..70480b9c Binary files /dev/null and b/src/images/chip/textures/blueKeyWall.png differ diff --git a/src/images/chip/textures/bugUp.png b/src/images/chip/textures/bugUp.png new file mode 100644 index 00000000..cfd8bb06 Binary files /dev/null and b/src/images/chip/textures/bugUp.png differ diff --git a/src/images/chip/textures/chipDown.png b/src/images/chip/textures/chipDown.png new file mode 100644 index 00000000..1d06deb1 Binary files /dev/null and b/src/images/chip/textures/chipDown.png differ diff --git a/src/images/chip/textures/chipItem.png b/src/images/chip/textures/chipItem.png new file mode 100644 index 00000000..bc087bee Binary files /dev/null and b/src/images/chip/textures/chipItem.png differ diff --git a/src/images/chip/textures/chipLeft.png b/src/images/chip/textures/chipLeft.png new file mode 100644 index 00000000..243a4400 Binary files /dev/null and b/src/images/chip/textures/chipLeft.png differ diff --git a/src/images/chip/textures/chipRight.png b/src/images/chip/textures/chipRight.png new file mode 100644 index 00000000..ec669d27 Binary files /dev/null and b/src/images/chip/textures/chipRight.png differ diff --git a/src/images/chip/textures/chipUp.png b/src/images/chip/textures/chipUp.png new file mode 100644 index 00000000..fdfb383c Binary files /dev/null and b/src/images/chip/textures/chipUp.png differ diff --git a/src/images/chip/textures/greenKey.png b/src/images/chip/textures/greenKey.png new file mode 100644 index 00000000..c6b4dfe4 Binary files /dev/null and b/src/images/chip/textures/greenKey.png differ diff --git a/src/images/chip/textures/greenKeyWall.png b/src/images/chip/textures/greenKeyWall.png new file mode 100644 index 00000000..6c9660b8 Binary files /dev/null and b/src/images/chip/textures/greenKeyWall.png differ diff --git a/src/images/chip/textures/portal.png b/src/images/chip/textures/portal.png new file mode 100644 index 00000000..600ff4c6 Binary files /dev/null and b/src/images/chip/textures/portal.png differ diff --git a/src/images/chip/textures/redKey.png b/src/images/chip/textures/redKey.png new file mode 100644 index 00000000..3bb88b4b Binary files /dev/null and b/src/images/chip/textures/redKey.png differ diff --git a/src/images/chip/textures/redKeyWall.png b/src/images/chip/textures/redKeyWall.png new file mode 100644 index 00000000..8ac73e32 Binary files /dev/null and b/src/images/chip/textures/redKeyWall.png differ diff --git a/src/images/chip/textures/tiles.png b/src/images/chip/textures/tiles.png new file mode 100644 index 00000000..e633013a Binary files /dev/null and b/src/images/chip/textures/tiles.png differ diff --git a/src/images/chip/textures/yellowKey.png b/src/images/chip/textures/yellowKey.png new file mode 100644 index 00000000..b537de26 Binary files /dev/null and b/src/images/chip/textures/yellowKey.png differ diff --git a/src/images/chip/textures/yellowKeyWall.png b/src/images/chip/textures/yellowKeyWall.png new file mode 100644 index 00000000..d6a5ea1a Binary files /dev/null and b/src/images/chip/textures/yellowKeyWall.png differ