Using the MAINWIN as an Aid to Designing Your GUI

by Welopez


Okay, I've been programming with Just Basic for some time now, and I am pretty proficient at creating and using GUI's, why should I use the console, or MAINWIN anymore? Isn't that only for beginners?

While many of us prefer to create our snazzy programs using a GUI (and impressing the heck out of other JB programmers, perhaps even the cute girl down the block), there will still be many occasions when using the MAINWIN will save you time before designing the GUI for your program. Last month, for instance, I was writing a program entirely in JB to play a game of Blackjack between the computer and one player. I wanted to create a GUI to display BMP images of cards when dealt. Before I could plan the GUI, I needed to know how many cards I could expect the player or dealer to draw; in other words, how many hits could I reasonably expect? If my GUI only allows for six cards, and the player hits a seventh time, I need a place to print the image or my program will crash! On the other hand, I don't want to waste screen space when designing my GUI.

"But five and under always wins!" you say. Not so... I worked as a dealer, pit boss, and shift boss in legal Nevada casinos for 15 years. In some hotels, a player with 5 and under will be an automatic winner, but the dealer must always hit if the dealer total is less than 17, or in some cases a soft 17 where an ace is being counted as 11. If you do a Google search for blackjack rules, you will find many examples, but none mention the five-and-under, or six-and-under rule. This is only an option which a casino may offer if they desire.

Now that we've gotten past the details, lets see how many cards a player might draw. I wrote a program using the MAINWIN and dealt many millions of hands just to find out.

DIM deck(52) 'An array to hold the values of all cards

FOR k=1 to 52
    READ dummy 'Read the DATA statement
    deck(k)=dummy 'Put the value in the array
NEXT k

[reDo] 'Start here for successive program runs
CLS 'Begin with a clear screen
INPUT "How many hands to deal? "; hands
maxHits=0 'Set the maximum number of hits to zero to begin
handsDealt=0 'Reset counter to zero if dealing again
PRINT "Dealing"
begin=TIME$("seconds")

'===== This is where we begin counting the number of hands
DO
handsDealt=handsDealt+1 'Counter for handsDealt
    view=view+1 'Counter for eye-candy
    IF view=10000 THEN
        ln=ln+1 'Number of lines printed to MAINWIN
        PRINT "*"; 'Eye candy to keep user's interest
            IF ln=10 THEN
                PRINT 'Add new line each 100,000 iterations
                ln=0 'Reset line count to zero
            END IF
        view=0 'Reset views to 0 after each 10,000 iterations
    END IF
'=====This is where we deal each hand and hit if needed
    DO
        hits=hits+1
        card=INT(RND(0)*52)+1
        handTot=handTot+deck(card)
        IF hits > maxHits THEN maxHits=hits
    LOOP WHILE handTot < 18 'If this hand is less than 18, hit it!
    handTot=0 : hits=0 'Reset the accumulators

LOOP WHILE handsDealt < hands

finish=TIME$("seconds")
PRINT
PRINT "There were "; hands ; " hands dealt."
PRINT "Time for execution was "; finish-begin; " seconds."
IF finish-begin > 0 THEN  'Use to prevent division by zero error
    PRINT "There were "; hands/(finish-begin); " hands per second."
END IF
PRINT "The maximum number of cards in any hand was "; maxHits
PRINT

INPUT "Do again? (Y/N)"; usrResp$
usrResp$=UPPER$(usrResp$)
IF LEFT$(usrResp$, 1)="Y" THEN
    GOTO [reDo]
ELSE
    PRINT "Okay, thanks for dropping by. Have a nice day!"
END IF

END
'===== Values for cards to be dealt (Ace = 11)
DATA 11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10
DATA 11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10
DATA 11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10
DATA 11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10


The first thing we must do is dimension an array for the cards, in this case, DIM deck(52). Then we load the array with the possible values of all 52 cards. Now we ask the user how many hands to deal. One thousand hands won't take long, but we might not get an accurate statistical sampling of the number of cards which might be dealt for each hand. On the other hand, even on a fast computer, it may take awhile to deal one million hands, so to avoid that feeling of, "Uh-oh, my program has locked up in an endless loop," I added some eye-candy to this routine, just to keep the user interested.

I used a DO/LOOP nested within another DO/LOOP. The inside loop keeps hitting the player's hand as long as the total is less than 18. (For this trial, we are making no allowances for counting an ace as 1 or 11.) For every card dealt, hits is incremented by one to determine the maximum number of cards dealt before the player's hand totaled 18 or more.

The outside loop keeps count of how many hands have been dealt. As long as the number of hands is less than the INPUT amount, another hand will be dealt.

The eye-candy is used to print an * for every ten thousand hands dealt. When 10 asterisks have been printed to a line, printing advances to the next line, making it easy to visualize every 100,000 hands dealt. If the users interest is captured by each line of asterisks, we can assume he hasn't fallen asleep.

When all hands have been dealt, we print the statistics: number of hands dealt, time needed for dealing, number of hands per second, and the maximum number of cards for any hand before the total was 18 or greater. This computer dealer is exceptionally fast, more than 12,000 hands per second, and sometimes the time reported will be less than 1 second for completion. To prevent a division by zero error, we don't print hands/(finish-begin) unless the time is greater than one second.

When finished, the user can run again, or exit the program. After many millions of hands, I satisfied myself the player will never draw more than 8 cards total. Now I can begin creating my GUI for the Blackjack program and rest assured it will not crash as long as I have room to print 8 cards for a hand, neither will I waste a lot of unneeded screen space.

No matter how long you've been programming, you can still use the MAINWIN to test the logic and flow of your program; rooting out any bugs before you go to the time and trouble of creating the graphical user interface.