diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/.classpath b/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/.classpath
new file mode 100644
index 0000000..bb83344
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/.classpath
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/.project b/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/.project
new file mode 100644
index 0000000..cd00a7c
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/.project
@@ -0,0 +1,17 @@
+
+
+ Assn10_Mazes
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/.settings/org.eclipse.core.resources.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/.settings/org.eclipse.jdt.core.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..e71285a
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=11
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=11
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/src/Collections.java b/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/src/Collections.java
new file mode 100644
index 0000000..32b2b20
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/src/Collections.java
@@ -0,0 +1,126 @@
+import java.util.Deque;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+
+// Represents a mutable collection of items
+interface ICollection {
+ // Is this collection empty?
+ boolean isEmpty();
+ // EFFECT: adds the item to the collection
+ void add(T item);
+ // Returns the first item of the collection
+ // EFFECT: removes that first item
+ T remove();
+}
+
+// first in first out
+class Stack implements ICollection {
+ Deque contents;
+ Stack() {
+ this.contents = new ArrayDeque();
+ }
+ public boolean isEmpty() {
+ return this.contents.isEmpty();
+ }
+ public T remove() {
+ return this.contents.removeLast();
+ }
+ public void add(T item) {
+ this.contents.addFirst(item);
+ }
+}
+
+// last in last out
+class Queue implements ICollection {
+ Deque contents;
+ Queue() {
+ this.contents = new ArrayDeque();
+ }
+ public boolean isEmpty() {
+ return this.contents.isEmpty();
+ }
+ public T remove() {
+ return this.contents.removeLast();
+ }
+ public void add(T item) {
+ this.contents.addLast(item); // NOTE: Different from Stack!
+ }
+}
+
+// highest priority out
+class PriorityQueue implements ICollection {
+ ArrayList heap;
+ IComparator comp;
+ PriorityQueue(ArrayList inputList, IComparator comp) {
+ this.comp = comp;
+ buildHeap(inputList);
+ }
+ PriorityQueue(IComparator comp) {
+ this(new ArrayList(), comp);
+ }
+ void buildHeap(ArrayList inputList) {
+ this.heap = inputList;
+ for (int i = inputList.size() - 1; i >= 0; i--) {
+ this.downHeap(i);
+ }
+ }
+ // swaps the parent and child items
+ void swap(int parentIndex, int childIndex) {
+ T temp = heap.get(parentIndex);
+ heap.set(parentIndex, heap.get(childIndex));
+ heap.set(childIndex, temp);
+ }
+ // recursively uses comp to compare child with parent
+ // and swaps if child is higher priority
+ void upHeap(int childIndex) {
+ int parentIndex = (childIndex - 1) / 2;
+ // comp will return >0 if left has higher priority than right
+ // ergo swap when comp returns <0
+ if (comp.compare(heap.get(parentIndex), heap.get(childIndex)) < 0) {
+ this.swap(parentIndex, childIndex);
+ this.upHeap(parentIndex);
+ }
+ }
+ // recursively uses comp to compare parent with children
+ // and swaps if child is higher priority
+ void downHeap(int parentIndex) {
+ this.downHeapMaxDepth(parentIndex, this.heap.size());
+ }
+ void downHeapMaxDepth(int parentIndex, int maxDepthIndex) {
+ int leftChildIndex = 2 * parentIndex + 1;
+ int rightChildIndex = 2 * parentIndex + 2;
+ if (rightChildIndex < maxDepthIndex) {
+ if (comp.compare(heap.get(leftChildIndex), heap.get(rightChildIndex)) > 0) {
+ if (comp.compare(heap.get(parentIndex), heap.get(leftChildIndex)) < 0) {
+ this.swap(parentIndex, leftChildIndex);
+ this.downHeapMaxDepth(leftChildIndex, maxDepthIndex);
+ }
+ } else if (comp.compare(heap.get(parentIndex), heap.get(rightChildIndex)) < 0) {
+ this.swap(parentIndex, rightChildIndex);
+ this.downHeapMaxDepth(rightChildIndex, maxDepthIndex);
+ }
+ } else if (leftChildIndex < maxDepthIndex) {
+ if (comp.compare(heap.get(parentIndex), heap.get(leftChildIndex)) < 0) {
+ this.swap(parentIndex, leftChildIndex);
+ this.downHeapMaxDepth(leftChildIndex, maxDepthIndex);
+ }
+ }
+ }
+
+ // Interface methods
+ public boolean isEmpty() {
+ return this.heap.isEmpty();
+ }
+ public void add(T item) {
+ this.heap.add(item);
+ this.upHeap(heap.size() - 1);
+ }
+ public T remove() {
+ int lastIndex = this.heap.size() - 1;
+ this.swap(0, lastIndex);
+ T response = this.heap.remove(lastIndex);
+ this.downHeap(0);
+ return response;
+ }
+
+}
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/src/Comparator.java b/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/src/Comparator.java
new file mode 100644
index 0000000..9a6d990
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/src/Comparator.java
@@ -0,0 +1,44 @@
+interface IPred {
+ boolean apply(T t);
+}
+
+interface IFunc {
+ R apply(A arg);
+}
+
+interface IFunc2 {
+ R apply(A1 arg1, A2 arg2);
+}
+
+interface IComparator {
+ // Returns a negative number if t1 priority is less than t2 priority==-
+ int compare(T t1, T t2);
+}
+
+class ParentLargerInteger implements IComparator {
+ // returns true (>0) if left has higher priority (larger int)
+ public int compare(Integer left, Integer right) {
+ return left - right;
+ }
+}
+
+class ParentSmallerInteger implements IComparator {
+ // returns true (>0) if left has a higher priority (smaller int)
+ public int compare(Integer left, Integer right) {
+ return right - left;
+ }
+}
+
+class ParentLargerEdge implements IComparator {
+ // returns true (>0) if left edge has a higher priority (lower weight)
+ public int compare(Hall left, Hall right) {
+ return left.weight - right.weight;
+ }
+}
+
+class ParentSmallerEdge implements IComparator {
+ // returns true (>0) if left edge has a higher priority (higher weight)
+ public int compare(Hall left, Hall right) {
+ return right.weight - left.weight;
+ }
+}
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/src/Maze.java b/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/src/Maze.java
new file mode 100644
index 0000000..6a4d802
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/src/Maze.java
@@ -0,0 +1,213 @@
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Deque;
+import java.util.HashMap;
+import javalib.impworld.*;
+import java.awt.Color;
+import javalib.worldimages.*;
+import java.util.Random;
+
+class Room {
+ String name; // names are needed for Kruskal's algo
+ ArrayList neighborConnections;
+ ArrayList openHalls;
+ int row, col;
+ Room(String name, ArrayList neighbors, ArrayList openHalls, int row, int col) {
+ this.name = name;
+ this.neighborConnections = neighbors;
+ this.openHalls = openHalls;
+ this.row = row;
+ this.col = col;
+ }
+ Room(String name, int row, int col) {
+ this(name, new ArrayList(), new ArrayList(), row, col);
+ }
+ Room(int row, int col) {
+ this(Integer.toString(row) + Integer.toString(col), new ArrayList(),
+ new ArrayList(), row, col);
+ }
+ void addNeighbor(Hall e) {
+ this.neighborConnections.add(e);
+ }
+ void addOpenHall(Hall e) {
+ this.openHalls.add(e);
+ }
+
+ void drawRoom(WorldScene scene, Color color) {
+ scene.placeImageXY(
+ new RectangleImage(
+ MazeWorld.ROOM_SIZE_PX,
+ MazeWorld.ROOM_SIZE_PX,
+ OutlineMode.SOLID,
+ color),
+ col * (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX)
+ + (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX) / 2,
+ row * (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX)
+ + (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX) / 2);
+ }
+}
+
+class Hall {
+ String name; // names are needed for Kruskal's algo
+ Room from, to;
+ int weight; // random weights are used to facilitate maze gen
+ Hall(String name, Room from, Room to, int weight) {
+ this.name = name;
+ this.from = from;
+ this.to = to;
+ this.weight = weight;
+ from.addNeighbor(this);
+ to.addNeighbor(this);
+ }
+ Hall(Room from, Room to, int weight) {
+ this(from.name + to.name, from, to, weight);
+ }
+
+ void drawHall(WorldScene scene) {
+ scene.placeImageXY(
+ new RectangleImage(
+ MazeWorld.ROOM_SIZE_PX - 1,
+ MazeWorld.ROOM_SIZE_PX - 1,
+ OutlineMode.SOLID,
+ MazeWorld.ROOM_COLOR),
+ (from.col + to.col) * (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX) / 2
+ + (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX) / 2,
+ (from.row + to.row) * (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX) / 2
+ + (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX) / 2);
+ }
+}
+
+class Maze {
+ int width, height; // number of vertices across and down
+ Random rand;
+
+ ArrayList rooms;
+ ArrayList routeTree;
+ ArrayList searchTree;
+
+ Maze(int width, int height, Random rand) {
+ this.width = width;
+ this.height = height;
+ this.rand = rand;
+ genVertsAndEdges();
+ genRouteTree();
+ }
+ Maze(int size) {
+ this(size, size, new Random());
+ }
+ Maze(int width, int height) {
+ this(width, height, new Random());
+ }
+ Maze(int width, int height, int seed) {
+ this(width, height, new Random(seed));
+ }
+ void genVertsAndEdges() {
+ this.rooms = new ArrayList();
+ // generate all the vertices
+ for (int i = 0; i < width * height; i++) {
+ Room v = new Room(Integer.toString(i), i / width, i % width);
+ // connect to vertex to the left (right comes for free with next vertex)
+ if (i % width != 0) {
+ new Hall(this.rooms.get(i - 1), v, rand.nextInt(10));
+ }
+ // connect to vertex above (below comes for free)
+ if (i >= width) {
+ new Hall(this.rooms.get(i - width), v, rand.nextInt(10));
+ }
+ this.rooms.add(v);
+ }
+ }
+ //Kruskal's Tree Algo
+ void genRouteTree() {
+ this.routeTree = new ArrayList();
+
+ HashMap setMap = new HashMap();
+ PriorityQueue worklist = new PriorityQueue(new ParentSmallerEdge());
+
+ for (Room v : this.rooms) {
+ // initialize every node's representative to itself
+ setMap.put(v.name, v.name);
+ for (Hall e : v.neighborConnections) {
+ // all edges in graph, sorted by edge weights
+ worklist.add(e);
+ }
+ }
+ Util u = new Util();
+ while (!u.isOneTree(this.rooms, setMap)) {
+ Hall lowestCostEdge = worklist.remove();
+ if (u.sameTree(lowestCostEdge.from.name, lowestCostEdge.to.name, setMap)) {
+ // discard this edge
+ // they're already connected
+ } else {
+ routeTree.add(lowestCostEdge);
+ u.union(setMap, lowestCostEdge.to.name, lowestCostEdge.from.name);
+ }
+ }
+ for (Hall h : this.routeTree) {
+ h.from.addOpenHall(h);
+ h.to.addOpenHall(h);
+ }
+ }
+ void breadthFirstSearch() {
+ this.searchTree = findPath(
+ this.rooms.get(0),
+ this.rooms.get(rooms.size() - 1),
+ new Queue());
+ }
+ void depthFirstSearch() {
+ this.searchTree = findPath(
+ this.rooms.get(0),
+ this.rooms.get(rooms.size() - 1),
+ new Stack());
+ }
+ ArrayList findPath(Room from, Room to, ICollection worklist) {
+ ArrayList alreadySeen = new ArrayList();
+
+ // Initialize the worklist with the from vertex
+ worklist.add(from);
+ // As long as the worklist isn't empty...
+ while (!worklist.isEmpty()) {
+ Room next = worklist.remove();
+ if (next.equals(to)) {
+ return alreadySeen; // Success!
+ } else if (alreadySeen.contains(next)) {
+ // do nothing: we've already seen this one
+ } else {
+ // add all the neighbors of next to the worklist for further processing
+ for (Hall h : next.neighborConnections) {
+ worklist.add(h.to);
+ }
+ // add next to alreadySeen, since we're done with it
+ alreadySeen.add(next);
+ }
+ }
+ // We haven't found the to vertex, and there are no more to try
+ throw new RuntimeException("Could not find a valid path");
+ }
+
+ void drawMaze(WorldScene scene) {
+ scene.placeImageXY(
+ new RectangleImage(
+ width * (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX),
+ height * (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX),
+ OutlineMode.SOLID,
+ MazeWorld.WALL_COLOR),
+ width * (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX) / 2,
+ height * (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX) / 2);
+ // draw each room slightly small
+ Color roomColor = MazeWorld.ROOM_COLOR;
+ for (Room r : this.rooms) {
+ r.drawRoom(scene, roomColor);
+ }
+ for (Hall h : this.routeTree) {
+ h.drawHall(scene);
+ }
+ }
+ void drawSearchTree(WorldScene scene, int tickCount) {
+ Color searchColor = MazeWorld.SEARCH_COLOR;
+ for (int i = 0; i <= tickCount && i < this.searchTree.size(); i++) {
+ this.searchTree.get(i).drawRoom(scene, searchColor);
+ }
+ }
+
+}
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/src/MazeExample.java b/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/src/MazeExample.java
new file mode 100644
index 0000000..845683e
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/src/MazeExample.java
@@ -0,0 +1,100 @@
+import tester.Tester;
+import java.util.Random;
+
+class Examples {
+ Random r314 = new Random(314);
+ Room v0, v1;
+ Hall e01;
+ Maze m3;
+ MazeWorld worldM3;
+ MazeWorld worldM16;
+
+ void testConstructors(Tester t) {
+ // test Vertex Constructor
+ v0 = new Room(0, 0);
+ t.checkExpect(v0.neighborConnections.size(), 0);
+ v1 = new Room(0, 1);
+ // test edge constructor incl adding edges to vertices
+ e01 = new Hall(v0, v1, r314.nextInt(10));
+ t.checkExpect(v0.neighborConnections.size(), 1);
+ t.checkExpect(v1.neighborConnections.size(), 1);
+ t.checkExpect(v0.neighborConnections.get(0), e01);
+ t.checkExpect(v1.neighborConnections.get(0), e01);
+ // test Maze constructor
+ m3 = new Maze(3, 3, 314);
+ // check all vertices were created
+ t.checkExpect(m3.rooms.size(), 9);
+ // check rooms were placed in correct location
+ t.checkExpect(m3.rooms.get(0).row, 0);
+ t.checkExpect(m3.rooms.get(0).col, 0);
+ t.checkExpect(m3.rooms.get(1).row, 0);
+ t.checkExpect(m3.rooms.get(1).col, 1);
+ t.checkExpect(m3.rooms.get(2).row, 0);
+ t.checkExpect(m3.rooms.get(2).col, 2);
+ t.checkExpect(m3.rooms.get(3).row, 1);
+ t.checkExpect(m3.rooms.get(3).col, 0);
+ t.checkExpect(m3.rooms.get(4).row, 1);
+ t.checkExpect(m3.rooms.get(4).col, 1);
+ t.checkExpect(m3.rooms.get(5).row, 1);
+ t.checkExpect(m3.rooms.get(5).col, 2);
+ t.checkExpect(m3.rooms.get(6).row, 2);
+ t.checkExpect(m3.rooms.get(6).col, 0);
+ t.checkExpect(m3.rooms.get(7).row, 2);
+ t.checkExpect(m3.rooms.get(7).col, 1);
+ t.checkExpect(m3.rooms.get(8).row, 2);
+ t.checkExpect(m3.rooms.get(8).col, 2);
+ // check correct number of edges were created
+ t.checkExpect(m3.rooms.get(0).neighborConnections.size(), 2);
+ t.checkExpect(m3.rooms.get(1).neighborConnections.size(), 3);
+ t.checkExpect(m3.rooms.get(2).neighborConnections.size(), 2);
+ t.checkExpect(m3.rooms.get(3).neighborConnections.size(), 3);
+ t.checkExpect(m3.rooms.get(4).neighborConnections.size(), 4);
+ t.checkExpect(m3.rooms.get(5).neighborConnections.size(), 3);
+ t.checkExpect(m3.rooms.get(6).neighborConnections.size(), 2);
+ t.checkExpect(m3.rooms.get(7).neighborConnections.size(), 3);
+ t.checkExpect(m3.rooms.get(8).neighborConnections.size(), 2);
+ // check that edges connect the correct vertices
+ t.checkExpect(m3.rooms.get(0).neighborConnections.get(0).to,
+ m3.rooms.get(1));
+ t.checkExpect(m3.rooms.get(0).neighborConnections.get(1).to,
+ m3.rooms.get(3));
+ t.checkExpect(m3.rooms.get(4).neighborConnections.get(0).from,
+ m3.rooms.get(3));
+ t.checkExpect(m3.rooms.get(4).neighborConnections.get(1).from,
+ m3.rooms.get(1));
+ t.checkExpect(m3.rooms.get(4).neighborConnections.get(2).to,
+ m3.rooms.get(5));
+ t.checkExpect(m3.rooms.get(4).neighborConnections.get(3).to,
+ m3.rooms.get(7));
+ t.checkExpect(m3.rooms.get(8).neighborConnections.get(0).from,
+ m3.rooms.get(7));
+ t.checkExpect(m3.rooms.get(8).neighborConnections.get(1).from,
+ m3.rooms.get(5));
+ // check that route tree was created
+ t.checkExpect(m3.routeTree.size(), 8);
+ t.checkExpect(m3.rooms.get(0).openHalls.get(0).to,
+ m3.rooms.get(1));
+ t.checkExpect(m3.rooms.get(1).openHalls.get(0).from,
+ m3.rooms.get(0));
+ t.checkExpect(m3.rooms.get(1).openHalls.get(1).to,
+ m3.rooms.get(4));
+ t.checkExpect(m3.rooms.get(1).openHalls.get(2).to,
+ m3.rooms.get(2));
+ t.checkExpect(m3.rooms.get(4).openHalls.get(0).from,
+ m3.rooms.get(3));
+ t.checkExpect(m3.rooms.get(4).openHalls.get(1).from,
+ m3.rooms.get(1));
+
+ }
+
+ void init() {
+ m3 = new Maze(3, 3, 314);
+ worldM3 = new MazeWorld(m3);
+ worldM16 = new MazeWorld(new Maze(16, 16, 314));
+ }
+ void testDrawMaze(Tester t) {
+ init();
+ worldM3.start();
+ // worldM16.start();
+ }
+}
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/src/MazeWorld.java b/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/src/MazeWorld.java
new file mode 100644
index 0000000..1b9045a
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/src/MazeWorld.java
@@ -0,0 +1,65 @@
+import java.awt.Color;
+import javalib.impworld.World;
+import javalib.impworld.WorldScene;
+
+class MazeWorld extends World {
+ // Constants
+ double TICKRATE = 1.0 / 2;
+ static int ROOM_SIZE_PX = 64;
+ static int WALL_SIZE_PX = 1;
+ static Color ROOM_COLOR = Color.GRAY;
+ static Color WALL_COLOR = Color.BLACK;
+ static Color SEARCH_COLOR = Color.blue;
+
+ //Variables
+ Maze maze;
+ int tickCount;
+
+ MazeWorld(Maze maze) {
+ this.maze = maze;
+ this.tickCount = -1;
+ }
+ MazeWorld(int size) {
+ this(new Maze(size));
+ }
+ MazeWorld(int cols, int rows) {
+ this(new Maze(cols, rows));
+ }
+ void reset() {
+ // reset maze to new random start
+ }
+
+ void start() {
+ this.bigBang(
+ (WALL_SIZE_PX + ROOM_SIZE_PX) * maze.width,
+ (WALL_SIZE_PX + ROOM_SIZE_PX) * maze.height);
+ }
+ public WorldScene makeScene() {
+ WorldScene scene = new WorldScene(
+ (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX) * this.maze.width,
+ (MazeWorld.ROOM_SIZE_PX + MazeWorld.WALL_SIZE_PX) * this.maze.height);
+ this.maze.drawMaze(scene);
+ if (this.tickCount >= 0) {
+ this.maze.drawSearchTree(scene, this.tickCount);
+ }
+ return scene;
+ }
+ public void onKeyEvent(String k) {
+ switch (k) {
+ case "r":
+ this.tickCount = -1;
+ reset();
+ case "b":
+ this.tickCount = 0;
+ this.maze.breadthFirstSearch();
+ case "d":
+ this.tickCount = 0;
+ this.maze.depthFirstSearch();
+ default:
+ break;
+ }
+ }
+ public void onTick() {
+ this.tickCount++;
+ }
+}
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/src/Util.java b/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/src/Util.java
new file mode 100644
index 0000000..956336f
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Assn10_Mazes/src/Util.java
@@ -0,0 +1,53 @@
+import java.util.ArrayList;
+import java.util.HashMap;
+
+class Util {
+ Util() {}
+
+ boolean isOneTree(ArrayList vertices, HashMap setMap) {
+ // this seems wildly inefficient but it works
+ for (Room v0 : vertices) {
+ for (Room v1 : vertices) {
+ if (!this.sameTree(v0.name, v1.name, setMap)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ boolean sameTree(String k1, String k2, HashMap setMap) {
+ return this.getStump(k1, setMap).equals(this.getStump(k2, setMap));
+ // if (setMap.get(k1).equals(setMap.get(k2))) {
+ // // easy answer
+ // return true;
+ // } else if (setMap.get(k1).equals(k1) &&
+ // setMap.get(k2).equals(k2)) {
+ // // if both nodes are part of their own sets they cannot be part
+ // // of the same set
+ // return false;
+ // } else {
+ // // run up the tree to see if it ends in the same tree
+ // // i can climb both sides here because when we get to a stump
+ // // the self reference will by definition create a loop that will
+ // // be broken by conditional above
+ // return sameTree(setMap.get(k1), setMap.get(k2), setMap);
+ // }
+ }
+ String getStump(String nodeName, HashMap setMap) {
+ String nodeSet = setMap.get(nodeName);
+ if (nodeName.equals(nodeSet)) {
+ return nodeSet;
+ } else {
+ return getStump(nodeSet, setMap);
+ }
+ }
+ void union(HashMap setMap, String k1, String k2) {
+ if (setMap.get(k2).equals(k2)) {
+ // if k2 is stump of tree change to k1
+ setMap.put(k2, this.getStump(k1, setMap));
+ } else {
+ // go up the tree to change stump's set to k1
+ this.union(setMap, k1, setMap.get(k2));
+ }
+ }
+}
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect33_ObjImplementation/Objects.rkt b/completedwork/core_programming/02_classbased_design/Workspace/Lect33_ObjImplementation/Objects.rkt
new file mode 100644
index 0000000..a0d2966
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect33_ObjImplementation/Objects.rkt
@@ -0,0 +1,60 @@
+;; The first three lines of this file were inserted by DrRacket. They record metadata
+;; about the language level of this file in a form that our tools can easily process.
+#reader(lib "htdp-advanced-reader.ss" "lang")((modname Objects) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #t #t none #f () #f)))
+;; An Object is [Itself Name Params -> Value]
+;; A Name is a symbol
+;; Params is [Listof Value]
+;; Itself is the object on which the method is being invoked
+
+(define object
+ (λ(this prop args)
+ (error prop "No such property found")))
+(define (make-pos x y)
+ (local [(define super object)]
+ (λ(this prop args)
+ (cond
+ [(symbol=? prop 'x) x]
+ [(symbol=? prop 'y) y]
+ [(symbol=? prop 'dist-to-0)
+ (sqrt (+ (sqr x) (sqr y)))]
+ [(symbol=? prop 'closer-than)
+ (local [(define that (first args))]
+ (< (dot this 'dist-to-0 '()) (dot that 'dist-to-0 '())))]
+ ;; NEW:
+ [else (super this prop args)]))))
+(define (make-3d-pos x y z)
+ (local [(define super (make-pos x y))]
+ (λ(this prop args)
+ (cond
+ [(symbol=? prop 'z) z]
+ [(symbol=? prop 'dist-to-0)
+ (sqrt (+ (sqr x) (sqr y) (sqr z)))]
+ ;; NEW:
+ [else (super this prop args)]))))
+(define (dot obj prop args)
+ ;; Passes the object to itself
+ (obj obj prop args))
+
+(define my-pos1 (make-pos 3 4))
+(define my-pos2 (make-pos 6 8))
+(define my-pos3 (make-3d-pos 3 4 12))
+
+(check-expect (dot my-pos1 'x '-) 3)
+(check-expect (dot my-pos2 'y '-) 8)
+(check-error (dot my-pos2 'z '-) "z: No such property found")
+
+(check-expect (dot my-pos3 'z '-) 12)
+(check-error (dot my-pos3 'w '-) "w: No such property found")
+
+(check-expect (dot my-pos1 'dist-to-0 '-) 5)
+(check-expect (dot my-pos2 'dist-to-0 '-) 10)
+(check-expect (dot my-pos3 'dist-to-0 '-) 13)
+
+;; Test 1: (3,4) is closer to the origin than (6,8)
+(check-expect (dot my-pos1 'closer-than (list my-pos2)) true)
+;; Test 2: (6,8) is not closer to the origin than (3,4)
+(check-expect (dot my-pos2 'closer-than (list my-pos1)) false)
+;; Test 3: (6,8) is closer to the origin than (3,4,12)
+(check-expect (dot my-pos2 'closer-than (list my-pos3)) true)
+;; Test 4: (3,4,12) is not closer to the origin than (6,8)
+(check-expect (dot my-pos3 'closer-than (list my-pos2)) false)
\ No newline at end of file
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect34_DynamicProg/.classpath b/completedwork/core_programming/02_classbased_design/Workspace/Lect34_DynamicProg/.classpath
new file mode 100644
index 0000000..8e3d409
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect34_DynamicProg/.classpath
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect34_DynamicProg/.project b/completedwork/core_programming/02_classbased_design/Workspace/Lect34_DynamicProg/.project
new file mode 100644
index 0000000..4fe4615
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect34_DynamicProg/.project
@@ -0,0 +1,17 @@
+
+
+ Lect34_DynamicProg
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect34_DynamicProg/.settings/org.eclipse.core.resources.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lect34_DynamicProg/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect34_DynamicProg/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect34_DynamicProg/.settings/org.eclipse.jdt.core.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lect34_DynamicProg/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..e71285a
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect34_DynamicProg/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=11
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=11
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect34_DynamicProg/src/Fibonacci.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect34_DynamicProg/src/Fibonacci.java
new file mode 100644
index 0000000..12e9878
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect34_DynamicProg/src/Fibonacci.java
@@ -0,0 +1,78 @@
+import tester.Tester;
+import java.util.ArrayList;
+
+class Fibonacci {
+ int fib(int n, String type) {
+ switch (type) {
+ case "recursive":
+ return fib_recursive(n);
+ case "memo":
+ return fib_memo(n);
+ case "loop":
+ return fib_loop(n);
+ default:
+ return 0;
+ }
+ }
+ int fib_recursive(int n) {
+ if (n == 0) {
+ return 1;
+ } else if (n == 1) {
+ return 1;
+ } else {
+ return fib_recursive(n - 1) + fib_recursive(n - 2);
+ }
+ }
+ int fib_memo(int n) {
+ ArrayList answers = new ArrayList();
+ answers.add(1); // Base cases: fib(0) = 1
+ answers.add(1); // fib(1) = 1
+ fibAcc(n, answers);
+ return answers.get(n);
+ }
+ int fibAcc(int n, ArrayList answers) {
+ // Check for redundant computation
+ if (answers.size() > n) {
+ return answers.get(n);
+ }
+ // Compute the new things:
+ if (n == 0) {
+ return 1;
+ } else if (n == 1) {
+ return 1;
+ } else {
+ int ans = fibAcc(n - 1, answers) + fibAcc(n - 2, answers);
+ answers.add(ans);
+ return ans;
+ }
+ }
+ int fib_loop(int n) {
+ if (n == 0) {
+ return 1;
+ } else if (n == 1) {
+ return 1;
+ } else {
+ int prev = 1;
+ int cur = 2;
+ for (int i = 2; i < n; i += 1) {
+ int next = prev + cur;
+ prev = cur;
+ cur = next;
+ }
+ return cur;
+ }
+ }
+}
+
+class FibExamples {
+ Fibonacci f = new Fibonacci();
+ void testFib(Tester t) {
+ // 1 1 2 3 5 8 13 21 34
+ t.checkExpect(f.fib(5, "recursive"), 8);
+ t.checkExpect(f.fib(8, "recursive"), 34);
+ t.checkExpect(f.fib(5, "memo"), 8);
+ t.checkExpect(f.fib(8, "memo"), 34);
+ t.checkExpect(f.fib(5, "loop"), 8);
+ t.checkExpect(f.fib(8, "loop"), 34);
+ }
+}
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect34_DynamicProg/src/Shoppers.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect34_DynamicProg/src/Shoppers.java
new file mode 100644
index 0000000..27cfedd
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect34_DynamicProg/src/Shoppers.java
@@ -0,0 +1,91 @@
+//import tester.Tester;
+//import java.util.ArrayList;
+//import java.util.Arrays;
+//
+//class Shoppers {
+// int bestScoreRecursive(ArrayList scores, ArrayList costs,
+// int curItemIndex, int remainingBudget) {
+// // Base case: no more items
+// if (curItemIndex >= scores.size()) {
+// return 0;
+// } else {
+// // Recursive case: take the better of...
+// return Math.max(
+// // this item
+// scores.get(curItemIndex) +
+// // score of the best item(s) below with remaining budget
+// bestScoreRecursive(scores, costs,
+// curItemIndex + 1,
+// remainingBudget - costs.get(curItemIndex)),
+// // or best item(s) below
+// bestScoreRecursive(scores, costs, curItemIndex + 1, remainingBudget));
+// }
+// }
+// int bestScoreMemo(ArrayList scores, ArrayList costs, int budget) {
+// ArrayList> memos = new ArrayList>();
+// // It's a bit easier to pre-fill the array with placeholders,
+// // than to try to dynamicalaly fill it during the algorithm itself.
+// for (int idx = 0; idx < scores.size(); idx += 1) {
+// ArrayList vals = new ArrayList();
+// for (int b = 0; b < budget; b += 1) {
+// vals.add(Integer.MAX_VALUE); // Placeholder value to mark invalid answers
+// }
+// memos.add(vals);
+// }
+// bestScoreMemoHelp(memos, scores, costs, 0, budget);
+// return memos.get(0).get(budget);
+// }
+// int bestScoreMemoHelp(ArrayList> memos,
+// ArrayList scores, ArrayList costs,
+// int curItemIndex, int remainingBudget) {
+// // Lookup memoized answer:
+// if (memos.get(curItemIndex).get(remainingBudget) != Integer.MAX_VALUE) {
+// return memos.get(curItemIndex).get(remainingBudget);
+// }
+// // Base case: no more items
+// if (curItemIndex >= scores.size()) {
+// return 0;
+// } else {
+// // Recursive case: take the better of...
+// int ans = Math.max(
+// // Try buying this item
+// scores.get(curItemIndex) + bestScoreRecursive(memos, scores, costs,
+// curItemIndex + 1,
+// remainingBudget - costs.get(curItemIndex)),
+// // Skip buying this item
+// bestScoreRecursive(memos, scores, costs, curItemIndex + 1, remainingBudget));
+// memos.get(curItemIndex).set(remainingBudget, ans);
+// return ans;
+// }
+// }
+//}
+//
+//class Examples {
+// Shoppers s;
+// ArrayList scores0;
+// ArrayList costs0;
+//
+// void init() {
+// s = new Shoppers();
+// scores0 = new ArrayList(Arrays.asList(
+// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
+// costs0 = new ArrayList(Arrays.asList(
+// 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0));
+// // 10 0 10 10
+// // 9 1 19 9
+// // 8 2 27 7
+// // 7 3 34 4
+// // 6 4 40 0
+// // 5 5
+// // 4 6
+// // 3 7
+// // 2 8
+// // 1 9
+// // 0 10
+// }
+// void testBestScore(Tester t) {
+// init();
+// t.checkExpect(s.bestScoreRecursive(scores0, costs0, 0, 10), 40);
+// t.checkExpect(s.bestScoreMemo(scores0, costs0, 10), 40);
+// }
+//}