diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab05/.classpath b/completedwork/core_programming/02_classbased_design/Workspace/Lab05/.classpath new file mode 100644 index 0000000..e446dbd --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab05/.classpath @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab05/.project b/completedwork/core_programming/02_classbased_design/Workspace/Lab05/.project new file mode 100644 index 0000000..7b26ae4 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab05/.project @@ -0,0 +1,17 @@ + + + Lab05 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab05/.settings/org.eclipse.core.resources.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lab05/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab05/.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/Lab05/.settings/org.eclipse.jdt.core.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lab05/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..e71285a --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab05/.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/Lab05/src/SimpleGame.java b/completedwork/core_programming/02_classbased_design/Workspace/Lab05/src/SimpleGame.java new file mode 100644 index 0000000..c593613 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab05/src/SimpleGame.java @@ -0,0 +1,329 @@ +import tester.*; // The tester library +import javalib.worldimages.*; // images, like RectangleImage or OverlayImages +import javalib.funworld.*; // the abstract World class and the big-bang library +import java.awt.Color; // general colors (as triples of red,green,blue values) +// and predefined colors (Color.RED, Color.GRAY, etc.) +import java.util.Random; + +class MyPosn extends Posn { + // standard constructor + MyPosn(int x, int y) { + super(x, y); + } + // constructor to convert from a Posn to a MyPosn + MyPosn(Posn p) { + this(p.x, p.y); + } + + MyPosn add(MyPosn that) { + // return a Posn with the x and y values of this and that Posn added together + return new MyPosn(this.x + that.x, this.y + that.y); + } + boolean isOffscreen(int width, int height) { + // returns true if this Posn is outside the provided screen dimensions + return this.x <= 0 || + this.x >= width || + this.y <= 0 || + this.y >= height; + } + int getX() { + return this.x; + } + int getY() { + return this.y; + } +} + +class Circle { + int radius; + MyPosn position; // in pixels + MyPosn velocity; // in pixels/tick + String fill; + Color color; + String DEFAULTFILL = "solid"; + Color DEFAULTCOLOR = Color.BLACK; + + Circle(int radius, MyPosn position, MyPosn velocity, String fill, Color color) { + this.radius = radius; + this.position = position; + this.velocity = velocity; + this.fill = fill; + this.color = color; + } + Circle(int radius, MyPosn position, MyPosn velocity) { + this.radius = radius; + this.position = position; + this.velocity = velocity; + this.fill = this.DEFAULTFILL; + this.color = this.DEFAULTCOLOR; + } + + Circle move() { + // returns a circle after being moved one tick + return new Circle(this.radius, this.position.add(velocity), velocity); + } + boolean isOffscreen(int width, int height) { + // returns true if this is outside the provided screen dimensions + return this.position.isOffscreen(width, height); + } + WorldImage draw() { + // returns an CircleImage of this + return new CircleImage(this.radius, this.fill, this.color); + } + WorldScene place(WorldScene scene) { + // returns a worldscene with a drawing of the circle at the appropriate position. + return scene.placeImageXY(this.draw(), this.position.getX(), this.position.getY()); + } +} + +interface ILoCircle { + // returns list of moved circles + ILoCircle moveAll(); + // returns a count of all offscreen circles + int countOffscreen(int width, int height); + int countOffscreenHelper(int width, int height, int cnt); + // returns list of circles with offscreen items removed + ILoCircle removeOffscreen(int width, int height); + // returns a scene with all circles drawn and placed + WorldScene placeAll(WorldScene scene); + // returns true if this list is empty + boolean isEmpty(); +} + +class MtLoCircle implements ILoCircle { + MtLoCircle() {} + public ILoCircle moveAll() { + return this; + } + public int countOffscreen(int width, int height) { + return 0; + } + public int countOffscreenHelper(int width, int height, int cnt) { + return cnt; + } + public ILoCircle removeOffscreen(int width, int height) { + return this; + } + public WorldScene placeAll(WorldScene scene) { + return scene; + } + public boolean isEmpty() { + return true; + } +} + +class ConsLoCircle implements ILoCircle { + Circle first; + ILoCircle rest; + ConsLoCircle(Circle first, ILoCircle rest) { + this.first = first; + this.rest = rest; + } + + public ILoCircle moveAll() { + return new ConsLoCircle(this.first.move(), this.rest.moveAll()); + } + public int countOffscreen(int width, int height) { + return this.countOffscreenHelper(width, height, 0); + } + public int countOffscreenHelper(int width, int height, int cnt) { + if (this.first.isOffscreen(width, height)) { + return this.rest.countOffscreenHelper(width, height, cnt + 1); + } else { + return this.rest.countOffscreenHelper(width, height, cnt); + } + } + public ILoCircle removeOffscreen(int width, int height) { + if (this.first.isOffscreen(width, height)) { + return this.rest.removeOffscreen(width, height); + } else { + return new ConsLoCircle(this.first, this.rest.removeOffscreen(width, height)); + } + } + public WorldScene placeAll(WorldScene scene) { + return this.rest.placeAll(this.first.place(scene)); + } + public boolean isEmpty() { + return false; + } +} + +class MyGame extends World { + double TICKRATE = 1.0 / 28.0; + int VELOMAG = 10; + int width; + int height; + int circlesRemoved; + int gameOver; + ILoCircle loCircles; + Random rand; + MyGame(int width, int height, int circlesRemoved, int gameOver, ILoCircle loCircles, + Random rand) { + this.width = width; + this.height = height; + this.circlesRemoved = circlesRemoved; + this.gameOver = gameOver; + this.loCircles = loCircles; + this.rand = rand; + } + MyGame(int gameOver, int seed) { + this.width = 500; + this.height = 300; + this.circlesRemoved = 0; + this.gameOver = gameOver; + this.loCircles = new MtLoCircle(); + this.rand = new Random(seed); + } + MyGame(int gameOver) { + this.width = 500; + this.height = 300; + this.circlesRemoved = 0; + this.gameOver = gameOver; + this.loCircles = new MtLoCircle(); + this.rand = new Random(); + } + public boolean start() { + return this.bigBang(this.width, this.height, this.TICKRATE); + } + @Override + public WorldScene makeScene() { + WorldScene scene = new WorldScene(this.width, this.height); + return this.loCircles.placeAll(scene); + } + @Override + public MyGame onTick() { + return this.moveCircles().removeCircles(); + } + public MyGame removeCircles() { + return new MyGame(this.width, + this.height, + this.circlesRemoved + this.loCircles.countOffscreen(this.width, this.height), + this.gameOver, + this.loCircles.removeOffscreen(this.width, this.height), + this.rand); + } + public MyGame moveCircles() { + return new MyGame(this.width, + this.height, + this.circlesRemoved, + this.gameOver, + this.loCircles.moveAll(), + this.rand); + } + @Override + public MyGame onMouseClicked(Posn pos) { + return new MyGame(this.width, + this.height, + this.circlesRemoved, + this.gameOver, + new ConsLoCircle(new Circle(10, new MyPosn(pos), this.randomVelo()), + this.loCircles), + this.rand); + } + public MyPosn randomVelo() { + switch (this.rand.nextInt(4)) { + case 0: + return new MyPosn(this.VELOMAG, 0); + case 1: + return new MyPosn(0, this.VELOMAG); + case 2: + return new MyPosn(this.VELOMAG * -1, 0); + case 3: + return new MyPosn(0, this.VELOMAG * -1); + default: + return new MyPosn(this.VELOMAG, 0); // should never happen + } + + } + @Override + public WorldEnd worldEnds() { + if (this.gameOver <= this.circlesRemoved) { + return new WorldEnd(true, this.makeEndScene()); + } else { + return new WorldEnd(false, this.makeEndScene()); + } + } + public WorldScene makeEndScene() { + WorldScene endScene = new WorldScene(this.width, this.height); + return endScene.placeImageXY(new TextImage("Game Over", Color.red), 250, 250); + + } +} + +class Examples { + MyPosn pn0 = new MyPosn(0, 0); + MyPosn pn1 = new MyPosn(100, 100); + MyPosn pn2 = new MyPosn(200, 200); + MyPosn pn3_offscreen = new MyPosn(-100, 200); + MyPosn pn4_offscreen = new MyPosn(200, -200); + MyPosn pn5_offscreen = new MyPosn(600, 200); + MyPosn pn6_offscreen = new MyPosn(200, 500); + + boolean testAdd(Tester t) { + return t.checkExpect(pn0.add(pn0), pn0) && + t.checkExpect(pn1.add(pn0), pn1) && + t.checkExpect(pn1.add(pn1), pn2) && + t.checkExpect(pn1.add(pn2), new MyPosn(300, 300)); + } + boolean testPosnOffscreen(Tester t) { + return t.checkExpect(pn1.isOffscreen(500, 300), false) && + t.checkExpect(pn3_offscreen.isOffscreen(500, 300), true) && + t.checkExpect(pn4_offscreen.isOffscreen(500, 300), true) && + t.checkExpect(pn5_offscreen.isOffscreen(500, 300), true) && + t.checkExpect(pn6_offscreen.isOffscreen(500, 300), true); + } + + Circle c1 = new Circle(1, pn1, pn0); + Circle c2 = new Circle(1, pn1, pn1); + Circle c3 = new Circle(1, pn2, pn1); + Circle c4_offscreen = new Circle(1, pn4_offscreen, pn1); + Circle c5_offscreen = new Circle(1, pn5_offscreen, pn1); + WorldScene scene0 = new WorldScene(500, 300); + boolean testMove(Tester t) { + return t.checkExpect(c1.move(), c1) && + t.checkExpect(c2.move(), c3); + } + boolean testIsOffscreen(Tester t) { + return t.checkExpect(c1.isOffscreen(500, 300), false) && + t.checkExpect(c2.isOffscreen(500, 300), false) && + t.checkExpect(c3.isOffscreen(500, 300), false) && + t.checkExpect(c4_offscreen.isOffscreen(500, 300), true) && + t.checkExpect(c5_offscreen.isOffscreen(500, 300), true); + } + boolean testDraw(Tester t) { + return t.checkExpect(c1.draw(), new CircleImage(1, OutlineMode.SOLID, Color.BLACK)); + } + boolean testPlace(Tester t) { + return t.checkExpect(c1.place(scene0), + scene0.placeImageXY(new CircleImage(1, OutlineMode.SOLID, Color.BLACK), 100, 100)); + } + + ILoCircle loc0 = new MtLoCircle(); + ILoCircle loc1 = new ConsLoCircle(c1, loc0); + ILoCircle loc2 = new ConsLoCircle(c2, loc1); + ILoCircle loc3 = new ConsLoCircle(c3, loc1); + ILoCircle loc2_moved = new ConsLoCircle(c1, new ConsLoCircle(c3, loc0)); + ILoCircle loc2_withOffscreen = new ConsLoCircle(c4_offscreen, + new ConsLoCircle(c5_offscreen, loc2)); + WorldScene scene1 = scene0.placeImageXY(c1.draw(), 100, 100); + WorldScene scene2 = scene1.placeImageXY(c3.draw(), 200, 200); + boolean testMoveAll(Tester t) { + return t.checkExpect(this.loc0.moveAll(), this.loc0) && + t.checkExpect(this.loc1.moveAll(), this.loc1) && + t.checkExpect(this.loc2.moveAll(), this.loc2_moved); + } + boolean testRemoveAll(Tester t) { + return t.checkExpect(this.loc0.removeOffscreen(500, 300), this.loc0) && + t.checkExpect(this.loc2.removeOffscreen(500, 300), this.loc2) && + t.checkExpect(this.loc2_withOffscreen.removeOffscreen(500, 300), this.loc2); + } + boolean testPlaceAll(Tester t) { + return t.checkExpect(this.loc0.placeAll(scene0), scene0) && + t.checkExpect(this.loc1.placeAll(scene0), scene1) && + t.checkExpect(this.loc3.placeAll(scene0), scene2); + } + boolean testBigBang(Tester t) { + MyGame world = new MyGame(10); + return world.start(); + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab06_VisitorsAndGenerics/.classpath b/completedwork/core_programming/02_classbased_design/Workspace/Lab06_VisitorsAndGenerics/.classpath new file mode 100644 index 0000000..e446dbd --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab06_VisitorsAndGenerics/.classpath @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab06_VisitorsAndGenerics/.project b/completedwork/core_programming/02_classbased_design/Workspace/Lab06_VisitorsAndGenerics/.project new file mode 100644 index 0000000..250ab10 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab06_VisitorsAndGenerics/.project @@ -0,0 +1,17 @@ + + + Lab06_VisitorsAndGenerics + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab06_VisitorsAndGenerics/.settings/org.eclipse.core.resources.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lab06_VisitorsAndGenerics/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab06_VisitorsAndGenerics/.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/Lab06_VisitorsAndGenerics/.settings/org.eclipse.jdt.core.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lab06_VisitorsAndGenerics/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..e71285a --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab06_VisitorsAndGenerics/.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/Lab06_VisitorsAndGenerics/src/Examples.java b/completedwork/core_programming/02_classbased_design/Workspace/Lab06_VisitorsAndGenerics/src/Examples.java new file mode 100644 index 0000000..259dce2 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab06_VisitorsAndGenerics/src/Examples.java @@ -0,0 +1,63 @@ +import tester.Tester; + +class Examples { + IList list_int = new ConsList(1, + new ConsList(2, new ConsList(3, new MtList()))); + + boolean testFoldr(Tester t) { + return t.checkExpect(this.list_int.foldr(new SumInteger(), 0), 6); + } + + IList list_json1 = new ConsList(new JSONBlank(), + new ConsList(new JSONNumber(1), new ConsList(new JSONBool(false), + new ConsList(new JSONString("A"), new MtList())))); + IList list_j2n1 = new ConsList(0, + new ConsList(1, new ConsList(0, + new ConsList(1, new MtList())))); + JSONList jList = new JSONList(list_json1); + IList list_json2 = new ConsList(jList, new MtList()); + IList list_j2n2 = new ConsList(2, new MtList()); + IList list_json3 = new ConsList(new JSONBlank(), + new ConsList(new JSONNumber(-1), new ConsList(new JSONBool(false), + new ConsList(new JSONString(""), new MtList())))); + + boolean testJSONMap(Tester t) { + return t.checkExpect(this.list_json1.map(new JSONToNumber()), list_j2n1) && + t.checkExpect(this.list_json2.map(new JSONToNumber()), list_j2n2); + } + + boolean testFilter(Tester t) { + return t.checkExpect(this.list_j2n1.filter(new IsIntPositive()), + new ConsList(1, new ConsList(1, new MtList()))); + } + boolean testFindSolution(Tester t) { + return t.checkExpect( + this.list_json1.findSolutionOrElse(new JSONToNumber(), new IsIntPositive(), 0), 1) && + t.checkExpect( + this.list_json3.findSolutionOrElse(new JSONToNumber(), new IsIntPositive(), 0), 0); + } + + Pair p0 = new Pair("A", new JSONBlank()); + Pair p1 = new Pair("B", new JSONNumber(1)); + Pair p2 = new Pair("C", new JSONBool(false)); + Pair p3 = new Pair("D", new JSONString("D")); + + JSONObject jObj1 = new JSONObject(new ConsList>(p0, + new ConsList>(p1, + new ConsList>(p2, + new ConsList>(p3, + new MtList>()))))); + + IList list_json4 = new ConsList(jObj1, new MtList()); + + boolean testJObjVisitor(Tester t) { + return t.checkExpect(this.list_json4.map(new JSONToNumber()), this.list_j2n2); + } + + boolean testJsonFind(Tester t) { + return t.checkExpect(this.list_json4.map(new JSONFind("B")), + new ConsList(new JSONNumber(1), new MtList())) && + t.checkExpect(this.list_json4.map(new JSONFind("E")), + new ConsList(new JSONBlank(), new MtList())); + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab06_VisitorsAndGenerics/src/Generics.java b/completedwork/core_programming/02_classbased_design/Workspace/Lab06_VisitorsAndGenerics/src/Generics.java new file mode 100644 index 0000000..1fba079 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab06_VisitorsAndGenerics/src/Generics.java @@ -0,0 +1,82 @@ +// Represents functions of signature A -> R, for some argument type A and +// result type R +interface IFunc { + R apply(A input); +} + +interface IFunc2 { + R apply(A1 arg1, A2 arg2); +} + +interface IPred { + boolean apply(T t); +} + +// generic list +interface IList { + T getFirst(T t); + IList filter(IPred pred); + // map over a list, and produce a new list with a (possibly different) + // element type + IList map(IFunc f); + U foldr(IFunc2 func, U base); + U findSolutionOrElse(IFunc convert, IPred pred, U backup); + T getFirstOrBackup(T backup); +} + +// empty generic list +class MtList implements IList { + public T getFirst(T t) { + return t; + } + public IList filter(IPred pred) { + return this; + } + public IList map(IFunc f) { + return new MtList(); + } + public U foldr(IFunc2 func, U base) { + return base; + } + public U findSolutionOrElse(IFunc convert, IPred pred, U backup) { + return backup; + } + public T getFirstOrBackup(T backup) { + return backup; + } +} + +// non-empty generic list +class ConsList implements IList { + T first; + IList rest; + + ConsList(T first, IList rest) { + this.first = first; + this.rest = rest; + } + public T getFirst(T t) { + return this.first; + } + public IList filter(IPred pred) { + if (pred.apply(this.first)) { + return new ConsList(this.first, this.rest.filter(pred)); + } else { + return this.rest.filter(pred); + } + } + public IList map(IFunc f) { + return new ConsList(f.apply(this.first), this.rest.map(f)); + } + public U foldr(IFunc2 func, U base) { + return func.apply(this.first, this.rest.foldr(func, base)); + } + public U findSolutionOrElse(IFunc convert, IPred pred, U backup) { + return this.map(convert) // List -> List + .filter(pred) // List -> List (filtered where pred == true) + .getFirstOrBackup(backup); // List -> U (first value of list where pred == true) + } + public T getFirstOrBackup(T backup) { + return this.first; + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab06_VisitorsAndGenerics/src/JSON.java b/completedwork/core_programming/02_classbased_design/Workspace/Lab06_VisitorsAndGenerics/src/JSON.java new file mode 100644 index 0000000..0ff0aa0 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab06_VisitorsAndGenerics/src/JSON.java @@ -0,0 +1,86 @@ +// a json value +interface JSON { + R accept(IJsonVisitor visitor); +} + +// no value +class JSONBlank implements JSON { + public R accept(IJsonVisitor visitor) { + return visitor.visitBlank(this); + } +} + +// a number +class JSONNumber implements JSON { + int number; + + JSONNumber(int number) { + this.number = number; + } + public R accept(IJsonVisitor visitor) { + return visitor.visitNumber(this); + } +} + +// a boolean +class JSONBool implements JSON { + boolean bool; + + JSONBool(boolean bool) { + this.bool = bool; + } + public R accept(IJsonVisitor visitor) { + return visitor.visitBool(this); + } +} + +// a string +class JSONString implements JSON { + String str; + + JSONString(String str) { + this.str = str; + } + public R accept(IJsonVisitor visitor) { + return visitor.visitString(this); + } +} + +//a list of JSON values +class JSONList implements JSON { + IList values; + + JSONList(IList values) { + this.values = values; + } + public R accept(IJsonVisitor visitor) { + return visitor.visitList(this); + } +} + +//a list of JSON pairs +class JSONObject implements JSON { + IList> pairs; + + JSONObject(IList> pairs) { + this.pairs = pairs; + } + public R accept(IJsonVisitor visitor) { + return visitor.visitObject(this); + } + + // public String find(IPairsVisitor visitor) { + // return + // } +} + +//generic pairs +class Pair { + X x; + Y y; + + Pair(X x, Y y) { + this.x = x; + this.y = y; + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab06_VisitorsAndGenerics/src/Visitor.java b/completedwork/core_programming/02_classbased_design/Workspace/Lab06_VisitorsAndGenerics/src/Visitor.java new file mode 100644 index 0000000..6ab4877 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab06_VisitorsAndGenerics/src/Visitor.java @@ -0,0 +1,121 @@ +class IsIntPositive implements IPred { + public boolean apply(Integer i) { + return i > 0; + } +} + +class FindKey implements IPred> { + String find; + FindKey(String find) { + this.find = find; + } + public boolean apply(Pair p) { + return find.compareTo(p.x) == 0; + } +} + +class MatchString implements IPred { + String find; + MatchString(String find) { + this.find = find; + } + public boolean apply(String str) { + return find.compareTo(str) == 0; + } +} + +class PairsToKey implements IFunc, String> { + public String apply(Pair p) { + return p.x; + } +} + +class PairsToJSON implements IFunc, JSON> { + public JSON apply(Pair p) { + return p.y; + } +} + +class SumInteger implements IFunc2 { + public Integer apply(Integer i, Integer sum) { + return i + sum; + } +} + +interface IJsonVisitor extends IFunc { + R visitBlank(JSONBlank blank); + R visitNumber(JSONNumber number); + R visitBool(JSONBool bool); + R visitString(JSONString str); + R visitList(JSONList list); + R visitObject(JSONObject obj); +} + +class JSONToNumber implements IJsonVisitor { + public Integer apply(JSON j) { + return j.accept(this); + } + public Integer visitBlank(JSONBlank blank) { + return 0; + } + public Integer visitNumber(JSONNumber number) { + return number.number; + } + public Integer visitBool(JSONBool bool) { + if (bool.bool) { + return 1; + } else { + return 0; + } + } + public Integer visitString(JSONString str) { + return str.str.length(); + } + public Integer visitList(JSONList list) { + return list.values.map(new JSONToNumber()).foldr(new SumInteger(), 0); + } + public Integer visitObject(JSONObject obj) { + return obj.pairs.map(new PairsToJSON()) // List -> JSONList + .map(new JSONToNumber()) // JSONList -> List + .foldr(new SumInteger(), 0); // List -> Integer + } +} + +interface IPairsVisitor extends IFunc {} + +class JSONFind implements IJsonVisitor { + String find; + JSONFind(String find) { + this.find = find; + } + public JSON apply(JSON j) { + return j.accept(this); + } + public JSON visitBlank(JSONBlank blank) { + return new JSONBlank(); + } + public JSON visitNumber(JSONNumber number) { + return new JSONBlank(); + } + public JSON visitBool(JSONBool bool) { + return new JSONBlank(); + } + public JSON visitString(JSONString str) { + if (this.find.compareTo(str.str) == 0) { + return str; + } else { + return new JSONBlank(); + } + } + public JSON visitList(JSONList list) { + return list.values //JSONList -> List + .map(new JSONFind(find)) //List -> List (containing JSONBlank and value == find) + .getFirstOrBackup(new JSONBlank()); //List -> JSON (first value of List) + } + public JSON visitObject(JSONObject obj) { + return obj.pairs // JSONObject -> List + .filter(new FindKey(find)) // List> -> List> (where key == find) + .map(new PairsToJSON()) // List> -> List + .getFirstOrBackup(new JSONBlank()); // List -> JSON (first value of List + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/.classpath b/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/.classpath new file mode 100644 index 0000000..8e3d409 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/.classpath @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/.project b/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/.project new file mode 100644 index 0000000..4c34331 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/.project @@ -0,0 +1,17 @@ + + + Lab07_Buddies + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/.settings/org.eclipse.core.resources.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/.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/Lab07_Buddies/.settings/org.eclipse.jdt.core.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..e71285a --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/.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/Lab07_Buddies/src/ConsLoBuddy.java b/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/src/ConsLoBuddy.java new file mode 100644 index 0000000..c75b020 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/src/ConsLoBuddy.java @@ -0,0 +1,65 @@ +// represents a list of Person's buddies +class ConsLoBuddy implements ILoBuddy { + + Person first; + ILoBuddy rest; + + ConsLoBuddy(Person first, ILoBuddy rest) { + this.first = first; + this.rest = rest; + } + // returns ILoBuddy which includes this and that + public ILoBuddy combine(ILoBuddy that) { + if (!that.isIncluded(this.first)) { + return new ConsLoBuddy(this.first, this.rest.combine(that)); + } else { + return this.rest.combine(that); + } + } + // returns true if that person is included in buddy list + public boolean isIncluded(Person that) { + if (this.first.equals(that)) { + return true; + } else { + return this.rest.isIncluded(that); + } + } + // returns the count of common persons in buddy list + public int countCommon(ILoBuddy those) { + return this.countCommonHelper(those, 0); + } + public int countCommonHelper(ILoBuddy those, int csf) { + if (those.isIncluded(this.first)) { + return this.rest.countCommonHelper(those, csf + 1); + } else { + return this.rest.countCommonHelper(those, csf); + } + } + // returns true if that person is included this extended buddy list + public boolean hasExtendedBuddy(Person that) { + return this.hasExtendedBuddyHelper(that, new MTLoBuddy()); + } + public boolean hasExtendedBuddyHelper(Person that, ILoBuddy wasChecked) { + if (wasChecked.isIncluded(this.first)) { + // if the first person was already checked move on + return this.rest.hasExtendedBuddyHelper(that, wasChecked); + } else if (this.first.equals(that)) { + // if the first person is the person person we are looking for return true + return true; + } else { + return this.rest.combine(this.first.buddies) // add first's buddies to work list accumulator (this.rest) + .hasExtendedBuddyHelper(that, // recursive call search + new ConsLoBuddy(this.first, wasChecked)); // add first to wasChecked so we dont look at them again + } + } + public int partyCount(int csf, ILoBuddy wasChecked) { + if (wasChecked.isIncluded(this.first)) { + // if the first person was already checked move on + return this.rest.partyCount(csf, wasChecked); + } else { + return this.rest.combine(this.first.buddies) + .partyCount(csf + 1, + new ConsLoBuddy(this.first, wasChecked)); + } + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/src/ExamplesBuddies.java b/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/src/ExamplesBuddies.java new file mode 100644 index 0000000..bff81fc --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/src/ExamplesBuddies.java @@ -0,0 +1,121 @@ +import tester.Tester; +//Ann's buddies are Bob and Cole +//Bob's buddies are Ann and Ed and Hank +//Cole's buddy is Dan +//Dan's buddy is Cole +//Ed's buddy is Fay +//Fay's buddies are Ed and Gabi +//Gabi's buddies are Ed and Fay +//Hank does not have any buddies +//Jan's buddies are Kim and Len +//Kim's buddies are Jan and Len +//Len's buddies are Jan and Kim + +public class ExamplesBuddies { + Person ann; + Person bob; + Person cole; + Person dan; + Person ed; + Person fay; + Person gabi; + Person hank; + Person jan; + Person kim; + Person len; + + Person lotsa; + + void initTestConditions() { + this.ann = new Person("ann"); + this.bob = new Person("bob"); + this.cole = new Person("cole"); + this.dan = new Person("dan"); + this.ed = new Person("ed"); + this.fay = new Person("fay"); + this.gabi = new Person("gabi"); + this.hank = new Person("hank"); + this.jan = new Person("jan"); + this.kim = new Person("kim"); + this.len = new Person("len"); + + this.ann.addBuddy(bob); + this.ann.addBuddy(cole); + this.bob.addBuddy(ann); + this.bob.addBuddy(ed); + this.bob.addBuddy(hank); + this.cole.addBuddy(dan); + this.dan.addBuddy(cole); + this.ed.addBuddy(fay); + this.fay.addBuddy(ed); + this.fay.addBuddy(gabi); + this.gabi.addBuddy(ed); + this.gabi.addBuddy(fay); + this.jan.addBuddy(kim); + this.jan.addBuddy(len); + this.kim.addBuddy(jan); + this.kim.addBuddy(len); + this.len.addBuddy(jan); + this.len.addBuddy(kim); + } + + void testInit(Tester t) { + initTestConditions(); + t.checkExpect(this.ann.buddies, + new ConsLoBuddy(this.cole, new ConsLoBuddy(this.bob, new MTLoBuddy()))); + t.checkExpect(this.hank.buddies, new MTLoBuddy()); + } + void testCombine(Tester t) { + initTestConditions(); + ILoBuddy mtList = new MTLoBuddy(); + ILoBuddy list1 = new ConsLoBuddy(this.ann, new ConsLoBuddy(this.bob, mtList)); + ILoBuddy list2 = new ConsLoBuddy(this.cole, new ConsLoBuddy(this.dan, mtList)); + ILoBuddy list_combo = new ConsLoBuddy(this.ann, new ConsLoBuddy(this.bob, + new ConsLoBuddy(this.cole, new ConsLoBuddy(this.dan, mtList)))); + t.checkExpect(list1.combine(list2), list_combo); + } + + void testHadBuddy(Tester t) { + initTestConditions(); + t.checkExpect(this.ann.hasDirectBuddy(bob), true); + t.checkExpect(this.ann.hasDirectBuddy(cole), true); + t.checkExpect(this.ann.hasDirectBuddy(dan), false); + t.checkExpect(this.cole.hasDirectBuddy(ann), false); + } + void testCountCommonBuddies(Tester t) { + initTestConditions(); + this.lotsa = new Person("Lotsa"); + this.lotsa.addBuddy(ann); + this.lotsa.addBuddy(bob); + this.lotsa.addBuddy(cole); + this.lotsa.addBuddy(dan); + this.lotsa.addBuddy(ed); + this.lotsa.addBuddy(fay); + this.lotsa.addBuddy(gabi); + this.lotsa.addBuddy(hank); + this.lotsa.addBuddy(jan); + this.lotsa.addBuddy(kim); + this.lotsa.addBuddy(len); + + t.checkExpect(this.ann.countCommonBuddies(bob), 0); + t.checkExpect(this.bob.countCommonBuddies(ann), 0); + t.checkExpect(this.ann.countCommonBuddies(dan), 1); + t.checkExpect(this.len.countCommonBuddies(kim), 1); + t.checkExpect(this.lotsa.countCommonBuddies(bob), 3); + t.checkExpect(this.bob.countCommonBuddies(lotsa), 3); + } + void testHasExtendedBuddy(Tester t) { + initTestConditions(); + t.checkExpect(this.ann.hasExtendedBuddy(bob), true); + t.checkExpect(this.ann.hasExtendedBuddy(ed), true); + t.checkExpect(this.ann.hasExtendedBuddy(fay), true); + t.checkExpect(this.ann.hasExtendedBuddy(gabi), true); + t.checkExpect(this.ann.hasExtendedBuddy(jan), false); + } + void testPartyCount(Tester t) { + t.checkExpect(this.len.partyCount(), 2); + t.checkExpect(this.kim.partyCount(), 2); + t.checkExpect(this.hank.partyCount(), 0); + t.checkExpect(this.ann.partyCount(), 7); + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/src/ILoBuddy.java b/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/src/ILoBuddy.java new file mode 100644 index 0000000..14106e0 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/src/ILoBuddy.java @@ -0,0 +1,15 @@ + +// represents a list of Person's buddies +interface ILoBuddy { + // returns ILoBuddy which includes this and that + ILoBuddy combine(ILoBuddy that); + // returns true if that person is included in buddy list + boolean isIncluded(Person that); + // returns the count of common persons in buddy list + int countCommon(ILoBuddy those); + int countCommonHelper(ILoBuddy those, int csf); + // returns true if that person is included this extended buddylist + boolean hasExtendedBuddy(Person that); + boolean hasExtendedBuddyHelper(Person that, ILoBuddy wasChecked); + int partyCount(int csf, ILoBuddy wasChecked); +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/src/MTLoBuddy.java b/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/src/MTLoBuddy.java new file mode 100644 index 0000000..54bd1f8 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/src/MTLoBuddy.java @@ -0,0 +1,31 @@ + +// represents an empty list of Person's buddies +class MTLoBuddy implements ILoBuddy { + MTLoBuddy() {} + + // returns ILoBuddy which includes this and that + public ILoBuddy combine(ILoBuddy that) { + return that; + } + // returns true if that person is included in buddy list + public boolean isIncluded(Person that) { + return false; + } + // returns the count of common persons in buddy list + public int countCommon(ILoBuddy those) { + return 0; + } + public int countCommonHelper(ILoBuddy those, int csf) { + return csf; + } + // returns true if that person is included this extended buddylist + public boolean hasExtendedBuddy(Person that) { + return false; + } + public boolean hasExtendedBuddyHelper(Person that, ILoBuddy wasChecked) { + return false; + } + public int partyCount(int csf, ILoBuddy wasChecked) { + return csf; + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/src/Person.java b/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/src/Person.java new file mode 100644 index 0000000..6f8f0ae --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab07_Buddies/src/Person.java @@ -0,0 +1,45 @@ + +// represents a Person with a user name and a list of buddies +class Person { + + String username; + ILoBuddy buddies; + + Person(String username) { + this.username = username; + this.buddies = new MTLoBuddy(); + } + + // add p to this person's buddy list + void addBuddy(Person p) { + this.buddies = new ConsLoBuddy(p, this.buddies); + } + + // returns true if this Person has that as a direct buddy + boolean hasDirectBuddy(Person that) { + return this.buddies.isIncluded(that); + } + + // returns the number of people that are direct buddies + // of both this and that person + int countCommonBuddies(Person that) { + return this.buddies.countCommon(that.buddies); + } + + // will that person be invited to a party + // organized by this person? + boolean hasExtendedBuddy(Person that) { + return this.buddies.hasExtendedBuddy(that); + } + // renamed hasExtendedBuddy + boolean isInvited(Person that) { + return this.hasExtendedBuddy(that); + } + + // returns the number of people who will show up at the party + // given by this person (not including inviter (this)) + int partyCount() { + return this.buddies.partyCount(0, // initialize count + new ConsLoBuddy(this, new MTLoBuddy())); // add this person to wasChecked to avoid off by one + } +}