Untitled

 avatar
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