// Michael Tartaglia
// 27 November 2002
// Dining Philosophers

// PHILOSOPHERS: this class contains the philosophers' traits,
//         namely the number of helpings wanted, and other 
//         states (thinking, eating, hungry)


public class Philosopher extends Thread {
   private int helpingsWanted;	// number of helpings wanted
   private byte curState,	// current hunger state
   		degreeOfHunger,	// how full philosopher feels
	 	ID,		// name of philosopher
		HUNGRY = 1,
		EATING = -1,
		THINKING = 0;
   private Chopstick left, right;
   private Thread runner;
   private boolean wasServed;
	
   public Philosopher(int n, Chopstick l, Chopstick r) {
      wasServed = false;
      ID = (byte)n;
      left = l; right = r;
      degreeOfHunger = 0; 
      curState = THINKING;
   }

   public void start() {
      runner = new Thread(this);
      runner.start();
   }
	
   public void run() {
      while(true) {
	 if (wasServed) eat();
      }
   }
	
   public byte name() {return ID;}

   public int howHungry() {
      return (int)(Math.random()*100)+1;
   }

   public boolean isHungry() {
      degreeOfHunger--;
      if (degreeOfHunger < 0) {
	 curState = HUNGRY;
	 degreeOfHunger = (byte)(Math.random()*2);
      }
      return (curState == HUNGRY);
   }

   public boolean isEating() {
      return (curState == EATING);
   }

   public boolean wasServed() { return wasServed; }

   public synchronized void served(int helpingsServed) {
      helpingsWanted = helpingsServed;
      wasServed = true;
   }

   private synchronized void eat() {
      if (left.isHeld() || right.isHeld()) {
	 System.out.println("Philosopher #" + ID
			+ " is waiting for a chopstick...");
      }
      while (left.isHeld() || right.isHeld());

      left.pickUp(); right.pickUp();
      curState = EATING;
      System.out.println("Philosopher #" + ID + " is eating!");
      try {runner.sleep(15*helpingsWanted);}
      catch (InterruptedException ie) {}
      helpingsWanted = 0;
      left.putDown(); right.putDown();

      wasServed = false;
      curState = THINKING;
   }

}
