Untitled
unknown
plain_text
5 months ago
7.2 kB
13
Indexable
package assignment5; import java.awt.Color; import java.io.File; import java.io.FileNotFoundException; import java.util.Objects; import java.util.Scanner; import javax.swing.JFileChooser; import edu.princeton.cs.introcs.StdDraw; /** * A Zombie Simulator! */ public class ZombieSimulator { public static final int X = 0; public static final int Y = 1; private static final String ZOMBIE_TOKEN_VALUE = "Zombie"; private static final Color ZOMBIE_COLOR = new Color(146, 0, 0); private static final Color NONZOMBIE_COLOR = new Color(0, 0, 0); private static final Color TEXT_COLOR = new Color(73, 0, 146); public static final double ENTITY_RADIUS = 0.008; public static final double RANDOM_DELTA_HALF_RANGE = 0.006; /** * Read entities from a file. */ public static void readEntities(Scanner in, boolean[] areZombies, double[][] positions) { for (int i = 0; i < areZombies.length; i++) { String entity = in.next(); areZombies[i] = entity.equals(ZOMBIE_TOKEN_VALUE); positions[i][X] = in.nextDouble(); positions[i][Y] = in.nextDouble(); } } /** * Draw all the entities. Zombies are drawn as ZOMBIE_COLOR filled circles of * radius ENTITY_RADIUS and non-zombies with filled NONZOMBIE_COLOR filled * circles of radius ENTITY_RADIUS). Further, add feedback for nonzombie count * (when ready to do so), and any additional desired drawing features. * * @param areZombies the zombie state of each entity * @param positions the (x,y) position of each entity */ public static void drawEntities(boolean[] areZombies, double[][] positions) { StdDraw.clear(); for (int i = 0; i < areZombies.length; i++) { double x = positions[i][X]; double y = positions[i][Y]; if (areZombies[i]==true) { StdDraw.setPenColor(ZOMBIE_COLOR); } else { StdDraw.setPenColor(NONZOMBIE_COLOR); } StdDraw.filledCircle(x, y, ENTITY_RADIUS); } int notZombieCount = nonzombieCount(areZombies); String ratio = "Ratio: " + notZombieCount + "/" + areZombies.length; StdDraw.text(0.1, 0.9, ratio); StdDraw.show(); } /** * Check if the entity at the given index is touching a zombie. (HINT: You know * the location of the center of each entity and that they all have a radius of * ENTITY_RADIUS. If the circles representing two entities overlap they are * considered to be touching. Consider using the distance formula.) * * @param index the index of the entity to check * @param areZombies the zombie state of each entity * @param positions the (x,y) position of each entity * @return true if the entity at index is touching a zombie, false otherwise */ public static boolean touchingZombie(int index, boolean[] areZombies, double[][] positions) { double x1 = positions[index][X]; //x coordinate of entity at the index double y1 = positions[index][Y]; //y coordinate of entity at the index for (int i = 0; i < areZombies.length; i++) { if (i != index && areZombies[i]) { //!index b/c entity can't be touching itself and turn into a zombie double x2 = positions[i][X]; //zombie x coordinate at i double y2 = positions[i][Y]; //zombie y coordinate at i double distance = Math.sqrt(Math.pow((x2-x1),2) + Math.pow((y2-y1),2)); //distance formula if (distance <= 2 * ENTITY_RADIUS) { return true; //if distance is less than or equal to 2, entity is touching a zombie } } } return false; } /** * Update the areZombies states and positions of all entities (assume Brownian * motion). * * The rules for an update are: * * Each entity should move by a random value between -RANDOM_DELTA_HALF_RANGE * and +RANDOM_DELTA_HALF_RANGE in both the x and the y coordinates. * * Entities should not be able to leave the screen. x and y coordinates should * be kept between [0-1.0] * * If a non-zombie is touching a zombie it should change to a zombie. (HINT: you * need to check all entities. On each one that is NOT a zombie, you can re-use * code you've already written to see if it's "touching" a Zombie and, if so, * change it to a zombie.) * * @param areZombies the zombie state of each entity * @param positions the (x,y) position of each entity */ public static void updateEntities(boolean[] areZombies, double[][] positions) { for (int i = 0; i < areZombies.length; i++) { double dX = (Math.random() * 2 * RANDOM_DELTA_HALF_RANGE) - RANDOM_DELTA_HALF_RANGE; //find random x distance double dY = (Math.random() * 2 * RANDOM_DELTA_HALF_RANGE) - RANDOM_DELTA_HALF_RANGE; //find random y distance double newX = positions[i][X] + dX; //adds it to the original position to find the new x position double newY = positions[i][Y] + dY; //adds it to the original position to find the new y position newX = Math.max(0.0, Math.min(1.0, newX)); //ensure the distance doesn't exceed 0.0 and 1.0 newY = Math.max(0.0, Math.min(1.0, newY)); positions[i][X] = newX; //sets the x coordinate of the entity at the new x position positions[i][Y] = newY; //sets the y coordinate of the entity at the new y position if (!areZombies[i] && touchingZombie(i, areZombies, positions)) { //if the entity is not a zombie and it is touching a zombie areZombies[i] = true; //the entity will become a zombie } } } /** * Return the number of nonzombies remaining */ public static int nonzombieCount(boolean[] areZombies) { int notZombieCount = 0; for (boolean isZombie : areZombies) { if (!isZombie) { notZombieCount++; } } return notZombieCount; } /** * Run the zombie simulation. */ static final int Z = 2; private static void runSimulation(Scanner in) { StdDraw.enableDoubleBuffering(); // reduce unpleasant drawing artifacts, speed things up int N = in.nextInt(); boolean[] areZombies = new boolean [N]; double[][] positions = new double [N][Z]; readEntities(in, areZombies, positions); drawEntities(areZombies, positions); StdDraw.pause(500); while (nonzombieCount(areZombies)>0) //while the nonzombie number is greater than 0 { updateEntities(areZombies, positions); //update the zombie state/positions of all its entities (nonzombies --> zombies) drawEntities(areZombies,positions); //redraw the new positions/ zombie state StdDraw.show(); //show the updated screen } } public static void main(String[] args) throws FileNotFoundException { JFileChooser chooser = new JFileChooser("zombieSims"); chooser.showOpenDialog(null); File f = new File(chooser.getSelectedFile().getPath()); Scanner in = new Scanner(f); //making Scanner with a File runSimulation(in); } }
Editor is loading...
Leave a Comment