import tester.*; class Person { String dest; // where the person wants to go double height; // person's height in inches Person(String dest, double height) { this.dest = dest; this.height = height; } boolean isDest(String place) { return this.dest.equals(place); } boolean isShorter(double h) { return this.height <= h; } } interface IDoor { IPath escapePath(Person player); } class Into implements IDoor { Room next; Into(Room next) { this.next = next; } public IPath escapePath(Person player) { return this.next.escapePath(player); } } class Escape implements IDoor { String place; Escape(String place) { this.place = place; } public IPath escapePath(Person player) { if (player.isDest(this.place)) return new Success(); else return new Fail(); } } class Short implements IDoor { Room next; double height; Short(Room next, double height) { this.next = next; this.height = height; } public IPath escapePath(Person player) { if (player.isShorter(this.height)) return this.next.escapePath(player); else return new Fail(); } } class Room { IDoor left; IDoor right; Room(IDoor left, IDoor right) { this.left = left; this.right = right; } IPath escapePath(Person player) { IPath rpath = this.right.escapePath(player); IPath lpath = this.left.escapePath(player); if (rpath.isOk()) return new Right(rpath); else if (lpath.isOk()) return new Left(lpath); else return new Fail(); } } interface IPath { boolean isOk(); } class Fail implements IPath { Fail() { } public boolean isOk() { return false; } } class Success implements IPath { Success() { } public boolean isOk() { return true; } } class Right implements IPath { IPath rest; Right(IPath rest) { this.rest = rest; } public boolean isOk() { return true; } } class Left implements IPath { IPath rest; Left(IPath rest) { this.rest = rest; } public boolean isOk() { return true; } } class Examples { IDoor mars = new Escape("mars"); IDoor venus = new Escape("venus"); Room planetsRoom = new Room(mars, venus); IDoor planets = new Into(planetsRoom); Room slcOrSpaceRoom = new Room(new Escape("Salt Lake City"), planets); IDoor slcOrSpace = new Into(slcOrSpaceRoom); Fail fail = new Fail(); Success success = new Success(); Person joe = new Person("junk", 80.0); Person martian = new Person("mars", 45.0); Person venutian = new Person("venus", 60.0); Person tallVenutian = new Person("venus", 61.0); Person matthias = new Person("Salt Lake City", 70.0); IDoor fiveFoot = new Short(planetsRoom, 60.0); void tests(Tester t) { t.checkExpect(mars.escapePath(joe), fail); t.checkExpect(mars.escapePath(martian), success); t.checkExpect(planets.escapePath(joe), fail); t.checkExpect(planets.escapePath(venutian), new Right(success)); t.checkExpect(slcOrSpace.escapePath(matthias), new Left(success)); t.checkExpect(slcOrSpace.escapePath(martian), new Right(new Left(success))); t.checkExpect(fiveFoot.escapePath(martian), new Left(success)); t.checkExpect(fiveFoot.escapePath(venutian), new Right(success)); t.checkExpect(fiveFoot.escapePath(tallVenutian), fail); t.checkExpect(planetsRoom.escapePath(joe), fail); t.checkExpect(planetsRoom.escapePath(martian), new Left(success)); t.checkExpect(joe.isDest("mars"), false); t.checkExpect(joe.isDest("junk"), true); t.checkExpect(joe.isShorter(70.0), false); t.checkExpect(joe.isShorter(90.0), true); t.checkExpect(joe.isShorter(80.0), true); } }