Choosing a Value
Before this: Truth Tables
Next steps: Toggles and Latches, Bits, Matching Text, Remote Control, Ready Check
Parts that use this: Drawbridge, Moving Platform
The logic operators give on or off. Often you want to pick between two other
values instead: a red light or a green one, one message or another. The if
you met in Reacting to the Game chooses which
steps run. This lesson’s if chooses a value.
Contents
chip2 "Counter"
chip "Color"
button Held -> chip2 pressed
chip2 presses -> chip presses
chip color -> light Color
switch Enabled -> light Enabled
Code
@left in presses: int
let pick = presses % 3
@right out color = if pick == 0 then Color(1.0, 0.0, 0.0)
else if pick == 1 then Color(0.0, 1.0, 0.0)
else Color(0.0, 0.0, 1.0)
@left in presses: intis a number pin. A small counter chip, given in Run, counts a button’s presses and feeds the number in here.%is the remainder after dividing.presses % 3counts 0, 1, 2, then back to 0: 4 presses leave a remainder of 1, and 6 leave 0.Color(r, g, b)makes a color from its red, green and blue parts, each from0.0to1.0.Color(1.0, 0.0, 0.0)is red.if pick == 0 then A else Bis a value:Awhen the condition is true,Bwhen it is false. TheBhere is anotherif, so the choice has three answers.thenandelsecan start new lines, as they do here.
With no presses yet the light is red. What color is it after four presses? After nine?
Run
-
Compile the chip and paste it in-game. Place a Button, a Switch and a Point Light.
-
Paste this counter chip as well. It adds one each time
pressedturns on. Remembering Values explains how.@left in pressed: exec var count: int = 0 @right out presses = count.Value on pressed { count += 1 } -
Wire the Button’s Held to the counter’s
pressed, the counter’spressesto the first chip’spresses, andcolorto the Point Light’s Color. Turn off the light’s Use Brick Color setting: while it is on, the light takes the brick’s color and ignores the wire. -
Wire the Switch’s Enabled straight to the Point Light’s Enabled, and flip it on.
-
Press the button. The light goes red, green, blue, red again. Four presses leave it green, and nine leave it red.
Under the Hood
Open the color chip. There is one Modulo gate for presses % 3. Both
comparisons read it, because let pick names one wire. Then there are two
Select gates, one for each if.
A Select gate has two value inputs, Input A and Input B, and a bool
input, Select B. Its output is Input B while Select B is on, and Input A
while it is off. An if puts the condition on Select B, the then value
on Input B, and the else value on Input A. The second Select’s
output is the first one’s Input A: that is the chain.
A Select gate does not choose which input to compute. Both are computed all
the time, and the gate passes one of them along. So an if value always does
the work of both arms, and the condition only picks which answer is used:
@left in a: int
@left in b: int
@right out q = if b != 0 then a / b else 0
This chip has a Divide gate wired straight to its pins, and it divides even
while b is 0. That is harmless here, because the game’s Divide gives 0 when
you divide by zero. But the if did not protect the division: the arm that is
not chosen still runs. The “Both arms evaluate” note on the reference’s
Expressions page
has the details, including the exception for an arm that writes a variable
inside a handler.
Modify
-
Add a fourth color. Change
% 3to% 4and add one moreelse if pick == 2 then ...before the lastelse. TryColor(1.0, 1.0, 0.0), which is yellow. -
Choose text the same way. Add an output for a Text Decal’s Text that names the color:
@left in presses: int let pick = presses % 3 @right out color = if pick == 0 then Color(1.0, 0.0, 0.0) else if pick == 1 then Color(0.0, 1.0, 0.0) else Color(0.0, 0.0, 1.0) @right out name = if pick == 0 then "red" else if pick == 1 then "green" else "blue"Open it: the two outputs share the one Modulo and both Equal gates, and each has its own pair of Selects.
-
Add a
@left in dim: boolpin from a Switch, and an output for the Point Light’s Brightness that is one number whiledimis on and a larger one while it is off. Pick the numbers by trying them in-game.
Make
Make a three-light signal: a red, a yellow and a green Point Light, each
with its own @right out pin wired to its Enabled, so that one press of a
button moves which one is on. Use presses % 3, and an == for each light
in place of an if.
chip2 "Counter"
chip "Signal"
button Held -> chip2 pressed
chip2 presses -> chip presses
chip red -> light1 Enabled
chip yellow -> light2 Enabled
chip green -> light3 Enabled
Good to Know
- An unwired number pin reads as 0. Before the counter is wired,
pressesis 0 and the light is red. - Divide and Modulo give 0 when the second input is 0, rather than failing. That is why an untaken arm that divides by zero does no harm, and also why it can hide a mistake: a wrong 0 looks like a real answer.
Other ways to choose
A chain of ifs is not the only way to pick one of several values. The same
color picker can be written two more ways.
With match over an enum, each choice gets a name instead of a number.
Hue.FromInt(n) turns the number into the enum’s value with that position
(0 is Red, 1 Green, 2 Blue), and match gives the value for each one.
It compiles to the same Selects as the if chain:
enum Hue { Red, Green, Blue }
@left in presses: int
@right out color = match Hue.FromInt(presses % 3) {
Red => Color(1.0, 0.0, 0.0),
Green => Color(0.0, 1.0, 0.0),
Blue => Color(0.0, 0.0, 1.0),
}
With a list, the choices sit in order and the number reads one by its
position. A list can only be read inside a handler, so the chip keeps the
pick in a var and reads the list each time presses changes
(on Change(presses)):
const COLORS = [Color(1.0, 0.0, 0.0), Color(0.0, 1.0, 0.0), Color(0.0, 0.0, 1.0)]
@left in presses: int
var shown: color = Color(1.0, 0.0, 0.0)
@right out color = shown.Value
on Change(presses) {
shown = COLORS[presses % 3]
}
The list costs the same few gates however many choices it holds, while an
if chain or a match grows by a gate or two per choice, so a list wins once
there are many. Enums and
Lists cover both in full.
Next: Toggles and Latches.