Previous |
| Next |
for
loop is a pretty
useful command.
But, you can make it even more useful if you nest one loop command inside another.
When you nest loops, it means that the inner loop will run N times for each time the outer loop does a cycle.
Try typing this code into Komodo Edit and see what it does.
|
You have to click the OK button a lot of times before you finish the two loops.
You can figure out how many times the innermost part of a loop will be
executed. It will be the product of all the times you go through each
loop. In the example above, that's 5 "X" loops and 3 "Y" loops. So there
will be 3 x 5
passes for 15 tk_messageBox commands.
There's a couple of rules for using nested loops.
Now, in fact, neither of these rules is absolute, but if you break them, you better know just what you're doing and why.
For starters, lets look at the number guessing game where you use numbers from 0 to 100 and put 10 guesses on each row.
You can do that with a single loop, like the code just below this.
Dividing the contents of the variable count
by 10 returns
the row to put each button on. If you divide one whole number by
another whole number in Tcl/Tk, it returns a whole number back to
you. This is the quotient without any remainder or fractional part.
When $count
is less than 10, $count / 10
will
be 0. When $count
is between 10 and 19, $count /
10
will be 1, and so forth.
The expr
command's % operator divides one number by
another and gives you the remainder instead of the quotient.
If you divide 23 by 10, the quotient is 2 with a remainder of 3. So
expr 23 %10
returns 3.
The remainder of 1 % 10
is 1
, the remainder
of 12 % 10
is 2
, and so forth.
|
This makes a display that looks like this:
We can create the same buttons with a pair of nested loops: one loop for the rows and one for the columns.
|
This is a little longer than the previous code, but it's also a little
simpler. Being able to split the rows and columns into two spots means
we don't need to think about the %
operator any more.
But, it takes a lot of time to type in all of these expr
commands to change the value of our loop variables.
Computer programmers don't like to waste a lot of time, so there are shorter ways to things that are very common. One very common thing for computer programs to do is to add a number to the value stored in a variable.
So, there's a command to increment a variable. It's called incr
.
You use this command by telling incr
what variable you want
to add a value to, and the value to add. If you leave out the value to
add, Tcl/Tk assumes you want to add 1. The value 1
is called
a default. When you don't put some arguments onto a command line,
you get a default value .
We can rewrite the previous loop using the incr
command,
and it will look like this:
|
It's not a big change, but it makes the program easier to read.
Using the nested loops makes it a little simpler to create the buttons on the game board.
When you've got 10 numbers in a row, the "Too High", and "Too Low" clues make sense. When the buttons are in a grid, those clues don't make so much sense. It would make more sense to say "LEFT", "RIGHT", "UP" or "DOWN". And then it's not a number guessing game, it's a position guessing game.
Instead of having a single secret number, we can change the game to have two secret numbers - a secret row and a secret column. When the player clicks too far to the left, they get told to go right, if they click to high, they get told to go down, etc.
It would be easy to write the loops like the next code. There's a problem with this. Look at it for a moment and see if you can see what the problem is. Here's a hint - the code will run just fine - it just won't do the right thing.
You might try typing it into Komodo Edit to see what it does.
|
You probably noticed that when you select a position to the left and
up, the code sets the
When you play the game, you need to go up and down until you find the
correct row, then left and right to the correct column.
That's not a fun way to play the game. We can make it better.
Just like it's pretty common to want to add one value to the contents
of a variable, it's common to want to add a new string onto the end of
the contents of a variable.
The command to append one string onto the end of another is
Like the
To make a variable with the string
Notice that we've got a space after the first quote in the
Here's the code for a position guessing game using the
The
These tests are combined using the
The
Boolean operators are just like the normal arithmetic operators
you're familiar with like +, - and so forth.
But while arithmetic operators work with lots of numbers, the
boolean operators only work with 2 values: TRUE and FALSE. We
sometimes represent FALSE as a 0, and TRUE as any non-zero number,
and sometimes as the words TRUE and FALSE, and sometimes we use the
words yes for TRUE and no for FALSE.
The two boolean operators we use for building
You can group sets of boolean expressions Just like you can group parts
of an arithmetic expression with parentheses.
For instance, if you want to make sure that the addition is done before the
multipliction in an arithmetic expression, you'd write
With boolean algebra, you group the tests in the order you want them
done.
This test below is from the
First Tcl/Tk
checks to see if
If
But if
If
Finally, Tcl/Tk compares the results to see if they are all TRUE. In this
exmpale, they are both TRUE, so the boolean expression is TRUE.
If both of these tests are TRUE, then the
Take another look at the
I put the
Do you need that text? What would happen if you had no
Try playing with the nested loops in Komodo Edit. Change the program
to be use a 15x15 grid instead of 10x10.
The important parts of this lesson are:
In the next lesson, we'll learn some more things about
message
variable to "Left", and then
overwrites that value and sets the message/CODE> variable to "Up".
append
.
incr
command, append
command needs
to know the variable to append new values to, and the values to append.
Unlike incr
, there is no default value for the
append
command.
first second
in it,
you might do something like this:
set message "first"
append message " second"
append
command. The append
command will append every single character
that you give it to the string in your variable. It won't add any new
characters (like a space) or skip any. If you left out the space,
the new contents of message
would be firstsecond
tk_messageBox
commands. Notice the first if
command. We'll discuss that
right after you look at this example.
# Calculate 2 secret numbers between 1 and 10
set secretX [expr 1 + int(rand() * 10)]
set secretY [expr 1 + int(rand() * 10)]
# The variable buttonNum will make it easy to build
# unique names for each button.
set buttonNum 0
for {set x 1} {$x <= 10} {incr x} {
for {set y 1} {$y <= 10} {incr y} {
# Initialize the message to be an empty string
set message {}
# If the X and Y both match the secrets
# the player has won.
if {($x == $secretX) && ($y == $secretY)} {
set message "You Win"
}
# If x is less than secret, they player needs to guess
# further to the right.
if {$x < $secretX} {
append message "Right "
}
# If x is greater than secret, they player needs to guess
# further to the left.
if {$x > $secretX} {
append message "Left "
}
# If y is less than secret, they player needs to guess
# further down.
if {$y < $secretY} {
append message "Down"
}
# If y is greater than secret, they player needs to guess
# further up.
if {$y > $secretY} {
append message "Up"
}
button .b_$buttonNum -text "Guess $x $y" \
-command "tk_messageBox -type ok -message {$message}"
grid .b_$buttonNum -column $x -row $y
incr buttonNum
}
}
if
command in that example has two tests. One to
check if $x
matchs $secretX
and one to
check if $y
matchs $secretY
.
&&
symbols. The
&&
means both of the tests have to be true for the
if
command to accept that the test is true.
&&
symbols are called boolean operators.
if
command
tests are:
Symbol
Name
Example
Description
&&
AND
$a && $b
Every argument must be true.
||
OR
$a || $b
At least one argument must be true.
(1 + 2) x 3
.
if
command above. Tcl/Tk
evaluates it in 3 steps:
($x == $secretX) && ($y == $secretY)
$x
is the same as $secretX
. If it
is, Tcl/Tk replaces that part of the command with a TRUE.
(TRUE) && ($y == $secretY)
$x
is not the same as $secretX
, then we're
done. A single FALSE means that the &&
can't be TRUE.
$x
is the same as $secretX
, Tcl/Tk will
check if $y
is the same as $secretY
, and then will
replace that part of the command as necessary.
$y
is the same as $secretY
, the new command will
look like this:
(TRUE) && (TRUE)
if
command will
look at the action associated with it.
button
in the command above.
The button text is Guess $x $y
. The $x
and
$y
will be replaced by the values of the x and y variables,
so the actual text will be things like Guess 2 3.
$x
and $y
into the button command
so you can see how the buttons are arranged on the screen.
-text
argument for the button
command, or if you just used a question
mark, or your name? Try changing these on the button and see what happens.
incr
command.
incr
to add a negative number to the
contents of a variable to do a subtractraction.
append
command.
snack
and make this program talk to us instead of using
the tk_messageBox
popups.
Previous
Next
Copyright 2007 Clif Flynt