Solved

Java question - sleep while no command (threads needed)

Posted on 2006-11-04
16
169 Views
Last Modified: 2010-03-31
Hello,

I am making a program to demonstrate artificial intelligence.

-To do this I am modelling a pet that can be fed, exercised etc.
-These variables are updated each time a user enters a feed command or exercsie command etc (also boredom, energy and energy volatility variables) or when the user leaves the pet, the variables go down e.g. if no excercise or other variables after a certain amount of time it dies.

The problem is this: It does not automaticlly decrement the variables when its left alone i.e. no commands issued.

Feel free to download and compile if it helps you help me.

Its getting there - at the moment it takes a command, sleeps until the next command, but then it crashes - null exception.

[code]
import java.util.*;

/**
 * Desktop   set path="C:\Program Files\Java\jdk1.5.0_08\bin"
 * Laptop    set path="E:\Program Files\Java\jdk1.5.0_08\bin"
 *
 *
**/

public class AIPet
{
      public int exercise = 90; // Initialise variable to 90%
      public int food = 90; // Initialise variable to 90%
      public int boredom = 90; // Initialise variable to 90%
      public int energy = 50; // Initialise variable to 50%
      public double randomControl = ((exercise + food + boredom) / 3);
      public int volatility = 0;
      public boolean male = true;
      public long goToSleep = 0;

      public String start()
      {
            System.out.println();
            System.out.println();
            System.out.println("Welcome to my AI Pet Demonstration");
            System.out.println("==================================");
            System.out.println("The aim is to keep the pet satisfied");
            System.out.println("i.e. keep all levels (food, exercise and");
            System.out.println("boredom) above 70% and make sure that");
            System.out.println("energy is never less than 1 (no energy");
            System.out.println("for body to function) or more than 100");
            System.out.println("(over exertion).");
            System.out.println("WIN = GETTING ALL LEVELS TO 100%");
            System.out.println();
            System.out.println("COMMANDS (one or two can be issued at once)");
            System.out.println("===========================================");
            System.out.println("Make the pet to exercise,  command = exercise");
            System.out.println("Feed the pet,              command = feed");
            System.out.println("Make the pet more excited, command = excite");
            System.out.println("Exercise and feed,         command = exercise feed");
            System.out.println("Exercise and excite,       command = exercise excite");
            System.out.println("Feed and excite,           command = feed excite");
            System.out.println("Exit,                      command = exit");
            System.out.println();
            System.out.println("NOTES");
            System.out.println("=====");
            System.out.println("Allowing the pet to exercise will make");
            System.out.println("it more fit but more hungry.");
            System.out.println("----------------------------------");
            System.out.println("Feeding the pet will make it less");
            System.out.println("hungry but will also make it bored");
            System.out.println("as it as more energy.");
            System.out.println("----------------------------------");
            System.out.println("Exciting the pet will make it more hungry");
            System.out.println("and fit as it has used energy.");
            System.out.println();
            System.out.println("----------------------------------");
            System.out.println("WARNING - Double commands may create energy imbalance");
            System.out.println("e.g. feeding the pet while exercising the pet will make");
            System.out.println("energy levels more volatile and increase chance of death.");
            System.out.println();
            System.out.println("----------------------------------");
            System.out.println("Choose if you want your pet animal to be");
            System.out.println("male (less excitement needed) or female");
            System.out.println("(does not need so much food).");
            System.out.println("Type male or female.");
            System.out.println();

            Scanner scan = new Scanner(System.in);
            String sex = scan.nextLine();

            if(sex.equals("male"))
            {
                  System.out.println("You choose male");
                  System.out.println();
                  System.out.println("Exercise at:   90");
                  System.out.println("Food at:       90");
                  System.out.println("Boredom at:    90");
                  System.out.println();
                  System.out.println("Energy at:     50");
                  System.out.println("Volatility at:  0");
                  System.out.println();

                  male("yes");
                  male = true;
            }
            else if(sex.equals("female"))
            {
                  System.out.println("You choose female");
                  System.out.println();
                  System.out.println("Exercise at:   90");
                  System.out.println("Food at:       90");
                  System.out.println("Boredom at:    90");
                  System.out.println();
                  System.out.println("Energy at:     50");
                  System.out.println("Volatility at:  0");
                  System.out.println();

                  female("yes");
                  male = false;
            }
            else
            {
                  System.out.println("Restart the program and then choose if you want the pet animal to be male or female.");
            }

            return null;
      }

      public String male(String male)
      {
            Scanner command = new Scanner(System.in);
            String commandIssued = command.nextLine();

            if(male.equals("yes"))
            {
                  goToSleep = System.currentTimeMillis() + 9000;

                  if(commandIssued.equals("exercise"))
                  {
                        exercised("exercise");
                  }
                  else if(commandIssued.equals("feed"))
                  {
                        feeding("fed", "male");
                  }
                  else if(commandIssued.equals("excite"))
                  {
                        excite("excite", "male");
                  }
                  else if(commandIssued.equals("exercise feed"))
                  {
                        volatility++;
                        exercised("exercise");
                        feeding("fed", "male");
                  }
                  else if(commandIssued.equals("exercise excite"))
                  {
                        volatility++;
                        exercised("exercise");
                        excite("excite", "male");
                  }
                  else if(commandIssued.equals("feed excite"))
                  {
                        volatility++;
                        feeding("fed", "male");
                        excite("excite", "male");
                  }
                  else if(commandIssued.equals("exit"))
                  {
                        System.exit(1);
                  }
            }

            return null;
      }

      public String female(String female)
      {
            Scanner command = new Scanner(System.in);
            String commandIssued = command.nextLine();

            if(female.equals("yes"))
            {
                  goToSleep = System.currentTimeMillis() + 9000;

                  if(commandIssued.equals("exercise"))
                  {
                        exercised("exercise");
                  }
                  else if(commandIssued.equals("feed"))
                  {
                        feeding("fed", "female");
                  }
                  else if(commandIssued.equals("excite"))
                  {
                        excite("excite", "female");
                  }
                  else if(commandIssued.equals("exercise feed"))
                  {
                        volatility++;
                        exercised("exercise");
                        feeding("fed", "female");
                  }
                  else if(commandIssued.equals("exercise excite"))
                  {
                        volatility++;
                        exercised("exercise");
                        excite("excite", "female");
                  }
                  else if(commandIssued.equals("feed excite"))
                  {
                        volatility++;
                        feeding("fed", "female");
                        excite("excite", "female");
                  }
                  else if(commandIssued.equals("exit"))
                  {
                        System.exit(1);
                  }
            }

            return null;
      }

      public void exercised(String exercised)
      {
            if(exercised.equals("exercise"))
            {
                  food--;
                  exercise++;

                  energy(exercise, food, boredom, energy, "yes");
                  display(exercise, food, boredom, energy, volatility);
            }
            else
            {
                  exercise--;
            }
      }

      public void feeding(String feed, String sex)
      {
            if(feed.equals("fed"))
            {
                  if(sex.equals("male"))
                  {
                        boredom = boredom + 2;
                  }

                  food++;
                  boredom--;

                  energy(exercise, food, boredom, energy, "yes");
                  display(exercise, food, boredom, energy, volatility);
            }
            else
            {
                  food--;
            }
      }

      public void excite(String excite, String sex)
      {
            if(excite.equals("excite"))
            {
                  exercise++;
                  food--;

                  if(sex.equals("female"))
                  {
                        food = food + 2;
                  }
                  else
                  {
                        boredom++;
                  }

                  energy(exercise, food, boredom, energy, "yes");
                  display(exercise, food, boredom, energy, volatility);
            }
            else
            {
                  boredom--;
            }
      }

      public void energy(int exercise, int food, int boredom, int energy, String energyChange)
      {
            int randomControl2 = (int)randomControl;

            if(energyChange.equals("yes"))
            {
                  if(volatility > 0)
                  {
                        Random random = new Random();//Second double command + 2 * 2 = 4 therefore higher random
                        energy = random.nextInt(randomControl2 + ((volatility * volatility)) + volatility);

                        display(exercise, food, boredom, energy, volatility);
                  }
                  else
                  {
                        Random random = new Random();
                        energy = random.nextInt(randomControl2) + volatility;

                        display(exercise, food, boredom, energy, volatility);
                  }
            }
      }

      public void display(int exercise, int food, int boredom, int energy, int volatility)
      {
            if(exercise >= 100)
            {
                  exercise = 100;
            }

            if(food >= 100)
            {
                  food = 100;
            }

            if(boredom >= 100)
            {
                  boredom = 100;
            }

            if(exercise < 70)
            {
                  System.out.println("Your pet died through lack of exercise.");
                  System.exit(1);
            }

            if(food < 70)
            {
                  System.out.println("Your pet died through lack of food.");
                  System.exit(1);
            }

            if(boredom < 70)
            {
                  System.out.println("Your pet died through lack of excitement.");
                  System.exit(1);
            }

            if(energy > 100)
            {
                  System.out.println("Your pet died from over excertion.");
                  System.exit(1);
            }

            if(energy < 0)
            {
                  System.out.println("Your pet died from lack of energy.");
                  System.exit(1);
            }

            System.out.println();
            System.out.println("Exercise at:    " + exercise);
            System.out.println("Food at:        " + food);
            System.out.println("Boredom at:     " + boredom);
            System.out.println("-----------------");
            System.out.println("Energy at:      " + energy);
            System.out.println("Volatility at:  " + volatility);
            System.out.println();
            System.out.println();

            System.out.print("Sleeping");

            for(int i = 0; i < 6; i++)
            {
                  System.out.print(".");

                  try
                  {
                        Thread.sleep(200);
                  }
                  catch(Exception e)
                  {
                        System.err.println("Caught Exception: " + e.getMessage());
                  }
            }

            System.out.println();
            System.out.println();

            backgroundThread.start(); //start after first input e.g. feed

            if(male == true)
            {
                  male("yes");
            }

            if(male == false)
            {
                  female("yes");
            }
      }

      private void sleep()
      {
            while(true)
            {
                  long timeLeft = goToSleep - System.currentTimeMillis(); // time left before next action

                  if(timeLeft <= 0)
                  {
                        break; // surely this needs to be a method call i.e. if no action in given time go back to display

                        //display(exercise, food, boredom, energy, volatility);
                  }

                  try
                  {
                        Thread.sleep(timeLeft);

                        System.out.println(timeLeft);

                        display(exercise, food, boredom, energy, volatility);
                  }
                  catch(Exception e)
                  {
                        System.err.println("Caught Exception: " + e.getMessage());
                  }

                  // OK, timer expired at this point so go to sleep.
            }
      }

      Thread backgroundThread = new Thread(new Runnable()
      {
            public void run()
            {
               sleep();
            }
      });

      public static void main(String[] args)
      {
            AIPet pet = new AIPet();
            pet.start();
      }
}
[/code]

If you can help I would be very happy

Thank you

John
0
Comment
Question by:john8932
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 7
16 Comments
 
LVL 6

Expert Comment

by:valipotor
ID: 17875729
What is the purpose of:

 for(int i = 0; i < 6; i++)
          {
               System.out.print(".");

               try
               {
                    Thread.sleep(200);
               }
               catch(Exception e)
               {
                    System.err.println("Caught Exception: " + e.getMessage());
               }
          }

an then

backgroundThread.start(); //start after first input e.g. feed

So sleep and then sleep again?
0
 

Author Comment

by:john8932
ID: 17876058
This is just a fancy way of displaying its sleeping i.e. sleeping. then next iteration sleeping.. then sleeping... and so on.

This is repeated every 9 seconds if no input, or should be anyway.

Cheers
0
 
LVL 6

Expert Comment

by:valipotor
ID: 17876071
In my opinion you should:

- start a thread that
 - sleeps for a second
 - prints Sleeping ....
 - checks if the vars were modified (if (modified==true) )
       - if yes, go back to sleep, set modified=false;
       - if no, decrement the variables by the required values

and the main thread should
- wait for input
- process any command
- update a flag, saying that the vars were modified
        modified=true;

Hope this helps,

valipotor
0
Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

 

Author Comment

by:john8932
ID: 17876087
Ok cool but why for one second?

So I move the sleeping... into the thread then.

And the boolean variable is a good idea.

Ill try and code this - if it does not work ill post it up again, but a shortened version.

Thanks
0
 

Author Comment

by:john8932
ID: 17876111
I am having trouble implementing your idea.

Was this what you were suggesting:

          backgroundThread.start(); //start after first input e.g. feed

          if(male == true)
              {
                     male("yes");
              }

              if(male == false)
              {
                     female("yes");
          }
    }

     private void sleep()
     {
          if(modified == true)
          {
                        try
                        {
                               Thread.sleep(1000);

                               System.out.print("Sleeping");

                               for(int i = 0; i < 6; i++)
                               {
                                     System.out.print(".");
                               }
                               try
                               {
                                     Thread.sleep(200);
                               }
                               catch(Exception e)
                               {
                                     System.err.println("Caught Exception: " + e.getMessage());
                               }

                               modified = false;
                     }
                     catch(Exception e)
                     {
                                 System.err.println("Caught Exception: " + e.getMessage());
                     }
          }
          else
          {
                    exercise--;
                    food--;
                    boredom--;
              }
     }

     Thread backgroundThread = new Thread(new Runnable()
     {
          public void run()
          {
             sleep();
          }
     });

     public static void main(String[] args)
     {
          AIPet pet = new AIPet();
          pet.start();
     }
}

Please change this if it is not right.
0
 
LVL 6

Expert Comment

by:valipotor
ID: 17876154
  private void sleep()
     {
                    try
                    {
                          Thread.sleep(1000);

                          System.out.print("Sleeping");
          if(modified == false)
          {
                 exercise--;
                 food--;
                 boredom--;
         }

                          modified = false;
                  }
                  catch(Exception e)
                  {
                            System.err.println("Caught Exception: " + e.getMessage());
                  }
          }
0
 

Author Comment

by:john8932
ID: 17876796
Its not working at the moment but I think I know why.

Where do you think I should use this code?

modified = true;

In the variable methods e.g. excite or exercised or in the female and male methods?

Also I think at the moment I am starting this thread twice with:

backgroundThread.start();

Therefore where should this go?

Thanks for the help so far
0
 
LVL 6

Expert Comment

by:valipotor
ID: 17877108
In the variable methods e.g. excite or exercised ...
0
 

Author Comment

by:john8932
ID: 17877152
Were you repeating this because you did not understand - it means do I put the modified = true in the exercised or excite type methods i.e. the methods that change variables once a command is input.

or did you mean this is the correct way?
0
 
LVL 6

Expert Comment

by:valipotor
ID: 17877283
Yes, you need to put the modified=true wherw you change the variables, in the exercise, feed ... methods.
0
 

Author Comment

by:john8932
ID: 17877382
Okay thats been done.

I think the background method is starting more than once at a time therefore an illegalthreadstate esception occurs at runtime.

Maybe I should put the thread method call in the start method so that it only gets run once i.e. when the program starts.

Then I could make the thread loop and run all the time, checking for input, if not sleep.

Does this sound feasable?

0
 
LVL 6

Expert Comment

by:valipotor
ID: 17877426
This is the way to implement the background thread:

Thread backgroundThread = new Thread(new Runnable()
     {
          public void run()
          {
             while (true)
             {
               sleep();
             }
          }
     });
0
 
LVL 6

Expert Comment

by:valipotor
ID: 17877436
The background task should be started only once, in the main() method.

After the male(), female() initialisation.

Once the start method is invokes, the thread will execute the run() method in a spearate thread of execution.

That's why the loop in the run() method. The run() method must not finish.
0
 

Author Comment

by:john8932
ID: 17877523
public boolean male = true;
      public long goToSleep;

      public String start()
      {
            backgroundThread.start();
            
            System.out.println();
            System.out.println();
            System.out.println("Welcome to my AI Pet Demonstration");

This is the new location for starting the method.

Do you think this is suitable?

It was going to be in main allow that produced an error.

Any more advice would be appreciated as it is still not working.

Cheers
0
 
LVL 6

Accepted Solution

by:
valipotor earned 250 total points
ID: 17879427
Post the current code, so I can take a look.
0

Featured Post

Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This was posted to the Netbeans forum a Feb, 2010 and I also sent it to Verisign. Who didn't help much in my struggles to get my application signed. ------------------------- Start The idea here is to target your cell phones with the correct…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…
Suggested Courses

628 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question