import tester.*; class Person { String dest; double height; String key; Person(String dest, double height, String key) { this.dest = dest; this.height = height; this.key = key; } // to determine whether the person wants to get to `target' boolean isDest(String target) { return this.dest.equals(target); } // to determine whether the person is shorter than `n' feet boolean isShorter(double n) { return this.height < n; } boolean hasKey(String wanted) { return this.key.equals(wanted); } } 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 name; Escape(String name) { this.name = name; } public IPath escapePath(Person player) { if (player.isDest(this.name)) 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 Locked implements IDoor { Room next; String key; Locked(Room next, String key) { this.next = next; this.key = key; } public IPath escapePath(Person player) { if (player.hasKey(this.key)) 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; } // determines how you can reach "dest" through this // room IPath escapePath(Person player) { IPath p1 = this.left.escapePath(player); if (p1.isOk()) return new Left(p1); else { IPath p2 = this.right.escapePath(player); if (p2.isOk()) return new Right(p2); 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 toAlaska = new Escape("Alaska"); IDoor toNorthPole = new Escape("North Pole"); Room northRoom = new Room(toAlaska, toNorthPole); IDoor toRoom = new Into(northRoom); Short littleGate = new Short(northRoom, 5.0); Locked redDoor = new Locked(northRoom, "red"); IDoor meadow = new Escape("meadow"); IDoor street = new Escape("street"); Room ms = new Room(meadow, street); Room planets = new Room(new Escape("mars"),new Escape("venus")); Room maze = new Room(new Into(ms), new Into(planets)); Person annie = new Person("Alaska", 5.1, "red"); Person sandra = new Person("Alaska", 4.8, "green"); Person joe = new Person("Arizona", 5.0, "blue"); Person santa = new Person("North Pole", 5.6, "orange"); Person elmo = new Person("street", 2.0, "yellow"); void tests(Tester t) { t.checkExpect(redDoor.escapePath(annie), new Left(new Success())); t.checkExpect(redDoor.escapePath(sandra), new Fail()); t.checkExpect(redDoor.escapePath(elmo), new Fail()); t.checkExpect(littleGate.escapePath(annie), new Fail()); t.checkExpect(littleGate.escapePath(sandra), new Left(new Success())); t.checkExpect(littleGate.escapePath(elmo), new Fail()); t.checkExpect(toRoom.escapePath(annie), new Left(new Success())); t.checkExpect(toRoom.escapePath(joe), new Fail()); t.checkExpect(toRoom.escapePath(santa), new Right(new Success())); t.checkExpect(new Into(maze).escapePath(elmo), new Left(new Right(new Success()))); t.checkExpect(annie.isShorter(6.0), true); t.checkExpect(annie.isShorter(5.0), false); t.checkExpect(annie.isShorter(5.1), false); t.checkExpect(annie.isDest("Alaska"), true); t.checkExpect(annie.isDest("Arizona"), false); t.checkExpect(annie.hasKey("red"), true); t.checkExpect(annie.hasKey("blue"), false); } }