Friday 19 December 2014

Web Tutorial: The QBasic Xmas Tree

Merry Christmas and Happy Holidays!

The occasion calls for some festive light-hearted fun, and what better than something I used to fool around with as an awkward geeky teenager?

QBasic! For more on this: http://en.wikipedia.org/wiki/QBasic

Now that I'm a slightly less awkward, even more geeky adult, here's an updated version of a little program I wrote back then, to test my mastery of nested loops and logic - the QBasic Xmas Tree!

Ah, the nostalgia.

This isn't a web tutorial per se, because QBasic has nothing to do with the web. On the other hand, this tutorial is being posted on the web, so... enough dithering! Let's fire up your QBasic editor and get right to it!

First, type the following code in your console.
INPUT "How many sections should your Xmas tree have"; sections

Run this line, and it should be enough to give you the following:

The program starts with user input.

This will serve to obtain user input (only in numerical format) and assign it to the variable sections. This is important because the program will generate a Xmas Tree with that number of sections.

Of course, we're not done yet. The first line works, but it's useless on its own unless you have the rest of the program. But first, a preview of what your Xmas Tree will look like with four sections!

Ta daaaaa


INPUT "How many sections should your Xmas tree have"; sections
CLS

COLOR 14

cols = sections * 20
cols = cols + (cols MOD 2)

filler = (cols - 1) / 2

CLS clears the screen after obtaining input. and COLOR 14 changes the text color to Yellow. You'll need to do this because we're drawing the star!

cols = sections *20 defines the total theoretical amount of width (in spaces) your tree should take up. It should commensurate with the number of sections the user specifies. cols = cols + (cols MOD 2) makes sure it's an odd number.  filler=cols-1 defines the number of empty spaces on the left. In this case, you deduct 1 from it because the first line is going to be your filler, followed by one character dedicated to the star. So add the following lines to draw the star!

INPUT "How many sections should your Xmas tree have"; sections
CLS

COLOR 14
cols = sections * 20
cols = cols + (cols MOD 2)
filler = (cols - 1) / 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "*"

PRINT line$

The star is supposed to be dead center top of your tree. It's of course, followed by the top of the tree. I'm going to use the character "^" and call it a leaf.

INPUT "How many sections should your Xmas tree have"; sections
CLS

COLOR 14
cols = sections * 20
cols = cols + (cols MOD 2)
filler = (cols - 1) / 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "*"
PRINT line$

COLOR 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "^"

PRINT line$

Of course, COLOR 2 changes the text color to Green.

Now, we have the star, and we have the top of the tree. Now we're going to keep using leaves to draw the rest! For that, we'll need to employ a certain amount of logic.

Here are the rules:

The first section starts with two lines, just after the top of the tree. The first line of the first section will be 3 leaves. Subsequent lines will be 2 leaves more than the previous line of the same section, and the filler will be one space less.

Subsequent sections will have one more row than the previous section. And each row will start with the same number of leaves as the second-last row of the previous section!

To show you what I mean, refer to the illustration below:

(star and top)
                    *
                    ^
(section 1)
                   ^^^
                  ^^^^^
(section 2)
                   ^^^
                  ^^^^^
                 ^^^^^^^
(section 3)
                 ^^^^^^^
                ^^^^^^^^^
               ^^^^^^^^^^^
              ^^^^^^^^^^^^^  
(and so on)

So maybe we should represent this numerically, in tabular form, in order to understand better.
section rows leaves per row
1 2 3,5
2 3 3,5,7
3 4 7,9,11,13
4 5 11,13,15,17,19

So now we're going to add the first loop for sections, and implement the rows logic.
INPUT "How many sections should your Xmas tree have"; sections
CLS

COLOR 14
cols = sections * 20
cols = cols + (cols MOD 2)
filler = (cols - 1) / 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "*"
PRINT line$

COLOR 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "^"

PRINT line

FOR i = 1 TO sections STEP 1
    rows = 1 + i

NEXT i

And then we'll nest another FOR loop within the first one,
INPUT "How many sections should your Xmas tree have"; sections
CLS

COLOR 14
cols = sections * 20
cols = cols + (cols MOD 2)
filler = (cols - 1) / 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "*"
PRINT line$

COLOR 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "^"

PRINT line

FOR i = 1 TO sections STEP 1
    rows = 1 + i

    FOR j = 1 TO rows STEP 1
        line$ = ""
        nextstartcol = 0

    NEXT j
NEXT i

In the nested loop, we initialize the variable line to nothing and nextstartcol to 0, because they will be changed frequently. Now, next  one's a biggie. It's a nested IF loop that implements the logic of leaves per row.
INPUT "How many sections should your Xmas tree have"; sections
CLS

COLOR 14
cols = sections * 20
cols = cols + (cols MOD 2)
filler = (cols - 1) / 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "*"
PRINT line$

COLOR 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "^"

PRINT line

FOR i = 1 TO sections STEP 1
    rows = 1 + i

    FOR j = 1 TO rows STEP 1
        line$ = ""
        nextstartcol = 0

        IF i = 1 THEN
            IF j = 1 THEN
                sectioncols = 3
                nextstartcols = 3
            ELSE
               
sectioncols = sectioncols + 2
            END IF
        ELSE
            IF j = 1 THEN
               
sectioncols = nextstartcols
            ELSE
               
sectioncols = sectioncols + 2

                IF j = rows - 1 THEN
                    nextstartcols =
sectioncols
                END IF
            END IF
        END IF

    NEXT j
NEXT i

Now that the hard part's out of the way, we've determined nextstartrows and sectioncols for each row. Time to draw it!
INPUT "How many sections should your Xmas tree have"; sections
CLS

COLOR 14
cols = sections * 20
cols = cols + (cols MOD 2)
filler = (cols - 1) / 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "*"
PRINT line$

COLOR 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "^"

PRINT line

FOR i = 1 TO sections STEP 1
    rows = 1 + i

    FOR j = 1 TO rows STEP 1
        line$ = ""
        nextstartcol = 0

        IF i = 1 THEN
            IF j = 1 THEN
                sectioncols = 3
                nextstartcols = 3
            ELSE
                sectioncols = sectioncols + 2
            END IF
        ELSE
            IF j = 1 THEN
                sectioncols = nextstartcols
            ELSE
                sectioncols = sectioncols + 2

                IF j = rows - 1 THEN
                    nextstartcols = sectioncols
                END IF
            END IF
        END IF

        filler = (cols - sectioncols) / 2

        FOR k = 1 TO filler STEP 1
            line$ = line$ + " "
        NEXT k

        FOR k = 1 TO sectioncols STEP 1
            line$ = line$ + "^"
        NEXT k

        PRINT line$

    NEXT j
NEXT i

And there you have your Xmas Tree. I'm gonna add one last segment of code as a message:
INPUT "How many sections should your Xmas tree have"; sections
CLS

COLOR 14
cols = sections * 20
cols = cols + (cols MOD 2)
filler = (cols - 1) / 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "*"
PRINT line$

COLOR 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "^"

PRINT line

FOR i = 1 TO sections STEP 1
    rows = 1 + i

    FOR j = 1 TO rows STEP 1
        line$ = ""
        nextstartcol = 0

        IF i = 1 THEN
            IF j = 1 THEN
                sectioncols = 3
                nextstartcols = 3
            ELSE
                sectioncols = sectioncols + 2
            END IF
        ELSE
            IF j = 1 THEN
                sectioncols = nextstartcols
            ELSE
                sectioncols = sectioncols + 2

                IF j = rows - 1 THEN
                    nextstartcols = sectioncols
                END IF
            END IF
        END IF

        filler = (cols - sectioncols) / 2

        FOR k = 1 TO filler STEP 1
            line$ = line$ + " "
        NEXT k

        FOR k = 1 TO sectioncols STEP 1
            line$ = line$ + "^"
        NEXT k

        PRINT line$
    NEXT j
NEXT i

COLOR 15
filler = (cols - 15) / 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "MERRY CHRISTMAS!"

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

PRINT line$

filler = (cols - 5) / 2
line$ = ""

FOR i = 1 TO filler STEP 1
    line$ = line$ + " "
NEXT i

line$ = line$ + "T___T"

PRINT line$

And that's the entire piece of code for the QBasic Xmas Tree. Pretty old-school stuff, especially when you consider it was done way back before the Internet came with color.

Pretty easy, wasn't it? One could even say it was... wait for it... elemen-tree!
T___T

2 comments:

  1. Oh, it seems in the line "FOR k = 1 TO bodycols STEP 1", I guess you ment "FOR k = 1 TO sectioncols STEP 1"?
    I used quickbasic quite a long time ago and I needed a while to find out why the program did not work as intended :D

    ReplyDelete