Learn Programming in Java


<<Previous | ToC | Next >>

Lesson #3: Conditionals & Input

Today we start to make complicated programs. Today we can begin to write a simple game like Rock-Paper-Scissors or Seaman. Later we can tackle something more challenging, like where the computer plays Tic-Tac-Toe against a human. But first we need to know how to tell the computer to choose different results based on the values of data. It's called a conditional, and the fundamental conditional is "if" (the same as you learned in the Kitchen computer) with an optional "else" ("otherwise" in the Kitchen computer). Start over with our HelloWorld program, but this time make the interior look like this:
public static void main() {
    int boyz = 7, gulz = 3;
    if (boyz>gulz) System.out.println("Chauvinist!");
    else if (boyz<gulz) System.out.println("Feminist!");
        else System.out.println("Equality!");
}


Let's look at the structure of those conditionals. Normally we want the condition (inside the parentheses, which are required in Java) to be a boolean value, either the result of a compare as here, or else a boolean variable calculated at some other time, or perhaps a composite expression value. You know, even before running this program -- and any decent Java compiler probably does too -- that it's going to print out "Chauvinist!" not "Feminist!". But now we are going to ask the human operator for how many boys and girls there are, and the program actually does something we couldn't know when it was written. Insert these four lines after the declaration and before the first println:

System.out.print("How many boys? ");
boyz = Zystem.ReadInt();
System.out.print("How many girls? ");
gulz = Zystem.ReadInt();


Ordinarily we would use "System" for both input and output, but the Java folks made that unnecessarily complicated, so I made up a fake "Zystem" to use in the beginning. Later on you can look through what I did and see why. And then you won't need it any more. For today, "Zystem.ReadInt()" gets a user-typed number from the console window. In the Guessing Game (below) you will use "Zystem.ReadLetter()" to read a single character (letter) input. In each case the variable you read it into must match the type the function is giving you. This helps prevent mistakes, which is much more useful in very large programs.

Now after you compile and run it, it will stop and ask how many boys and girls you want it to compute on. Type in the number 4 and press Enter, then the number 5 and press Enter again. You have told the computer something it did not know, then it told you something based on the information it had. Run it a few times and convince yourself that you understand how it works.
 

Guessing Game

Games are always fun, but most games are pretty complicated and we do not yet have a lot of tools for dealing with that complexity. So let's do a simple guessing game, where you think of a number, and the computer will ask a few questions and try to guess what the number is. Actually it's not a guess at all, it will do a simple binary search, so it will always come back with the correct answer (unless you cheat), but it will give you an idea what a real program looks like. If you did the Guessing Game in the Kitchen computer, this will be familiar.

Although you can do each new program (like this guessing game) inside the same "Hello" class that we started in, it's sort of nice to keep a record of the significant programs you write, if nothing else, so you can show them off to your family and friends on the last day of this session. The easy way is to create a new class -- that would be a new yellow box in the BlueJ dashboard window (the "StartHere" window with the yellow rectangles). In that window, right-click the blank space behind those yellow rectangles, or else pull down the Edit menu, and choose "New Class". In the dialog that pops up, give it your class name, like "Guess" (it must be a single word that starts with a capital letter), verify that it will be making a Java class (later versions of BlueJ have several irrelevant options) and hit OK. Then double-click the new yellow rectangle with your class name.

What BlueJ gives you is a green box outlining the class, with two yellow boxes for methods. I (drag-selected, and) deleted both yellow boxes and in their place (in the white space inside the green box) made a single

public static void main() {

} // end of main

Just like in Hello. Notice that it made a new yellow box for you. This is where your guessing game code will go, in the white space inside that yellow box. If your left and right braces don't match up, you will get dark red error bars in the left margin. You need to be careful about that.

The first thing you do when writing any real program is to stop and think about what needs to be done. If you already did the Kitchen computer version, you might want to try your hand at doing it before you read through the following paragraphs. If it doesn't work, come back and go through the steps.

Suppose you want the computer to guess a number between 1 and 8. It could ask you (eight times) "Is it 1, is it 2, is it 3, ..." but that's both tedious and unnecessary. So let's think about how to divide the search space into smaller portions. Although we start off with eight possible numbers, if we ask "Is it more than 4?" and the answer is "no" then we have reduced the choices to four, 1 to 4. Similarly, if the answer is "yes" we still have reduced the search space to half. So each time the computer wants to ask a question, it can divide its search space approximately in half, until there's only one number left. For an initial search space of eight items, that only takes three questions, like this:

    int hi = 8, lo = 1, mid;
    char ans;
    System.out.println("Think of a number between " + lo + " and " + hi);
    mid = (hi+lo)/2; // initial test @ 4
    System.out.print("Is your number greater than " + mid + " (y/n)? ");
    ans = Zystem.ReadLetter();
    if (ans == 'y') lo = mid+1;
      else hi = mid;
    mid = (hi+lo)/2; // second test @ 2
    System.out.print("Is your number greater than " + mid + " (y/n)? ");
    ans = Zystem.ReadLetter();
    if (ans == 'y') lo = mid+1;
      else hi = mid;
    mid = (hi+lo)/2; // third test @ 1
    System.out.print("Is your number greater than " + mid + " (y/n)? ");
    ans = Zystem.ReadLetter();
    if (ans == 'y') lo = mid+1;
      else hi = mid;
    if (hi==lo) System.out.println("Your number is " + hi);
      else System.out.println("Oops something went wrong");


The first question will always be 4. This is integer (whole number) division, so half of (1+8=9) 4, not 4.5. Anyway, if the result of the compare is greater, then the range becomes 5-8 and the second question is 6, otherwise the range is reduced to 1-4, and the second question is 2. Can you figure out what the four different possible third questions are? What happens if you give it different starting numbers?

Let's look more closely at how this works.

Next: Using the BlueJ Debugger

<<Previous | ToC | Next >>

Revised: 2021 May 19