// Example of divide-conquer-and-glue problem solving with buggles. // Works for any grid size >= 24. // For odd numbers less than 23, will end up trying to place bagels // into cells already occupied by bagels or will run into a wall. // For even numbers between 16 and 22, will give an interesting pattern // due to forward and backward being defined on negative numbers. // For even numbers less than 14, will run into wall. import java.awt.*; // Need this to refer to Colors // A subclass of BuggleWorld that can also be run as an application public class SpiralsWorld extends BuggleWorld { protected ParameterFrame params; int initialSide = 27; public void setup () { params = new ParameterFrame("SpiralsWorldParams", 200, 150, new String [] {"side"}, new String [] {}); params.setIntParam("side", initialSide); params.show(); setDimensions(initialSide,initialSide); } public void run() { SpiralBuggle spiro = new SpiralBuggle(); spiro.allSpirals(params.getIntParam("side")); } public void reset() { int side = params.getIntParam("side"); if (side <= 0) { throw new BuggleException ("side must be greater than 0: " + side); } setDimensions(side,side); super.reset(); } //------------------------------------------------------------------------------ // The following main method is needed to run the applet as an application public static void main (String[] args) { runAsApplication(new SpiralsWorld(), "SpiralsWorld"); } } class SpiralBuggle extends Buggle { // Assume brushDown is true. // Draw the spirals picture in a side x side grid // Afterwards, the buggle is in the same state that it started. public void allSpirals (int side) { threeSpirals(side-3, Color.red, Color.blue, Color.yellow); nextCorner(side); threeSpirals(side-3, Color.blue, Color.yellow, Color.cyan); nextCorner(side); threeSpirals(side-3, Color.yellow, Color.cyan, Color.red); nextCorner(side); threeSpirals(side-3, Color.cyan, Color.red, Color.blue); nextCorner(side); } // Move from one corner to the next corner of an nxn grid public void nextCorner (int n) { brushUp(); forward(n-1); left(); brushDown(); } // Assume brushDown is true. // Draw three nested spirals. // The outer (largest) one has n cells in its largest line and has color c1. // The middle one has n-2 cells in its largest line and has color c2. // The inner one has n-4 cells in its largest line and has color c3. // Afterwards, the buggle is in the same state that it started. public void threeSpirals (int n, Color c1, Color c2, Color c3) { spiral(c1, n); moveIn(); spiral(c2, n-2); moveIn(); spiral(c3, n-4); moveOut(); moveOut(); } // Assume brushDown is true. // Draw one spiral consisting of four bagel-terminated lines in color c. // The largest line in the spiral covers n cells. // Afterwards, the buggle is in the same state that it started. public void spiral (Color c, int n) { setColor(c); line(n); line(n-3); line(n-9); line(n-15); unline(n-15); unline(n-9); unline(n-3); unline(n); } // Assume brushDown is true. // Draw a bagel-terminated line covering i cells and turn left. public void line (int i) { forward(i-1); dropBagel(); setCellColor(getColor()); // Color last cell left(); } // Undo the movements of line(i) public void unline (int i) { right(); backward(i-1); } // Move in by (1,1) with brushUp public void moveIn () { // Alternative implementation: // moveBy(1,1); brushUp(); forward(); left(); forward(); right(); brushDown(); } // Move out by (-1,-1) with brushUp public void moveOut () { // Alternative implementation: // moveBy(-1,-1); brushUp(); left(); backward(); right(); backward(); brushDown(); } /********************************************************************** // THIS IS A BUGGY IMPLEMENTATION THAT DOES NOT WORK // IF THIS BUGGLE ISN'T FACING EAST! // An alternative implementation public void moveBy (int x, int y) { Location loc = getPosition(); setPosition(new Location(loc.x + x, loc.y + y)); } **********************************************************************/ // THIS IS A CORRECT IMPLEMENTATION THAT WORKS FOR ANY DIRECTION // An alternative implementation public void moveBy (int x, int y) { Location loc = getPosition(); Direction dir = getHeading(); // Create a vector for a move one unit forward and one unit to the left: Location delta = dir.toLocation().add(dir.left().toLocation()); // Change the current location by delta scaled by (x,y) setPosition(new Location(loc.x + x*delta.x, loc.y + y*delta.y)); } }