// Originally from a Randy Lecture? // [lyn, 9/28/07] // * Added static main() method for running as an application. // * Modified so that every reset() has Goblin make new path. // (similar to BagelTrailWorld making a path of bagels). import java.awt.*; import java.util.*; public class GoblinWorld extends BuggleWorld { Randomizer rand = new Randomizer(5555); public void reset() { // Extend default state initialization to make goblin trail as well. super.reset(); new Goblin(rand).makeTrail(); } public void run () { GoblinFollower spidey = new GoblinFollower(); spidey.tick64(); } public static void main (String[] args) { runAsApplication(new GoblinWorld(), "GoblinWorld"); } } class GoblinFollower extends TickBuggle { public void tick() { followGoblin(); } public void followGoblin() { if (isFacingTrail(Color.green)) { forward(); } else { left(); if (isFacingTrail(Color.green)) { forward(); } else { right(); right(); if (isFacingTrail(Color.green)) { forward(); } else { // I must be right behind him! left(); } } } } public boolean isFacingTrail(Color c) { if (isFacingWall()) { return false; } else { //there is a cell in front of me brushUp(); forward(); if (getCellColor().equals(c)) { backward(); brushDown(); return true; } else { backward(); brushDown(); return false; } } } /* A better way to say the same thing. public boolean isFacingTrail() { if (isFacingWall()) { return false; } else { brushUp(); forward(); boolean result = getCellColor().equals(getColor()); backward(); brushDown(); return result; } } */ } class Goblin extends Buggle { private Randomizer rand; public Goblin (Randomizer r) { super(); rand = r; setColor(Color.green); } // Makes the goblin run away, leaving a green trail behind it. public void makeTrail() { int moves = rand.intBetween(10,50); for (int i = 0; i < moves; i++) { move(); } } public void move() { // The options vector will hold copies of the strings "forward", "left", and "right" // that are possible move options. The number of strings will represent their relative weight. Vector options = new Vector(); if (canMoveForward()) { for (int i = 1; i <= 5; i++) { options.add("forward"); // stuff the ballot box with forward } } if (canMoveLeft()) { options.add("left"); } if (canMoveRight()) { options.add("right"); } if (options.size() > 0) { // If some move is possible // pick one randomly and do it: String chosen = options.get(rand.intBetween(0, options.size()-1)); if (chosen.equals("forward")) { forward(); } else if (chosen.equals("left")) { left(); forward(); } else { right(); forward(); } } } // Returns true if can go forward a step without hitting a wall // or touching a green square on any side but the one we came from. public boolean canMoveForward() { if (isFacingWall()) { return false; } else { brushUp(); forward(); boolean result = noTrailToLeft() && noTrailInFront() && noTrailToRight(); backward(); brushDown(); return result; } } public boolean canMoveLeft() { left(); boolean result = canMoveForward(); right(); return result; } public boolean canMoveRight() { right(); boolean result = canMoveForward(); left(); return result; } // Assume brush is up. Return true if there is a wall or // a cell without green in front. public boolean noTrailInFront() { if (isFacingWall()) { return true; } else { forward(); boolean result = !getCellColor().equals(Color.green); backward(); return result; } } public boolean noTrailToLeft() { left(); boolean result = noTrailInFront(); right(); return result; } public boolean noTrailToRight() { right(); boolean result = noTrailInFront(); left(); return result; } }