scg/ch08/FluSimulator

From FANG

Jump to: navigation, search

001 package scg.ch08;
002 
003 import java.util.ArrayList;
004 
005 import fang2.core.Alarm;
006 import fang2.core.Game;
007 import fang2.sprites.StringSprite;
008 
009 public class FluSimulator
010   extends Game
011   implements Alarm {
012   /** Number of neighbors exposed to a contagious villager per day */
013   public static final int EXPOSED_PER_DAY = 3;
014 
015   /** Maximum neighbor visiting distance */
016   public static final int NEIGHBOR_DISTANCE = 3;
017 
018   /** Patients zero are initially ill patients. */
019   public static final int NUMBER_OF_PATIENTS_ZERO = 2;
020 
021   /** The number of individuals in the village */
022   public static final int NUMBER_OF_VILLAGERS = 20;
023 
024   /** Clock seconds per simulated day */
025   public static final double SECONDS_PER_DAY = 1.0;
026 
027   /** Number of days elapsed since the beginning of the simulation. */
028   private int dayCount;
029 
030   /** String sprite assigned to display the day count. */
031   private StringSprite dayCountDisplay;
032 
033   /** The collection of Person representing the village. */
034   private ArrayList<Person> village;
035 
036   /**
037    * Perform a scheduled action: Advance simulation one day into the
038    * future. This method is required to implement the Action interface.
039    */
040   public void act() {
041     spreadInfection();
042     advanceSimulatedTime();
043     // schedule the next update unless the simulation is quiescent
044     if (simulationContinues()) {// schedule a new call in the future
045       scheduleRelative(this, SECONDS_PER_DAY);
046     } else {
047       endgameStatistics();
048     }
049   }
050 
051   /**
052    * Initialize the game: Construct the villagers and put them in the
053    * village. Add the day counting variables.
054    */
055   @Override
056   public void setup() {
057     // how big is each villager (so they all fit in one line)
058     double scale = 1.0 / NUMBER_OF_VILLAGERS;
059 
060     // set aside space for the collection (no Persons yet)
061     village = new ArrayList<Person>();
062 
063     for (int = 0; i < NUMBER_OF_VILLAGERS; ++i{
064       // construct one person
065       Person nextVillager = new Person();
066       nextVillager.setScale(scale);
067       nextVillager.setLocation((i * scale+ (scale / 2)0.5);
068       addSprite(nextVillager);
069 
070       // add one person to village
071       village.add(nextVillager);
072     }
073 
074     dayCount = 1;
075     dayCountDisplay = new StringSprite();
076     dayCountDisplay.setScale(0.1);
077     dayCountDisplay.leftJustify();
078     dayCountDisplay.setLocation(0.20.1);
079     dayCountDisplay.setText("Day #" + Integer.toString(dayCount));
080     addSprite(dayCountDisplay);
081 
082     infectPatientsZero();
083 
084     scheduleRelative(this, SECONDS_PER_DAY);
085   }
086 
087   /**
088    * Advance simulation to the next day. Tell each villager to advance
089    * their health and update the day count.
090    */
091   private void advanceSimulatedTime() {
092     for (int currentVillagerNdx = 0;
093         currentVillagerNdx != village.size()++currentVillagerNdx{
094       Person villager = village.get(currentVillagerNdx);
095 
096       villager.nextDay();
097     }
098     // increment the day count and display it
099     ++dayCount;
100     dayCountDisplay.setText("Day #" + Integer.toString(dayCount));
101   }
102 
103   /**
104    * Are any villagers neither healthy nor dead?
105    *
106    @return  false if all villagers are healthy or dead; true otherwise
107    */
108   private boolean anySick() {
109     boolean sawSick = false;
110 
111     for (int currentVillagerNdx = 0;
112         currentVillagerNdx != village.size()++currentVillagerNdx{
113       Person villager = village.get(currentVillagerNdx);
114       sawSick = sawSick || villager.isSick() ||
115         villager.isContagious() || villager.isRecovering();
116     }
117 
118     return sawSick;
119   }
120 
121   /**
122    * How many villagers are currently dead? Iterate across the village,
123    * counting elements which meet some criteria (isDead() returns true)
124    *
125    @return  the number of dead villagers
126    */
127   private int countOfTheDead() {
128     int numberOfDead = 0;
129 
130     for (int currentVillagerNdx = 0;
131         currentVillagerNdx != village.size()++currentVillagerNdx{
132       Person villager = village.get(currentVillagerNdx);
133 
134       if (villager.isDead()) {
135         ++numberOfDead;
136       }
137     }
138 
139     return numberOfDead;
140   }
141 
142   /**
143    * Display end of game statistics on the screen.
144    */
145   private void endgameStatistics() {
146     StringSprite announcement = new StringSprite();
147     announcement.setLocation(0.50.7);
148     announcement.setColor(getColor("misty rose"));
149     announcement.setText("Dead: " + countOfTheDead() + " of " +
150       NUMBER_OF_VILLAGERS);
151     announcement.setWidth(0.9);
152     addSprite(announcement);
153   }
154 
155   /**
156    * Expose a contagious villager, at contagiousVillagerNdx, to randomly
157    * chosen neighbors.
158    *
159    @param  contagiousVillagerNdx
160    */
161   private void handleContagiousVillager(int contagiousVillagerNdx{
162     for (int numberOfExposed = 0; numberOfExposed != EXPOSED_PER_DAY;
163         ++numberOfExposed{
164       int exposedVillagerNdx = selectNeighbor(contagiousVillagerNdx);
165 
166       if (isValidNdx(exposedVillagerNdx)) {
167         village.get(exposedVillagerNdx).expose();
168       }
169     }
170   }
171 
172   /**
173    * Randomly select and infect initial patients. The same patient <i>
174    * could</i> be selected more than once so initial number of the sick
175    * may be < NUMBER_PATIENTS_ZERO.
176    */
177   private void infectPatientsZero() {
178     for (int sickies = 0; sickies != NUMBER_OF_PATIENTS_ZERO;
179         ++sickies{
180       village.get(randomInt(NUMBER_OF_VILLAGERS)).makeSick();
181     }
182   }
183 
184   /**
185    * Is ndx a valid index into the village?
186    *
187    @param   ndx  the index to check
188    *
189    @return  true if the index is valid index into village collection;
190    *          false otherwise.
191    */
192   private boolean isValidNdx(int ndx{
193     return (<= ndx&& (ndx < village.size());
194   }
195 
196   /**
197    * Select a neighbor of the villager at currNdx. Returned value will
198    * be within NEIGHBOR_DISTANCE of currNdx.
199    *
200    @param   currentVillagerNdx  the index of the villager for whom we
201    *                              must select a neighbor
202    *
203    @return  an "index" of a neighbor; index in quotes as it might be
204    *          outside the legal range for village
205    */
206   private int selectNeighbor(int currentVillagerNdx{
207     int neighborNdx;
208     neighborNdx = currentVillagerNdx +
209       randomInt(-NEIGHBOR_DISTANCE, NEIGHBOR_DISTANCE);
210 
211     return neighborNdx;
212   }
213 
214   /**
215    * Does the simulation need to keep running?
216    *
217    @return  true if someone's health will change spontaneously; false
218    *          otherwise
219    */
220   private boolean simulationContinues() {
221     return anySick();
222   }
223 
224   /**
225    * Cycle across the village, exposing any contagious villagers to
226    * their neighbors.
227    */
228   private void spreadInfection() {
229     for (int currentVillagerNdx = 0;
230         currentVillagerNdx != village.size()++currentVillagerNdx{
231       Person villager = village.get(currentVillagerNdx);
232       if (villager.isContagious()) {
233         handleContagiousVillager(currentVillagerNdx);
234       }
235     }
236   }
237 }
238 
239 //Uploaded on Mon Mar 29 21:39:14 EDT 2010


Download/View scg/ch08/FluSimulator.java





Views
Personal tools
Add to 
del.icio.usAdd to 
diggAdd to 
FacebookAdd to 
favoritesAdd to 
GoogleAdd to 
MySpaceAdd to 
PrintAdd to 
SlashdotAdd to 
StumbleUponAdd to 
Twitter

Games
Games