A variable is a labeled place for a value
A game needs to remember a score, a player's position, and whether a door is unlocked. Give each fact a clear name. Dim declares the variable; As states what kind of value it can hold; = stores a value.
Option Explicit
Dim HeroName As Text
Dim Score As Number
Dim HasKey As Boolean
Dim Speed As Double
HeroName = "Nova"
Score = 70
HasKey = True
Speed = 2.5
| Type | Use it for | Examples | Default |
|---|---|---|---|
Number | Whole-number scores, counts, indices, IDs | 7, 0, -3 | 0 |
Double | Fractional positions, speeds, elapsed seconds | 2.5, 0.125, 1e-3 | 0.0 |
Boolean | A yes-or-no fact | True, False | False |
Text | Names, dialogue, labels | "Nova", "Level 1" | "" (empty text) |
You will also meet Image for pictures, and your own Enum, Type, and Class types. Start with the four kinds above.
Put Option Explicit at the start of each source file, before ordinary declarations or instructions. Comments may come first. Module files have a slightly different placement, shown in Modules. Older examples may omit it; new learner programs should declare their variables.
Turn rules into expressions
An expression calculates a value. For example, Gems * PointsPerGem calculates the reward for all collected gems. A constant is a named value that cannot be changed while the program runs.
Const PointsPerGem = 10
Dim Gems As Number
Dim Score As Number
Gems = 7
Score = Gems * PointsPerGem
Print Score
| Expression | Meaning | Result |
|---|---|---|
7 + 2 | Add | 9 |
7 - 2 | Subtract | 5 |
7 * 2 | Multiply | 14 |
7 / 2 | Divide whole numbers; discard the fractional part | 3 |
7 Mod 2 | Whole-number remainder | 1 |
7.0 / 2.0 | Divide fractional numbers | 3.5 |
(7 + 2) * 3 | Calculate the parentheses first | 27 |
Multiplication and division happen before addition and subtraction. Use parentheses whenever they make your intention clearer. In an assignment such as Score = Score + 10, SMILE reads the old score, adds ten, and stores the new result.
Whole numbers and fractional numbers are different
Number means an integer in SMILE 2.0. Writing 7 creates a Number literal; writing 7.0 creates a Double literal. SMILE does not silently change one type into the other. Use ToDouble or ToNumber where you intend a conversion.
Dim Speed As Double
Dim ElapsedMilliseconds As Number
Dim Distance As Double
Speed = 2.5
ElapsedMilliseconds = 200
Distance = Speed * (ToDouble(ElapsedMilliseconds) / 1000.0)
Print Distance
At 2.5 units per second for 200 milliseconds, the distance is 0.5 units. Converting the elapsed time before division keeps that fraction. ToDouble(1 / 2) is 0.0, because the integer division already produced zero. ToDouble(1) / 2.0 is 0.5.
ToNumber(3.9) gives 3; ToNumber(-3.9) gives -3. The fractional part is removed toward zero. Array positions and loop counters still need Number values.
Double uses binary floating point. Many decimal fractions cannot be stored exactly. Compare a calculated value with a small tolerance when appropriate, such as Abs(Distance - 0.5) < 0.000001. Division by zero and invalid operations such as Sqrt(-1.0) are errors. Write 0.5, with digits on both sides of the dot.
Talk to the player with Text
Text goes inside double quotation marks. Join Text values with +. To print a label beside a number, separate them with a semicolon. SMILE does not turn a Number into Text just because it is next to a Text value.
Dim HeroName As Text
Dim Score As Number
HeroName = "Nova"
Score = 70
Print "Welcome, " + HeroName + "!"
Print "Score: "; Score
Print normally finishes the line. A final semicolon keeps the next output on that same line. A plain Print finishes that line. Text supports Unicode, so names and dialogue can contain more than English letters.
Text_Length("Nova") gives 4. Text_Slice("Nova", 1, 2) gives "ov": start at zero-based character index 1, then take 2 characters. These functions count Unicode scalar values. See the built-in reference for text and conversion functions.
Ask questions with Boolean expressions
A comparison returns True or False. In an assignment, = stores a value. Inside a condition or expression, = checks equality.
| Question | Expression |
|---|---|
| Are these equal? | Score = 100 |
| Are these different? | Score <> 100 |
| Below / at most / above / at least? | <, <=, >, >= |
| Are both facts true? | HasKey And IsNearDoor |
| Is at least one fact true? | HasKey Or DoorIsOpen |
| Reverse yes and no? | Not HasKey |
And and Or short-circuit from left to right: the right side is skipped if the left side already decides the answer. Text equality is exact: "Nova" and "nova" are different values, even though SMILE variable names are case-insensitive.
An array stores several values under one name
Imagine three score slots in a row. Dim RoundScores[3] As Number makes three Number elements. Their positions, called indices, start at zero.
Const RoundCount = 3
Dim RoundScores[RoundCount] As Number
Dim Total As Number
Dim RoundIndex As Number
RoundScores[0] = 70
RoundScores[1] = 40
RoundScores[2] = 90
For RoundIndex = 0 To RoundCount - 1
Total = Total + RoundScores[RoundIndex]
End For
Print Total
The For loop visits each valid index and adds its score. The total is 200. You will learn loops on the next page. Array lengths are fixed by positive compile-time Number expressions; they are not a growable list.
Two dimensions are useful for board games. Dim Board[8, 8] As Number creates 64 elements. Board[2, 5] = 1 changes one cell. Both indices must be from 0 to 7. SMILE checks array bounds; an out-of-range access stops the program with an error.
Code that your future self can read
- Use names such as
PlayerHealthandPointsPerGeminstead of single letters. - Use
'for comments that explain why a rule exists. - Put one instruction on each line and indent nested code by four spaces.
- Spell keywords consistently:
Dim,Print,End If. SMILE is case-insensitive, but a consistent style helps you read. - To continue a long expression onto another line, enclose it in balanced parentheses. An array's square brackets do not enable continuation.
Your mission: add a fourth round
Download the complete scoreboard example. Change RoundCount to 4, add a score of 60 at index 3, and predict the new total before running it.
Reveal one solution
Change the constant and add the new assignment after the other round scores. The existing loop already uses RoundCount - 1, so it visits the new element too. The total becomes 260.
Const RoundCount = 4
' Add this after assigning indices 0, 1, and 2:
RoundScores[3] = 60