Catfish.java
上传用户:taztks
上传日期:2022-04-09
资源大小:37k
文件大小:14k
源码类别:

Applet

开发平台:

Java

  1. import java.util.Vector;
  2. /*
  3.  * Created at 11.00 on 26 november 2009
  4.  *
  5.  */
  6. /**
  7.  * Catfish - simulates a catfish - can swim, eat, and consume 
  8.  * energy in the process.
  9.  * 
  10.  * @author Adilbek Khalikhov
  11.  *
  12.  */
  13. public class Catfish extends LivingBeing {
  14. /**
  15.  * The catfish is born "alive". 
  16.  * Then it dies, becoming a corpse. 
  17.  */
  18. private static final String ALIVE = "alive";
  19. /**
  20.  * The catfish is born "alive". 
  21.  * Then it dies, becoming a "dead" corpse. 
  22.  */
  23. private static final String DEAD = "dead";
  24. /**
  25.  * Energy needed to swim in a block of time.
  26.  */
  27. private static final int ENERGY_TO_SWIM = 2;
  28. /**
  29.  * debugging level. 
  30.  */
  31. private static final int DEBUG = 0;
  32. /**
  33.  * Energy needed to look for food once.
  34.  */
  35. private static final int ENERGY_TO_LOOK_FOR_FOOD = 1;
  36. /**
  37.  * Energy expended to eat once.
  38.  */
  39. private static final int ENERGY_TO_EAT = 1;
  40. /**
  41.  * Energy gained when a full meal is eaten.
  42.  */
  43. private static final int ENERGY_IN_A_FULL_MEAL = 10;
  44. /**
  45.  * Energy needed to look for food once.
  46.  */
  47. private static final int ENERGY_TO_LOOK_FOR_PREDATORS = 5;
  48. /**
  49.  * Lowest possible energy needed for a baby to survive. 
  50.  */
  51. private static final int BABY_MIN_ENERGY = 15;
  52. /**
  53.  * Maximum energy that a baby can store. 
  54.  */
  55. private static final int BABY_MAX_ENERGY = 100;
  56. /**
  57.  * For each block of time, the min energy grows by a certain amount
  58.  */
  59. private static final int MIN_ENERGY_GROWTH_INCREMENT = 5;
  60. /**
  61.  * For each block of time, the max energy grows by a certain amount
  62.  */
  63. private static final int MAX_ENERGY_GROWTH_INCREMENT = 10;
  64. /**
  65.  * String constant - used to indicate the direction catfish is facing.
  66.  */
  67. private static final String RIGHT = "right";
  68. /**
  69.  * String constant - used to indicate the direction catfish is facing.
  70.  */
  71. private static final String LEFT = "left";
  72. /**
  73.  * String constant - used to indicate the direction catfish is facing.
  74.  */
  75. private static final String UP = "up";
  76. /**
  77.  * String constant - used to indicate the direction catfish is facing.
  78.  */
  79. private static final String DOWN = "down";
  80. /**
  81.  * Name of species
  82.  */
  83. private static final String SPECIES = "Catfish";
  84. /**
  85.  * Row-wise location of the catfish
  86.  */
  87. private int row;
  88. /**
  89.  * Column-wise location of the catfish
  90.  */
  91. private int column;
  92. /**
  93.  * Is the catfish dead or alive?
  94.  */
  95. private String deadOrAlive;
  96. /**
  97.  * If a predator is nearby, the catfish will be alarmed
  98.  */
  99. private boolean alarmed = false;
  100. /**
  101.  * Amount of energy the catfish has.
  102.  */
  103. private int energy;
  104. /**
  105.  * Age expressed as blocks of time lived
  106.  */
  107. private int age = 0;
  108. /**
  109.  * Name of this catfish.
  110.  */
  111. private final String name;
  112. /**
  113.  * The simulation to which this catfish belongs.
  114.  * This is needed so the catfish can send a message 
  115.  * to simulation and ask
  116.  * for prey (or predator) in the neighboring locations. 
  117.  * Prey is food. Food is good!
  118.  */
  119. private Simulation simulation;
  120. /**
  121.  * Minimum energy level needed to survive.
  122.  * The minimum could increase as the individual grows.
  123.  */
  124. private int minEnergy;
  125. /**
  126.  * Maximum energy level that the catfish could carry.
  127.  * The maximum could change as the individual grows.
  128.  */
  129. private int maxEnergy;
  130. /**
  131.  * Which direction am I facing.
  132.  */
  133. private String direction; 
  134. /**
  135.  * 
  136.  * Number of Catfish created
  137.  */
  138. private static int nCatfishCreated = 0; 
  139. /**
  140.  * Constructor. Initialize a catfish to start life at a specified 
  141.  * location with a specified energy. If location is out of bounds,
  142.  * locate the catfish at the nearest edge.
  143.  * 
  144.  * @param initialRow - the row at which the catfish is located
  145.  * @param initialColumn - the column at which the catfish is located
  146.  * @param initialSimulation - the simulation that the catfish belongs to
  147.  */
  148. public Catfish(
  149. int initialRow,
  150. int initialColumn,
  151. Simulation initialSimulation) {
  152. simulation = initialSimulation;
  153. deadOrAlive = ALIVE; 
  154. // Set the Row within bounds
  155. if (initialRow > initialSimulation.getLastRow()) {
  156. row = initialSimulation.getLastRow();
  157. } else if (initialRow < initialSimulation.getFirstRow()) {
  158. row = initialSimulation.getFirstRow();
  159. } else {
  160. row = initialRow;
  161. }
  162. // Set the Column within bounds
  163. if (initialColumn > initialSimulation.getLastColumn()) {
  164. column = initialSimulation.getLastColumn();
  165. } else if (initialColumn < initialSimulation.getFirstColumn()) {
  166. column = initialSimulation.getFirstColumn();
  167. } else {
  168. column = initialColumn;
  169. }
  170. // Set the minEnergy and maxEnergy
  171. minEnergy = BABY_MIN_ENERGY;
  172. maxEnergy = BABY_MAX_ENERGY;
  173. energy =
  174. simulation.getRand().nextInt(maxEnergy - minEnergy) + minEnergy;
  175. age = 0;
  176. name = SPECIES + nCatfishCreated;
  177. direction = RIGHT; // Start by facing east.
  178. ++nCatfishCreated;
  179. }
  180. /**
  181.  * Get the row at which the catfish is located 
  182.  * 
  183.  * @return - the row of the catfish's location. 
  184.  */
  185. public int getRow() {
  186. return row;
  187. }
  188. /**
  189.  * Get the column at which the catfish is located
  190.  * 
  191.  * @return - the column of the catfish's location. 
  192.  */
  193. public int getColumn() {
  194. return column;
  195. }
  196. /**
  197.  * Get the catfish's age
  198.  * 
  199.  * @return the age of the catfish expressed in blocks of time
  200.  */
  201. public int getAge() {
  202. return age;
  203. }
  204. /**
  205.  * Color of the catfish expressed in hex notation.
  206.  * For example, the "green-est" color is "#00FF00",
  207.  * "blue-est" is "#0000FF", the "red-est" is "#FF0000".
  208.  * 
  209.  * @return the rgb color in hex notation. preceded by a pound character '#'
  210.  */
  211. public String getColor() {
  212. return "#FFFFFF"; // default is white.
  213. }
  214. /**
  215.  * Get the name of this catfish
  216.  * 
  217.  * @return the name of the catfish.
  218.  */
  219. public String getName() {
  220. return name;
  221. }
  222. /**
  223.  * Get the minimum energy needed to live.
  224.  * 
  225.  * @return the minimum energy needed for the catfish to live.
  226.  */
  227. private int getMinEnergy() {
  228. return minEnergy;
  229. }
  230. /**
  231.  * get the maximum energy that the catfish can carry.
  232.  * 
  233.  * @return the maximum energy the catfish can carry.
  234.  */
  235. private int getMaxEnergy() {
  236. return maxEnergy;
  237. }
  238. /**
  239.  * Get the energy currently carried by the catfish.
  240.  * 
  241.  * @return current energy level of the organism
  242.  */
  243. public int getEnergy() {
  244. return energy;
  245. }
  246. /**
  247.  * Sets energy level.
  248.  * If new energy level is less than minimum energy level, the organism dies.
  249.  * New energy level is capped at maximum energy level.
  250.  */
  251. private void setEnergy(int newEnergy) {
  252. if (newEnergy < getMinEnergy()) {
  253. energy = newEnergy;
  254. die();
  255. } else if (newEnergy > getMaxEnergy()) {
  256. energy = getMaxEnergy();
  257. } else {
  258. energy = newEnergy;
  259. }
  260. }
  261. /**
  262.  * Die: Change the deadOrAlive to DEAD.
  263.  */
  264. public void die() {
  265. deadOrAlive = DEAD;
  266. }
  267. /**
  268.  * Is the catfish dead?
  269.  * 
  270.  * @return <code>true</code> if dead. <code>false</code>, otherwise.
  271.  */
  272. public boolean isDead() {
  273. return (deadOrAlive == DEAD);
  274. }
  275. /**
  276.  * Get the direction faced by the catfish.
  277.  * 
  278.  * @return the facing direction.
  279.  */
  280. private String getDirection() {
  281. return direction;
  282. }
  283. /** 
  284.  * Is the catfish hungry?
  285.  * 
  286.  * @return True, if hungry. False, otherwise.
  287.  */
  288. private boolean isHungry() {
  289. // Hungry, if current energy level is less than twice the 
  290. // amount needed for survival.
  291. return (getEnergy() < (2 * getMinEnergy()));
  292. }
  293. /**
  294.  * Move the catfish to a new row, if new row is within lake bounds.
  295.  * 
  296.  * @param newRow - the row to move to.
  297.  * @return the row moved to. Lake boundary limits movement. -1, if dead.
  298.  */
  299. private int moveToRow(int newRow) {
  300. if (isDead()) {
  301. return -1;
  302. }
  303. // Keep the new value within lake boundary.
  304. if (newRow > simulation.getLastRow()) {
  305. newRow = simulation.getLastRow();
  306. } else if (newRow < simulation.getFirstRow()) {
  307. newRow = simulation.getFirstRow();
  308. }
  309. // I might face a new direction.
  310. if (newRow < row) {
  311. direction = UP;
  312. } else if (newRow > row) {
  313. direction = DOWN;
  314. }
  315. row = newRow;
  316. return row;
  317. }
  318. /**
  319.  * Move the catfish to a new column, if new column is within lake bounds.
  320.  * 
  321.  * @param newColumn - the column to move to.
  322.  * @return the column moved to. Lake boundary limits movement.
  323.  */
  324. private int moveToColumn(int newColumn) {
  325. if (isDead()) {
  326. return -1;
  327. }
  328. // System.out.println("column = " + column + ", newCOlumn = " + newColumn);
  329. // System.out.flush();
  330. // Keep the new value within lake boundary.
  331. if (newColumn > simulation.getLastColumn()) {
  332. newColumn = simulation.getLastColumn();
  333. } else if (newColumn < simulation.getFirstColumn()) {
  334. newColumn = simulation.getFirstColumn();
  335. }
  336. // I might face a new direction.
  337. if (newColumn < column) {
  338. direction = LEFT;
  339. } else if (newColumn > column) {
  340. direction = RIGHT;
  341. }
  342. column = newColumn;
  343. return column;
  344. }
  345. /**
  346.  * Is the catfish alarmed?
  347.  *
  348.  * @return Is the catfish alarmed?
  349.  **/
  350. public boolean getAlarmed() {
  351. return alarmed;
  352. }
  353. /**
  354.  * Set the catfish's alarmed state
  355.  *
  356.  **/
  357. public void setAlarmed(boolean alarm) {
  358. alarmed = alarm;
  359. }
  360. /**
  361.  * This individual belongs to the Catfish species.
  362.  *  
  363.  * @return The string indicating the species
  364.  */
  365. public String getSpecies() {
  366. return SPECIES;
  367. }
  368. /**
  369.  * Catfish should be displayed as an image.
  370.  * 
  371.  * @return a constant defined in {@link Simulation#IMAGE Simulation} class
  372.  */
  373. public String getDisplayMechanism() {
  374. return Simulation.IMAGE;
  375. }
  376. /**
  377.  * Get the image of the catfish
  378.  * 
  379.  * @return filename of Catfish image
  380.  */
  381. public String getImage() {
  382. if (getDirection() == RIGHT) {
  383. if(getAlarmed()) {
  384. return "/Catfish-red-right.gif";
  385. }
  386. return "/Catfish-right.gif";
  387. }
  388. if (getDirection() == LEFT) {
  389. if(getAlarmed()) {
  390. return "/Catfish-red-left.gif";
  391. }
  392. return "/Catfish-left.gif";
  393. }
  394. if (getDirection() == UP) {
  395. if(getAlarmed()) {
  396. return "/Catfish-red-up.gif";
  397. }
  398. return "/Catfish-up.gif";
  399. }
  400. if (getDirection() == DOWN) {
  401. if(getAlarmed()) {
  402. return "/Catfish-red-down.gif";
  403. }
  404. return "/Catfish-down.gif";
  405. }
  406. return "Catfish-right.gif";
  407. }
  408. /**
  409.  * Look for food in the neighborhood. Consume some energy in the process.
  410.  * 
  411.  * @return a neighboring algae that is food.
  412.  */
  413. private AlgaeColony lookForFoodInNeighborhood() {
  414. int neighborIndex;
  415. // Looking for food consumes energy.
  416. setEnergy(getEnergy() - ENERGY_TO_LOOK_FOR_FOOD);
  417. if (isDead()) {
  418. return null;
  419. }
  420. Vector neighbors =
  421. simulation.getNeighbors(getRow(), getColumn(), 1);
  422. for (neighborIndex = 0;
  423. neighborIndex < neighbors.size();
  424. ++neighborIndex) {
  425. if (neighbors.get(neighborIndex) instanceof AlgaeColony) {
  426. return (AlgaeColony) neighbors.get(neighborIndex);
  427. }
  428. }
  429. return null;
  430. }
  431. /** 
  432.  * Swim to a new location if possible.
  433.  * Consumes some energy.
  434.  */
  435. private void swimIfPossible() {
  436. AlgaeColony food;
  437. if (isDead()) {
  438. return;
  439. }
  440. // If hungry, swim to a location where there is food.
  441. if (isHungry()) {
  442. // Naive swimming - We are not checking if a predator is in the destination.
  443. food = lookForFoodInNeighborhood();
  444. if (food != null) {
  445. // Consume energy to swim. 
  446. setEnergy(getEnergy() - ENERGY_TO_SWIM);
  447. if (isDead()) {
  448. return;
  449. }
  450. if (DEBUG > 50) {
  451. System.out.println(
  452. "moving from (row, col) = ("
  453. + getRow()
  454. + ", "
  455. + getColumn()
  456. + ") to ("
  457. + food.getRow()
  458. + ", "
  459. + food.getColumn()
  460. + ")");
  461. }
  462. moveToRow(food.getRow());
  463. moveToColumn(food.getColumn());
  464. } else {
  465. // Do not swim. Need to conserve energy.
  466. }
  467. return;
  468. } else {
  469. // Consume energy to swim.
  470. setEnergy(getEnergy() - ENERGY_TO_SWIM);
  471. if (isDead()) {
  472. return;
  473. }
  474. // Swim at random in one of four directions.
  475. // Naive swimming - We are not checking if a predator is in the destination.
  476. int direction = simulation.getRand().nextInt(4);
  477. // Swim up.
  478. if (direction == 0) {
  479. moveToRow(getRow() - 1);
  480. }
  481. // Swim down.
  482. if (direction == 1) {
  483. moveToRow(getRow() + 1);
  484. }
  485. // Swim left.
  486. if (direction == 2) {
  487. moveToColumn(getColumn() - 1);
  488. }
  489. // Swim right.
  490. if (direction == 3) {
  491. moveToColumn(getColumn() + 1);
  492. }
  493. }
  494. }
  495. /**
  496.  * Eat food if available.
  497.  *
  498.  */
  499. private void eatIfPossible() {
  500. Vector foodMaybe;
  501. int neighborIndex;
  502. if (isDead()) {
  503. return;
  504. }
  505. foodMaybe = simulation.getNeighbors(getRow(), getColumn(), 0);
  506. for (neighborIndex = 0;
  507. neighborIndex < foodMaybe.size();
  508. ++neighborIndex) {
  509. if (foodMaybe.get(neighborIndex) instanceof AlgaeColony) {
  510. AlgaeColony alg = (AlgaeColony) foodMaybe.get(neighborIndex);
  511. int energyGained = alg.giveUpEnergy(ENERGY_IN_A_FULL_MEAL);
  512. // Spend ENERGY_TO_EAT, irrespective of amount gained.
  513. setEnergy(getEnergy() + energyGained - ENERGY_TO_EAT);
  514. return;
  515. }
  516. }
  517. }
  518. /**
  519.  * Catfish lives its life. It may lose or gain energy.
  520.  */
  521. public void liveALittle() {
  522. if (isDead()) {
  523. return;
  524. }
  525. age = age + 1;
  526. swimIfPossible();
  527. eatIfPossible();
  528. // As I am growing bigger, I need to increase my minEnergy 
  529. // and maxEnergy.
  530. minEnergy = getMinEnergy() + MIN_ENERGY_GROWTH_INCREMENT;
  531. maxEnergy = getMaxEnergy() + MAX_ENERGY_GROWTH_INCREMENT;
  532. alarmedIfNecessary(); 
  533. }
  534. /**
  535.  * become alarmed if necessary.
  536.  *
  537.  */
  538. private void alarmedIfNecessary() {
  539. setAlarmed(findPredator());
  540. }
  541. private boolean findPredator() {
  542. /* Student To Do: Add code to find any predators within 1 block.
  543.  * If a prdator is found, return true, else return false
  544.  */
  545.  
  546. setEnergy(getEnergy()-ENERGY_TO_LOOK_FOR_PREDATORS);
  547. if (isDead()) {
  548. return false;
  549. }
  550. Vector localVector = simulation.getNeighbors(getRow(), getColumn(), 1);
  551. int index=0;
  552. if (index<localVector.size())
  553. {
  554. return localVector.get(index) instanceof Crocodile;
  555. }
  556. return false;
  557. }
  558. }