Skip to content

Asking Two Things at Once

Join questions together with AND, OR and NOT, so one test can ask about more than one thing.

  • Foundations

Real questions are rarely about one thing. Can the player shoot? Only if they are alive and they have ammo. Is a number in our chosen interval? Only if it is at least 1 and at most 10.

You can join questions together. Here we assume ASK has supplied an ordinary numeric value. Checking typed text or rejecting a malformed answer is a separate job. A variable holds a value; a comparison reads it and gives TRUE or FALSE.

Both, or either

AND is true when both halves are true. OR is true when either half is, or both.

Code
ASK "Guess a number from 1 to 10? " INTO guess
IF guess < 1 OR guess > 10 THEN
  SHOW "That is not between 1 and 10"
ELSE
  SHOW "Good guess"
END
Output
Guess a number from 1 to 10? 42
That is not between 1 and 10

That OR catches a guess that is too small and a guess that is too big, in one question. Written with AND it says the same thing from the other side:

Code
IF guess >= 1 AND guess <= 10 THEN
  SHOW "Good guess"
ELSE
  SHOW "That is not between 1 and 10"
END

>= means at least, and <= means at most. Both endpoints are included. The two versions choose the same message: one asks whether the number is outside, the other whether it is inside, and we swapped the messages too.

A number greater than zero is not necessarily at least one: 0.5 passes guess > 0 but fails guess >= 1. Those tests agree when a separate rule guarantees whole-number input; without it, write the boundary you mean.

Which values get Good guess: 0, 1, 1.5, 10 and 10.5? Does passing both bounds make a value a whole number?

Show the explanation

1, 1.5 and 10 are inside; 0 and 10.5 are outside. The number 1.5 is not whole, but it passes both comparisons. That is correct for this interval. A game that promises whole-number guesses needs an extra whole-number check. Neither AND nor OR performs that check for us.

For an optional machine example, Keep guessing explains separate range and whole-number checks in Sinclair BASIC. Read its “Enforce the promised range” section without playing the preceding game; its input rules belong to BASIC, rather than to this teaching notation.

The opposite

NOT turns an answer round. NOT yes is no, and NOT no is yes.

Code
IF NOT (guess = 7) THEN
  SHOW "Keep going"
END

The brackets are doing the job they did in Working It Out: work this out first. NOT turns round whatever sits inside them, so the whole question guess = 7 gets answered, and then turned round.

That asks whether the guess is anything other than seven. You could write the same thing as guess <> 7, which means is not equal to. Use whichever reads better where you are standing: NOT in front of a whole question, <> inside a small one.

Two questions, not one twice

A trap worth meeting now. This does not do what it looks like:

Code
IF guess = 3 OR 7 THEN

Read it as the computer does. It joins two questions: is guess equal to 3, and is 7. The second one is a number where our Boolean notation needs a TRUE/FALSE answer. Say both comparisons in full:

Code
IF guess = 3 OR guess = 7 THEN

Both halves of an AND or an OR stand on their own as Boolean answers here. A real language may accept numbers as conditions. In Sinclair BASIC, guess=3 OR 7 is accepted and gives a true result even when guess is 4: the non-zero 7 makes its OR true. Repeating the comparison expresses the intended rule instead of relying on that language-specific conversion.

Mixing them

AND and OR have an order too, the way * and + do: AND goes first. So alive AND ammo > 0 OR grenades > 0 may not ask what you think it asks.

Rather than lean on the rule, say it with brackets:

Code
IF alive AND (ammo > 0 OR grenades > 0) THEN
  SHOW "You can shoot"
END

Now the player must be alive whichever resource is available. To check whether the brackets matter, choose a case that could make the two versions disagree.

With alive FALSE, ammo 0 and grenades 1, does each version allow shooting? How would you repair the wrong guard?

Show the explanation

The ungrouped version is (alive AND ammo > 0) OR grenades > 0. Its first part is FALSE, but the grenade comparison is TRUE, so the whole test is TRUE. The grouped version is FALSE: alive must be TRUE as well as one resource being available. Keep the brackets around the two resource comparisons to express that rule. Testing only a living player with ammo would miss this difference.

When it’s wrong, see why

  • The test is always true. Check an OR that cannot come back no. guess < 1 OR guess > 0 covers every ordinary numeric value in these examples.
  • The test is never true. Check an AND asking for two things that cannot both hold. guess < 1 AND guess > 10 has no answer.
  • You wrote the value once and the question once. guess = 3 OR 7 names a value where a question belongs. Write both questions out.

What you’ve learnt

  • AND is true when both halves are true. OR is true when either is.
  • NOT turns an answer round, and <> asks whether two things differ.
  • >= and <= ask at least and at most.
  • Each half of a joined question has to be a question in its own right.

What’s next

Your programs can decide, and now they can decide about more than one thing at a time. In the next module, Repeating, you stop writing the same line ten times over.