Untitled

 avatar
unknown
plain_text
5 months ago
6.7 kB
6
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;

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) {
		int i = 0;
	    while (in.hasNext()) {
	        String entityType = in.next(); // Read "Zombie" or "NonZombie"
	        double x = in.nextDouble();    // Read the x-coordinate
	        double y = in.nextDouble();    // Read the y-coordinate

	        areZombies[i] = Objects.equals(entityType, ZOMBIE_TOKEN_VALUE);
	        positions[i][X] = x;
	        positions[i][Y] = y;
	        i++;
	    }
	}

	/**
	 * 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++) {
	        if (areZombies[i]) {
	            StdDraw.setPenColor(ZOMBIE_COLOR);
	        } else {
	            StdDraw.setPenColor(NONZOMBIE_COLOR);
	        }
	        StdDraw.filledCircle(positions[i][X], positions[i][Y], ENTITY_RADIUS);
	    }
		// TODO: Write the loop that displays all the entities 

		

		// DONE: Show everything that was drawn (show the updated frame). This should be
		// the only "show()" command!
		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) {
		// TODO: Complete this method
	    for (int i = 0; i < areZombies.length; i++) {
	        if (areZombies[i] && i != index) { // Check only if the other entity is a zombie
	            double dx = positions[index][X] - positions[i][X];
	            double dy = positions[index][Y] - positions[i][Y];
	            double distance = Math.sqrt(dx * dx + dy * dy);
	            if (distance <= 2 * ENTITY_RADIUS) {
	                return true; // Touching a zombie
	            }
	        }
	    }
		return false; // FIXME: Replace this so it returns the value of interest
	}

	/**
	 * 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) {
		// TODO: Complete this method: It should update the positions of items in the
		// entities array
		for (int i = 0; i < areZombies.length; i++) {
	        // Brownian motion: random change in position
	        double deltaX = Math.random() * 2 * RANDOM_DELTA_HALF_RANGE - RANDOM_DELTA_HALF_RANGE;
	        double deltaY = Math.random() * 2 * RANDOM_DELTA_HALF_RANGE - RANDOM_DELTA_HALF_RANGE;
	        
	        // Update position within bounds
	        positions[i][X] = Math.min(1.0, Math.max(0.0, positions[i][X] + deltaX));
	        positions[i][Y] = Math.min(1.0, Math.max(0.0, positions[i][Y] + deltaY));

	        // If non-zombie, check if it's touching a zombie
	        if (!areZombies[i] && touchingZombie(i, areZombies, positions)) {
	            areZombies[i] = true; // Become a zombie
	        }
		}
	}
	//Return the number of nonzombies remaining
	public static int nonzombieCount(boolean[] areZombies) {
	    int count = 0;
	    for (boolean isZombie : areZombies) {
	        if (!isZombie) {
	            count++;
	        }
	    }
	    return count;
	}
	// TODO: Change TodoReplaceWithCorrectReturnType to appropriate return type.
	// TODO: Change TodoReplaceWithCorrectParameterType to appropriate parameter type.
	// TODO: Rename todoRenameMe.
	// public static TodoReplaceWithCorrectReturnType nonzombieCount(TodoReplaceWithCorrectParameterType todoRenameMe) {
	//     TODO: complete this method
	// }

	
	//Run the zombie simulation.
	private static void runSimulation(Scanner in) {
		StdDraw.enableDoubleBuffering(); // reduce unpleasant drawing artifacts, speed things up
		int N = in.nextInt(); // Assume the first value is the number of entities
		boolean[] areZombies = new boolean[N];
		double[][] positions = new double[N][2];
		    
		readEntities(in, areZombies, positions);
		drawEntities(areZombies, positions);
		
		StdDraw.pause(500);
		while (nonzombieCount(areZombies) > 0) {
			updateEntities(areZombies, positions);
			drawEntities(areZombies, positions);
			StdDraw.pause(100); // Slow down the simulation slightly
		    }	
	}

	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