// This code requires the projf2.plt patch abstract class Animal { double weight; Animal(double weight) { this.weight = weight; } boolean isLighter(int n) { return this.weight < n; } boolean isLight() { return this.isLighter(10); } } class Snake extends Animal { String name; String food; Snake(String name, double weight, String food) { super(weight); this.name = name; this.food = food; } boolean likesFood(String s) { return this.food.equals(s); } } // Etc. for Dillo and Ant // ---------------------------------------- abstract class Path { abstract boolean isOk(); } class Fail extends Path { Fail() { } boolean isOk() { return false; } } abstract class Success extends Path { boolean isOk() { return true; } } class Immediate extends Success { Immediate() { } } class Right extends Success { Success rest; Right(Success rest) { this.rest = rest; } } class Left extends Success { Success rest; Left(Success rest) { this.rest = rest; } } // ---------------------------------------- abstract class Door { abstract Path escapePath(Person p); } class Into extends Door { Room next; Into(Room next) { this.next = next; } Path escapePath(Person p) { return this.next.escapePath(p); } } class Escape extends Door { String name; Escape(String name) { this.name = name; } Path escapePath(Person p) { if (p.isDest(this.name)) return new Immediate(); else return new Fail(); } } class Short extends Into { double height; Short(Room next, double height) { super(next); this.height = height; } Path escapePath(Person p) { if (p.height <= this.height) return super.escapePath(p); else return new Fail(); } } class Room { Door left; Door right; Room(Door left, Door right) { this.left = left; this.right = right; } Path escapePath(Person p) { Path lp = this.left.escapePath(p); if (lp.isOk()) return new Left((Success)lp); else { Path rp = this.right.escapePath(p); if (rp.isOk()) return new Right((Success)rp); else return new Fail(); } } } class Person { String dest; double height; Person(String dest, double height) { this.dest = dest; this.height = height; } boolean isDest(String s) { return this.dest.equals(s); } } // The Factory class helps in writing tests: // new Factory().Example().escapePath(new Person("mars", 1)) class Factory { Factory() { } Room Example() { Door meadow = new Escape("meadow"); Door street = new Escape("street"); Room ms = new Room(meadow, street); Room planets = new Room(new Escape("mars"), new Escape("venus")); return new Room(new Into(ms), new Short(planets, 1)); } }