// Author: benson limketkai // Date: May 22, 2007 // Modified: June 3, 2008 import java.util.*; import java.awt.*; public class World { // grid dimensions private int width, height; // coordinates of the extreme points private int minX, minY; private int maxX, maxY; // for drawing private DrawingPanel panel; private int panelWidth, panelHeight; private static final int CELL_SIZE = 40; private static final int WORLD_SIZE = 10; public World(int width, int height) { this.width = width; this.height = height; minX = -(width / 2); minY = -(height / 2); maxX = (width + 1) / 2; // +1 rounds up if necessary maxY = (height + 1)/ 2; panelWidth = width * CELL_SIZE; panelHeight = height * CELL_SIZE; panel = new DrawingPanel(panelWidth, panelHeight); } ///////////////////////////////////////////////////////// // accessors ///////////////////////////////////////////////////////// public int getWidth() { return width; } public int getHeight() { return height; } public int getMinX() { return minX; } public int getMinY() { return minY; } public int getMaxX() { return maxX; } public int getMaxY() { return maxY; } ///////////////////////////////////////////////////////// public static void main(String[] args) { World grid = new World(WORLD_SIZE, WORLD_SIZE); Scanner console = new Scanner(System.in); Robot bot = new Robot(grid); // continually ask for moves while (true) { // draws the grid with the robot grid.draw(bot); System.out.print("Move? "); boolean isInt = false; int numSteps = 0; String move = ""; if (console.hasNextInt()) { isInt = true; numSteps = console.nextInt(); } else { move = console.next(); } // process move (valid integers move robot forward) if (isInt && numSteps < 5 && numSteps > 0) { bot.move(numSteps); } else if (move.equals("left")) { bot.turn(false); } else if (move.equals("right")) { bot.turn(true); } else if (move.equals("quit")) { System.exit(0); } else { System.out.println("Huh? Your choices are \"left\", \"right\", or a number greater than 0 but less than 5."); } } } // draws the grid with the robot public void draw(Robot bot) { Graphics g = panel.getGraphics(); // clear screen g.setColor(Color.WHITE); g.fillRect(0, 0, panelWidth, panelHeight); // draw grid g.setColor(Color.BLACK); // draw vertical lines for (int i = 0; i < width; i++) { int panelX = i * CELL_SIZE; g.drawLine(panelX, 0, panelX, panelHeight); } // draw horizontal lines for (int i = 0; i < height; i++) { int panelY = i * CELL_SIZE; g.drawLine(0, panelY, panelWidth, panelY); } // tell the robot to draw itself, passing this grid as a parameter, // so it can call the grid's methods to draw lines; these methods // take in grid coordinates and draws them appropriately on the // drawing panel; the robot does not ever have to know what world // coordinates are (now that's abstraction!) bot.draw(this); } // converts a point from grid coordinates to world (i.e. panel) coordinates private Point grid2world(double x, double y) { int worldX = (int)((x - minX) * CELL_SIZE); int worldY = panelHeight - (int)((y - minY) * CELL_SIZE); return new Point(worldX, worldY); } // draw a line with a given thickness -- essentially a quadrilateral; // parameters are given in grid coordinates; all computations of the // four points of the quadrilateral are done in grid coordinates before // final conversion to world coordinates for drawing public void drawLine(double x1, double y1, double x2, double y2, double thickness) { // a two-dimensional array! double[][] points = new double[2][2]; points[0][0] = x1; points[0][1] = y1; points[1][0] = x2; points[1][1] = y2; double width = thickness / 2; // go out perpendicularly from each endpoint double angle = Math.atan2(y2 - y1, x2 - x1); double[] angles = new double[2]; angles[0] = angle + Math.toRadians(90); angles[1] = angle + Math.toRadians(-90); // how far to go out from each endpoint double[][] deltas = new double[2][2]; for (int i = 0; i < deltas.length; i++) { deltas[i][0] = width * Math.cos(angles[i]); deltas[i][1] = width * Math.sin(angles[i]); } // the coordinates of the four points of the quadrilateral double[][] coords = new double[4][2]; for (int i = 0; i < coords.length; i++) { for (int j = 0; j < coords[i].length; j++) { coords[i][j] = points[i/2][j] + deltas[((i+1)%4)/2][j]; } } // convert to world coordinates Point[] worldPoints = new Point[4]; for (int i = 0; i < worldPoints.length; i++) { worldPoints[i] = grid2world(coords[i][0], coords[i][1]); } // draw polygon (line with thickness) Polygon p = new Polygon(); for (int i = 0; i < worldPoints.length; i++) { p.addPoint((int)worldPoints[i].getX(), (int)worldPoints[i].getY()); } panel.getGraphics().fillPolygon(p); } public void setColor(Color c) { panel.getGraphics().setColor(c); } // fill an circle using (x,y) as the center // parameters are given in grid coordinates public void fillCircle(double x, double y, double r) { Point worldPoint = grid2world(x, y); int worldX = (int)worldPoint.getX(); int worldY = (int)worldPoint.getY(); int radius = (int)(r * CELL_SIZE); panel.getGraphics().fillOval(worldX - radius, worldY - radius, radius * 2, radius * 2); } }