Labs 5 through 7

This commit is contained in:
Nathan Howard 2025-11-21 18:46:38 -08:00
parent 5641a77589
commit 4b928dd18e
22 changed files with 1083 additions and 0 deletions

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src"/>
<classpathentry kind="lib" path="/Users/nathanhoward/Documents/Code/OSSU-CS/completedwork/core_programming/02_classbased_design/Jars/javalib.jar"/>
<classpathentry kind="lib" path="/Users/nathanhoward/Documents/Code/OSSU-CS/completedwork/core_programming/02_classbased_design/Jars/tester.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Lab05</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@ -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

View File

@ -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();
}
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src"/>
<classpathentry kind="lib" path="/Users/nathanhoward/Documents/Code/OSSU-CS/completedwork/core_programming/02_classbased_design/Jars/javalib.jar"/>
<classpathentry kind="lib" path="/Users/nathanhoward/Documents/Code/OSSU-CS/completedwork/core_programming/02_classbased_design/Jars/tester.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Lab06_VisitorsAndGenerics</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@ -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

View File

@ -0,0 +1,63 @@
import tester.Tester;
class Examples {
IList<Integer> list_int = new ConsList<Integer>(1,
new ConsList<Integer>(2, new ConsList<Integer>(3, new MtList<Integer>())));
boolean testFoldr(Tester t) {
return t.checkExpect(this.list_int.foldr(new SumInteger(), 0), 6);
}
IList<JSON> list_json1 = new ConsList<JSON>(new JSONBlank(),
new ConsList<JSON>(new JSONNumber(1), new ConsList<JSON>(new JSONBool(false),
new ConsList<JSON>(new JSONString("A"), new MtList<JSON>()))));
IList<Integer> list_j2n1 = new ConsList<Integer>(0,
new ConsList<Integer>(1, new ConsList<Integer>(0,
new ConsList<Integer>(1, new MtList<Integer>()))));
JSONList jList = new JSONList(list_json1);
IList<JSON> list_json2 = new ConsList<JSON>(jList, new MtList<JSON>());
IList<Integer> list_j2n2 = new ConsList<Integer>(2, new MtList<Integer>());
IList<JSON> list_json3 = new ConsList<JSON>(new JSONBlank(),
new ConsList<JSON>(new JSONNumber(-1), new ConsList<JSON>(new JSONBool(false),
new ConsList<JSON>(new JSONString(""), new MtList<JSON>()))));
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<Integer>(1, new ConsList<Integer>(1, new MtList<Integer>())));
}
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<String, JSON> p0 = new Pair<String, JSON>("A", new JSONBlank());
Pair<String, JSON> p1 = new Pair<String, JSON>("B", new JSONNumber(1));
Pair<String, JSON> p2 = new Pair<String, JSON>("C", new JSONBool(false));
Pair<String, JSON> p3 = new Pair<String, JSON>("D", new JSONString("D"));
JSONObject jObj1 = new JSONObject(new ConsList<Pair<String, JSON>>(p0,
new ConsList<Pair<String, JSON>>(p1,
new ConsList<Pair<String, JSON>>(p2,
new ConsList<Pair<String, JSON>>(p3,
new MtList<Pair<String, JSON>>())))));
IList<JSON> list_json4 = new ConsList<JSON>(jObj1, new MtList<JSON>());
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<JSON>(new JSONNumber(1), new MtList<JSON>())) &&
t.checkExpect(this.list_json4.map(new JSONFind("E")),
new ConsList<JSON>(new JSONBlank(), new MtList<JSON>()));
}
}

View File

@ -0,0 +1,82 @@
// Represents functions of signature A -> R, for some argument type A and
// result type R
interface IFunc<A, R> {
R apply(A input);
}
interface IFunc2<A1, A2, R> {
R apply(A1 arg1, A2 arg2);
}
interface IPred<T> {
boolean apply(T t);
}
// generic list
interface IList<T> {
T getFirst(T t);
IList<T> filter(IPred<T> pred);
// map over a list, and produce a new list with a (possibly different)
// element type
<U> IList<U> map(IFunc<T, U> f);
<U> U foldr(IFunc2<T, U, U> func, U base);
<U> U findSolutionOrElse(IFunc<T, U> convert, IPred<U> pred, U backup);
T getFirstOrBackup(T backup);
}
// empty generic list
class MtList<T> implements IList<T> {
public T getFirst(T t) {
return t;
}
public IList<T> filter(IPred<T> pred) {
return this;
}
public <U> IList<U> map(IFunc<T, U> f) {
return new MtList<U>();
}
public <U> U foldr(IFunc2<T, U, U> func, U base) {
return base;
}
public <U> U findSolutionOrElse(IFunc<T, U> convert, IPred<U> pred, U backup) {
return backup;
}
public T getFirstOrBackup(T backup) {
return backup;
}
}
// non-empty generic list
class ConsList<T> implements IList<T> {
T first;
IList<T> rest;
ConsList(T first, IList<T> rest) {
this.first = first;
this.rest = rest;
}
public T getFirst(T t) {
return this.first;
}
public IList<T> filter(IPred<T> pred) {
if (pred.apply(this.first)) {
return new ConsList<T>(this.first, this.rest.filter(pred));
} else {
return this.rest.filter(pred);
}
}
public <U> IList<U> map(IFunc<T, U> f) {
return new ConsList<U>(f.apply(this.first), this.rest.map(f));
}
public <U> U foldr(IFunc2<T, U, U> func, U base) {
return func.apply(this.first, this.rest.foldr(func, base));
}
public <U> U findSolutionOrElse(IFunc<T, U> convert, IPred<U> pred, U backup) {
return this.map(convert) // List<T> -> List<U>
.filter(pred) // List<U> -> List<U> (filtered where pred == true)
.getFirstOrBackup(backup); // List<U> -> U (first value of list where pred == true)
}
public T getFirstOrBackup(T backup) {
return this.first;
}
}

View File

@ -0,0 +1,86 @@
// a json value
interface JSON {
<R> R accept(IJsonVisitor<R> visitor);
}
// no value
class JSONBlank implements JSON {
public <R> R accept(IJsonVisitor<R> visitor) {
return visitor.visitBlank(this);
}
}
// a number
class JSONNumber implements JSON {
int number;
JSONNumber(int number) {
this.number = number;
}
public <R> R accept(IJsonVisitor<R> visitor) {
return visitor.visitNumber(this);
}
}
// a boolean
class JSONBool implements JSON {
boolean bool;
JSONBool(boolean bool) {
this.bool = bool;
}
public <R> R accept(IJsonVisitor<R> visitor) {
return visitor.visitBool(this);
}
}
// a string
class JSONString implements JSON {
String str;
JSONString(String str) {
this.str = str;
}
public <R> R accept(IJsonVisitor<R> visitor) {
return visitor.visitString(this);
}
}
//a list of JSON values
class JSONList implements JSON {
IList<JSON> values;
JSONList(IList<JSON> values) {
this.values = values;
}
public <R> R accept(IJsonVisitor<R> visitor) {
return visitor.visitList(this);
}
}
//a list of JSON pairs
class JSONObject implements JSON {
IList<Pair<String, JSON>> pairs;
JSONObject(IList<Pair<String, JSON>> pairs) {
this.pairs = pairs;
}
public <R> R accept(IJsonVisitor<R> visitor) {
return visitor.visitObject(this);
}
// public String find(IPairsVisitor<String> visitor) {
// return
// }
}
//generic pairs
class Pair<X, Y> {
X x;
Y y;
Pair(X x, Y y) {
this.x = x;
this.y = y;
}
}

View File

@ -0,0 +1,121 @@
class IsIntPositive implements IPred<Integer> {
public boolean apply(Integer i) {
return i > 0;
}
}
class FindKey implements IPred<Pair<String, JSON>> {
String find;
FindKey(String find) {
this.find = find;
}
public boolean apply(Pair<String, JSON> p) {
return find.compareTo(p.x) == 0;
}
}
class MatchString implements IPred<String> {
String find;
MatchString(String find) {
this.find = find;
}
public boolean apply(String str) {
return find.compareTo(str) == 0;
}
}
class PairsToKey implements IFunc<Pair<String, JSON>, String> {
public String apply(Pair<String, JSON> p) {
return p.x;
}
}
class PairsToJSON implements IFunc<Pair<String, JSON>, JSON> {
public JSON apply(Pair<String, JSON> p) {
return p.y;
}
}
class SumInteger implements IFunc2<Integer, Integer, Integer> {
public Integer apply(Integer i, Integer sum) {
return i + sum;
}
}
interface IJsonVisitor<R> extends IFunc<JSON, R> {
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<Integer> {
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<Pairs<String, JSON> -> JSONList
.map(new JSONToNumber()) // JSONList -> List<Integer>
.foldr(new SumInteger(), 0); // List<Integer> -> Integer
}
}
interface IPairsVisitor<R> extends IFunc<JSON, R> {}
class JSONFind implements IJsonVisitor<JSON> {
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<JSON>
.map(new JSONFind(find)) //List<JSON> -> List<JSON> (containing JSONBlank and value == find)
.getFirstOrBackup(new JSONBlank()); //List<JSON> -> JSON (first value of List<JSON>)
}
public JSON visitObject(JSONObject obj) {
return obj.pairs // JSONObject -> List<Pairs<String, JSON>
.filter(new FindKey(find)) // List<Pairs<String, JSON>> -> List<Pairs<String, JSON>> (where key == find)
.map(new PairsToJSON()) // List<Pairs<String, JSON>> -> List<JSON>
.getFirstOrBackup(new JSONBlank()); // List<JSON> -> JSON (first value of List<JSON>
}
}

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src"/>
<classpathentry kind="lib" path="/Users/nathanhoward/Documents/Code/OSSU-CS/completedwork/core_programming/02_classbased_design/Jars/tester.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Lab07_Buddies</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@ -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

View File

@ -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));
}
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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
}
}