Using Flags in Your Code
by Welopez
When testing the flow of logic decisions and branching in your code, it is quick and easy to use the MAINWIN. After your code is working properly, then you can create your GUI and place controls for events in your program.
Flags have been used for millennia, as a means of marking important features or events. Flags are both important and useful to basic code. Long before textiles were invented, a flag might consist of an animal skull or totem placed before the tribal chieftans hut, allowing members of the tribe (or enemies!) to locate the important headman.
When fabrics became available, colors and designs could be added to flags to give special meaning. In the noise and confusion of battle, when distances can be quite large, flags have been used by the military to designate the location of the leader or sub-leader, and send commands for conducting the battle. Naval vessels have used flags to send commands or messages to other vessels, in fact, flag etiquette and code have well defined international meanings which can be used regardless of the language used by the vessel captains.
In some cases, we can use a flag simply to check and see if a window has been opened or closed. At startup, all flag values will be zero. When we open a window, we set it to 1, and reset it to zero when closing the window. In our [quit] or [exit] routine, we can check the status of all flags and close any windows for which flags have not been set to zero, avoiding one of those annoying error messages when Worbles begin waving flags at us, "Hey, you dumb coder! You forgot to close this window!" Sometimes you don't have to add code to your program to create a flag, the Worbles may do it for you!
When writing computer games, flags are often used to see if the player has magic spell in his bag of tricks, or photon torpedoes, or some other item. Flags can also be used to determine if you last moved North, South, East, West, etc, or if a player has or has not been removed from a game. There are many uses for flags, but they are mainly used to see if an action has been taken or can be taken.
In the short block of code below, we'll open a window to get input from the user, then branch [showMe] when the button is pressed. If the button is pressed a second time, we'll check the status of the flag to see if we've already done this and, if we have, we'll change the action of the button and branch to a different block of code.
'Change the branch action of a button with a FLAG
NOMAINWIN
WindowWidth=200
WindowHeight=200
UpperLeftX=INT((DisplayWidth-WindowWidth)/2)
UpperLeftY=INT((DisplayHeight-WindowHeight)/2)
msg$="Please enter your hourly wage in the textbox above." 'The message to print
STATICTEXT #ex.st1, msg$, 15, 50, 160, 75
TEXTBOX #ex.tb1, 15, 20, 160, 25
BUTTON #ex.btn1, "Show It", [showMe], UL, 70, 130, 60, 30
OPEN "Example" FOR WINDOW AS #ex
PRINT #ex, "font arial 11"
PRINT #ex, "trapclose [quit]"
PRINT #ex.tb1, "!font courier 10"
[again]
PRINT #ex.tb1, ""
PRINT #ex.tb1, "!setfocus"
WAIT
[showMe]
IF flag=1 THEN 'Check to see if we've already done this
PRINT #ex.st1, msg$
flag=0 'Reset the flag
GOTO [again]
END IF
PRINT #ex.tb1, "!contents? salary"
PRINT #ex.st1, "You entered $"; USING("#####.##", salary)+CHR$(13)+_
CHR$(13)+"Press the button to do another."
flag=1 'Set the flag the first time we've done this
WAIT
[quit]
CLOSE #ex
END
There, that wasn't so difficult, was it? The first time through the code, the flag value was zero, so we printed a message and set the flag to 1 when the button was pressed. The second time the button is pressed, we use an IF/THEN comparison so see if we've already done this and, if so, we'll branch to a different location to set up the window again.
There can be many more situations when you will choose to create a flag. Take for example, young Don Juan de Worble....
Juan fancies himself quite the dashing young Worble, attractive to all the female Worbles around the CPU. Juan uses the computer to keep a list of his lady friends and, to avoid getting seriously involved with any particular lady, he uses a routine to randomly fill his social calendar for the coming month.
An example of Juan's code might look like this:
'Don Juan de Worble's Social Calendar
'Fill the array with names of Juan's girl friends
'We don't need to DIM gal$() array,
'because there are fewer than 10 entries.
gal$(1)="Brenda"
gal$(2)="Donna"
gal$(3)="Shirley"
gal$(4)="Trish"
gal$(5)="Michelle"
gal$(6)="Candy"
gal$(7)="Bambi"
gal$(8)="Wendy"
gal$(9)="Iris"
INPUT "How many nights out this month? "; callsToMake
PRINT
PRINT "Day"; TAB(5); "Call"
DO
callsMade=callsMade+1
thisGal=INT(RND(0)*9) + 1 'Random choice of gal to call
PRINT callsMade; TAB(5); gal$(thisGal)
LOOP UNTIL callsMade = callsToMake
END
Juan decided not to use a FOR/NEXT loop for reasons which will become obvious later. In this DO/LOOP, the number of callsMade is incremented by one with each pass through the loop. callsMade must be incremented before the RND(0) choice because we use it as a counter when printing out Juan's social calendar for this month, and continue looping until Juan has a date planned for each night out.
Okay, that runs fairly well. Juan decides how much money he has at Worble Savings and Loan, compares that with the evenings he has off this month, and enters the number of dates he would like to plan for. When the program runs, Juan has a list of which lady to call next. Juan is really in love with himself and hasn't considered that any of his lady friends might have other plans or might not wish to go out that night.
One problem Juan recognized immediately: Even if he only has 10 dates planned for this month, occasionally his random routine will choose the same lady twice, or even three times in a row. This is not acceptable to Juan; he is too special to date the same lady successively, and wants to spread himself around for the benefit of all the ladies. Ain't he a jerk?
Juan is a clever Worble and decides to set a flag in his code and see if he has already dated this gal. Juan adds four lines inside his DO/LOOP. He also placed the accumulator for callsMade inside the IF/THEN comparison, because he doesn't want to increment that value until he checks the status of the flag.
DO
thisGal=INT(RND(0)*9) + 1 'Random choice of gal to call
flag(thisGal)=flag(thisGal)+1 '<<< Add this flag to the code
IF flag(thisGal)=1 THEN '<<< Should we call this gal?
callsMade = callsMade + 1
PRINT callsMade; TAB(5); gal$(thisGal)
flag(thisGal)=0 '<<< Set flag to zero after call
END IF '<<< End the comparison
LOOP UNTIL callsMade=callsToMake
The first line added sets a flag to find out if he has previously dated this gal. At start up, all flags are zero. After a random choice is made, the flag can be set to flag=1, but Juan discovered his random number generator, just like dice, can roll the same number in succession.
Although this code has fewer repeats, Juan still wants to avoid dating the same girl twice in a row, so he uses a larger value for flag in the IF/THEN comparison. Even testing for flag=2, RND(0) may still select the same gal, so Juan tries 3, and even 4! There is no reason we can't test for 5, or even 10, just to insure RND(0) has not repeated a selection. Eventually, a gal will be called and printed to Juan's social calendar, then the flag for that gal will be reset to zero so she can be tossed back into Juan's gal-pool. When using flags, it is important to remember to reset values when a comparison has been met and the action taken.
Because Juan is using the RND(0) function before making a phone call, he has no idea how many calls will or will not be made, so a FOR/NEXT loop was not appropriate. He might have used a WHILE/WEND loop to make a list for n number of calls, but chose instead to use a DO/UNTIL loop. You have several choices of loops available to perform repetitive actions, so use the method which is most appropriate for your code. For other examples and creative uses of loops, click here.
Juan has only 9 gal Worlbes in his little black book at this time, and the probability of choosing the same gal is quite high. He hopes he will eventually have dozens of lady friends, reducing the probability of repeats, and he will have to DIM flag() and gal$() to allow for all the gals to be favored with his attention.
Choosing where to increment your flag and other variables will determine the logic of your code. If you increment callsMade before checking the flag status, you may be counting non-existant calls should your IF/THEN fall through.
Juan was pretty lazy when writing this routine, probably in a hurry to shower and go out on the town with one of his gal friends. If he hadn't been in such a hurry, he probably would have loaded his callsMade into an array before printing. If he had done that, then he could compare the selections to previous selections and be 100% certain that every gal had been dated at least once before Juan began starting through his list again. See Avoiding 5 Aces for one way to check an array for repeats.
Even I could have told him that, but Juan is such an unlikeable fellow, I thought it would be more fun to watch him make a fool of himself.