'===========================================================================
' Subject: MATH TEST                          Date: 03-30-96 (00:00)       
'  Author: Dave Gjessing                      Code: QB, QBasic, PDS        
'  Origin: dgjess@freenet.columbus.oh.us    Packet: ALGOR.ABC
'===========================================================================
DEFINT A-Z

'QMATHTST.BAS - a little math test prog based on the
'IFACE_06.BAS text user interface - Dave Gjessing 1996
'(as if *I* know anything about math! <BG>)

'Thanks to Ken Melvin for contributing the music bits to ABC
'and to William Yu for maintaining same (ABC)

main:

DLBox 2, 1, 23, 80, 176, 0, 15, 1, 0
MenuBar 1, 15, 1
DLBox 8, 26, 13, 54, 0, 1, 15, 1, 0
LOCATE 9, 30: PRINT "Addition"
LOCATE 10, 30: PRINT "Subtraction"
LOCATE 11, 30: PRINT "Multiplication"
LOCATE 12, 30: PRINT "Division"
IF TotalProbs! > 0 THEN
        Average! = (TotalCorrect! * 100) / TotalProbs!
        LOCATE 17, 18: PRINT " So far, your average score is  ";
        PRINT USING "###"; Average!;
        PRINT "% correct ";
        END IF
CommandPointer 9, 28, 12, 15, 1, DoLine%
SELECT CASE DoLine%
   CASE 9
   addprobs
   GOTO main
   CASE 10
   subprobs
   GOTO main
   CASE 11
   multprobs
   GOTO main
   CASE 12
   divprobs
   GOTO main
   CASE 610             'F10 key re-initializes score-keeping
   TotalProbs! = 0
   TotalCorrect! = 0
   GOTO main
   CASE 900             'ESC key exits the program
   CLS
   LOCATE 11, 30: PRINT "Thanks for playing!"
   LOCATE 13, 25: PRINT "dgjess@freenet.columbus.oh.us"
   SLEEP 3: CLS
   END
   CASE ELSE            'anything else does nothing
   GOTO main
END SELECT

SUB addprobs
SHARED TotalProbs!
SHARED TotalCorrect!
DLBox 2, 1, 23, 80, 0, 1, 15, 1, 0
MenuBar 2, 15, 1

LOCATE 3, 4: PRINT "Addition test!"
LOCATE 5, 4: PRINT "I, your computer, will be making up addition problems"
LOCATE 6, 4: PRINT "for you, based on the answers you give to the next few questions."
LOCATE 10, 4: INPUT "What is the largest number you want me to use"; tops
LOCATE 12, 4: INPUT "How many problems do you want me to give you (up to 20)"; probs
IF probs > 20 THEN probs = 20
TotalProbs! = TotalProbs! + probs
correct = 0
wrong = 0
DLBox 2, 1, 23, 80, 0, 1, 15, 1, 0
RANDOMIZE tops
            FOR I% = 1 TO probs
                LOCATE 1, 2: PRINT (probs - I%) + 1; " to go";
                x = INT(RND * tops) + 1
                y = INT(RND * tops) + 1
                answer = x + y
                DLBox 12, 20, 14, 60, 0, 1, 15, 1, 0
                LOCATE 13, 23: PRINT y; " plus "; x; " equals ";
                INPUT try
                IF try = answer THEN correct = correct + 1: PLAY "t240o3l8d#fgl8b-p8l8gl2b-": LOCATE 8, 37: PRINT "RIGHT!": SLEEP 1: LOCATE 8, 37: PRINT "      "
                IF try <> answer THEN
                PLAY "t255l16o1bo4dg#o2f"
                wrong = wrong + 1
                LOCATE 15, 30: PRINT "the answer is "; answer;
                SLEEP 2
                DLBox 2, 1, 23, 80, 0, 1, 15, 1, 0
                END IF
                LOCATE 1, 2: PRINT STRING$(40, 0);
            NEXT I%
DLBox 2, 1, 23, 80, 176, 1, 15, 1, 0
DLBox 8, 26, 11, 54, 0, 1, 15, 1, 0
LOCATE 9, 28: PRINT "you got -> "; correct; "correct"
TotalCorrect! = TotalCorrect! + correct
LOCATE 10, 28: PRINT "you got -> "; wrong; "wrong"
IF wrong = 0 THEN BEEP
DLBox 14, 26, 16, 54, 0, 1, 15, 1, 0
LOCATE 15, 28: LINE INPUT "press ENTER to continue "; junk$

END SUB

SUB CommandPointer (firstline%, Col%, BotLimit%, Fgc%, Bgc%, DoLine%)
'this is where the user reacts to menu choices...

COLOR Fgc%, Bgc%
DoLine% = firstline%    'set aside the first line (sent with the sub call)
                        'as the upper limit to the list. (Work with DoLine%)
LOCATE firstline%, Col% 'go to the line and column called for in the
                        'subroutine call
PRINT CHR$(16)          'and print the line pointer on the screen

DO                      'run around in circles awaiting instructions
selection$ = INKEY$
selection$ = UCASE$(selection$)

'the next two IF's move the pointer up and down...
IF selection$ = CHR$(0) + "H" THEN           'UpArrow
   LOCATE DoLine%, Col%: PRINT CHR$(0)       'first blank out old pointer
   DoLine% = DoLine% - 1                     'move up one line
   IF DoLine% < firstline% THEN DoLine% = BotLimit% 'jump to bottom if at top
   LOCATE DoLine%, Col%                      'go to where directed
   PRINT CHR$(16)                            'print new pointer on screen
   END IF
IF selection$ = CHR$(0) + "P" THEN           'DnArrow
   LOCATE DoLine%, Col%: PRINT CHR$(0)       'cover the last pointer
   DoLine% = DoLine% + 1                     'move down one line
   IF DoLine% > BotLimit% THEN DoLine% = firstline% 'jump to top if at bottom
   LOCATE DoLine%, Col%                      'go to where directed
   PRINT CHR$(16)                            'new pointer
   END IF

'this IF reacts to the user pressing the ENTER key. The sub ends with a new
'value for DoLine%, equal to the line that the pointer was on.
IF selection$ = CHR$(13) THEN
    DoLine% = DoLine%
    EXIT SUB
    END IF

'these other IF's return a value for DoLine% which is not a valid screen
'coordinate. It is up to the SELECT CASE statements that follow the line
'that called CommandPointer to determine what to do with the returned value

IF selection$ = CHR$(0) + CHR$(81) THEN      'page down key
   DoLine% = 100
   EXIT SUB
   END IF
IF selection$ = CHR$(0) + CHR$(73) THEN      'page up key
   DoLine% = 200
   EXIT SUB
   END IF
IF selection$ = CHR$(0) + CHR$(59) THEN      'F1 key
   DoLine% = 601
   EXIT SUB
   END IF
IF selection$ = CHR$(0) + CHR$(60) THEN      'F2 key
   DoLine% = 602
   EXIT SUB
   END IF
IF selection$ = CHR$(0) + CHR$(61) THEN      'F3 key
   DoLine% = 603
   EXIT SUB
   END IF
IF selection$ = CHR$(0) + CHR$(62) THEN      'F4 key
   DoLine% = 604
   EXIT SUB
   END IF
IF selection$ = CHR$(0) + CHR$(63) THEN      'F5 key
   DoLine% = 605
   EXIT SUB
   END IF
IF selection$ = CHR$(0) + CHR$(64) THEN      'F6 key
   DoLine% = 606
   EXIT SUB
   END IF
IF selection$ = CHR$(0) + CHR$(65) THEN      'F7 key
   DoLine% = 607
   EXIT SUB
   END IF
IF selection$ = CHR$(0) + CHR$(66) THEN      'F8 key
   DoLine% = 608
   EXIT SUB
   END IF
IF selection$ = CHR$(0) + CHR$(67) THEN      'F9 key
   DoLine% = 609
   EXIT SUB
   END IF
IF selection$ = CHR$(0) + CHR$(68) THEN      'F10 key
   DoLine% = 610
   EXIT SUB
   END IF
IF selection$ = CHR$(27) THEN                'escape key
   DoLine% = 900
   EXIT SUB
   END IF
LOOP
'break out of the loop and return to the calling module with a new variable
'called DoLine%, equal to the line number on screen where the selected item
'was being displayed, or else with a number beyond the screen size (100, 200,
'etc.), which will be used to convey special instructions
END SUB

SUB divprobs
SHARED TotalProbs!
SHARED TotalCorrect!

DLBox 2, 1, 23, 80, 0, 1, 15, 1, 0
MenuBar 2, 15, 1

LOCATE 3, 4: PRINT "Division test!"
LOCATE 5, 4: PRINT "I, your computer, will be making up division problems"
LOCATE 6, 4: PRINT "for you, based on the answers you give to the next few questions."
LOCATE 8, 4: INPUT "What number do you want to divide by"; table
LOCATE 10, 4: INPUT "What is the largest number you want me to use"; tops
LOCATE 12, 4: INPUT "How many problems do you want me to give you (up to 20)"; probs
IF probs > 20 THEN probs = 20
TotalProbs! = TotalProbs! + probs
correct = 0
wrong = 0
DLBox 2, 1, 23, 80, 0, 1, 15, 1, 0
RANDOMIZE tops
            FOR I% = 1 TO probs
                LOCATE 1, 2: PRINT (probs - I%) + 1; " to go";
                x = INT(RND * tops) + 1
                answer = x \ table
                DLBox 12, 20, 14, 60, 0, 1, 15, 1, 0
                LOCATE 13, 23: PRINT x; " divided by "; table; " equals ";
                LINE INPUT try$
                IF LEN(try$) = 0 THEN GOTO wrong
                try = VAL(try$)
                IF try = answer THEN
                correct = correct + 1: PLAY "t240o3l8d#fgl8b-p8l8gl2b-": LOCATE 8, 37: PRINT "RIGHT!": SLEEP 1: LOCATE 8, 37: PRINT "      "
                GOTO nextprob
                END IF
                IF try <> answer THEN
wrong:
                PLAY "t255l16o1bo4dg#o2f"
                wrong = wrong + 1
                LOCATE 15, 30: PRINT "the answer is "; answer;
                SLEEP 2
                DLBox 2, 1, 23, 80, 0, 1, 15, 1, 0
                END IF
nextprob:
                LOCATE 1, 2: PRINT STRING$(40, 0);
            NEXT I%
DLBox 2, 1, 23, 80, 176, 1, 15, 1, 0
DLBox 8, 26, 11, 54, 0, 1, 15, 1, 0
LOCATE 9, 28: PRINT "you got -> "; correct; "correct"
TotalCorrect! = TotalCorrect! + correct
LOCATE 10, 28: PRINT "you got -> "; wrong; "wrong"
IF wrong = 0 THEN BEEP
DLBox 14, 26, 16, 54, 0, 1, 15, 1, 0
LOCATE 15, 28: LINE INPUT "press ENTER to continue "; junk$

END SUB

SUB DLBox (TLine, LCol, BLine, RCol, FieldNo, border, Fgc, Bgc, shadow)
'DLBOX (DeLuxe Box) is a fancy box sub-routine that includes
'a user-defined background character parameter, single or double-
'line border (or no border), and foreground and background color parameters,
'plus shadow or no shadow option.
'
'The no-border option makes this "box" routine able to replace "background"
'routines.
COLOR Fgc, Bgc
   IF border = 0 THEN    'no border at all
      ULC = FieldNo
      URC = FieldNo
      LLC = FieldNo
      LRC = FieldNo
      HORIZ = FieldNo
      VERT = FieldNo
         END IF
   IF border = 1 THEN   'single line border
      ULC = 218         'upper left corner
      URC = 191         'upper right corner
      LLC = 192         'lower left corner
      LRC = 217         'lower right corner
      HORIZ = 196       'horizontal lines
      VERT = 179        'vertical lines
         END IF
   IF border = 2 THEN   'double line border
      ULC = 201         'ditto all above
      URC = 187
      LLC = 200
      LRC = 188
      HORIZ = 205
      VERT = 186
         END IF

LOCATE TLine, LCol
PRINT CHR$(ULC) + STRING$(((RCol - LCol) - 1), CHR$(HORIZ)) + CHR$(URC)
FOR x = 1 TO (BLine - TLine) - 1
LOCATE ((TLine + 1) + NextLine), LCol
   NextLine = NextLine + 1
PRINT CHR$(VERT) + STRING$(((RCol - LCol) - 1), CHR$(FieldNo)) + CHR$(VERT);
NEXT x
LOCATE BLine, LCol
PRINT CHR$(LLC) + STRING$(((RCol - LCol) - 1), CHR$(HORIZ)) + CHR$(LRC);
 

IF shadow = 1 THEN   'for consistancy, use 1 for shadows, 0 for no shadow
   IF BLine > 24 OR RCol > 79 THEN GOTO badshadow
COLOR 7, 0           'shadows are dark

LOCATE BLine + 1, LCol + 1                 'across the
PRINT STRING$((RCol - LCol), CHR$(176));  'bottom...
 
FOR I = TLine + 1 TO BLine + 1              'on the
LOCATE I, RCol + 1: PRINT CHR$(176);         'right side
NEXT

END IF
COLOR Fgc, Bgc       'restore original colors
badshadow:

END SUB

SUB MenuBar (message, Fgc, Bgc)
COLOR Bgc%, Bgc%                             'nothing but background
LOCATE 1, 1: PRINT STRING$(80, 219);           'color bar 1 at top
LOCATE 24, 1: PRINT STRING$(80, 219);          'color bar 2 at bottom
LOCATE 25, 1: PRINT STRING$(80, 219);          'color bar 3 at very bottom
COLOR Fgc%, Bgc%                             'activate foreground color
progname$ = "QMATHTST.BAS - a math test program in QBasic"
title1$ = "Select a subject"
LOCATE 25, (40 - (LEN(progname$) / 2)): PRINT progname$;   'prog name

IF message% = 1 THEN
    LOCATE 1, 1: PRINT " <ESC> quits "; CHR$(4); " <ARROWS> & <ENTER> to select "; CHR$(4); " <F10> to re-set score"
    LOCATE 24, (40 - (LEN(title1$) / 2)): PRINT title1$;
END IF

IF message% = 2 THEN
END IF

IF message% = 3 THEN
END IF

IF message% = 4 THEN
END IF

IF message% = 5 THEN
END IF

IF message% = 6 THEN
END IF

IF message% = 7 THEN
END IF

IF message% = 8 THEN
END IF

IF message% = 9 THEN
END IF

IF message% = 10 THEN
END IF

END SUB

SUB multprobs
SHARED TotalProbs!
SHARED TotalCorrect!

DLBox 2, 1, 23, 80, 0, 1, 15, 1, 0
MenuBar 2, 15, 1

LOCATE 3, 4: PRINT "Multiplication test!"
LOCATE 5, 4: PRINT "I, your computer, will be making up multiplication problems"
LOCATE 6, 4: PRINT "for you, based on the answers you give to the next few questions."
LOCATE 8, 4: INPUT "What number do you want to multiply by"; table
LOCATE 10, 4: INPUT "What is the largest number you want me to use"; tops
LOCATE 12, 4: INPUT "How many problems do you want me to give you (up to 20)"; probs
IF probs > 20 THEN probs = 20
TotalProbs! = TotalProbs! + probs

correct = 0
wrong = 0
DLBox 2, 1, 23, 80, 0, 1, 15, 1, 0
RANDOMIZE tops
            FOR I% = 1 TO probs
                LOCATE 1, 2: PRINT (probs - I%) + 1; " to go";
                x = INT(RND * tops) + 1
                answer = x * table
                DLBox 12, 20, 14, 60, 0, 1, 15, 1, 0
                LOCATE 13, 23: PRINT table; " times "; x; " equals ";
                INPUT try
                IF try = answer THEN correct = correct + 1: PLAY "t240o3l8d#fgl8b-p8l8gl2b-": LOCATE 8, 37: PRINT "RIGHT!": SLEEP 1: LOCATE 8, 37: PRINT "      "
                IF try <> answer THEN
                PLAY "t255l16o1bo4dg#o2f"
                wrong = wrong + 1
                LOCATE 15, 30: PRINT "the answer is "; answer;
                SLEEP 2
                DLBox 2, 1, 23, 80, 0, 1, 15, 1, 0
                END IF
                LOCATE 1, 2: PRINT STRING$(40, 0);
            NEXT I%
DLBox 2, 1, 23, 80, 176, 1, 15, 1, 0
DLBox 8, 26, 11, 54, 0, 1, 15, 1, 0
LOCATE 9, 28: PRINT "you got -> "; correct; "correct"
TotalCorrect! = TotalCorrect! + correct
LOCATE 10, 28: PRINT "you got -> "; wrong; "wrong"
IF wrong = 0 THEN BEEP
DLBox 14, 26, 16, 54, 0, 1, 15, 1, 0
LOCATE 15, 28: LINE INPUT "press ENTER to continue "; junk$
END SUB

SUB subprobs
SHARED TotalProbs!
SHARED TotalCorrect!

DLBox 2, 1, 23, 80, 0, 1, 15, 1, 0
MenuBar 2, 15, 1

LOCATE 3, 4: PRINT "Subtraction test!"
LOCATE 5, 4: PRINT "I, your computer, will be making up subtraction problems"
LOCATE 6, 4: PRINT "for you, based on the answers you give to the next few questions."
LOCATE 10, 4: INPUT "What is the largest number you want me to use"; tops
LOCATE 12, 4: INPUT "How many problems do you want me to give you (up to 20)"; probs
IF probs > 20 THEN probs = 20
TotalProbs! = TotalProbs! + probs

correct = 0
wrong = 0
DLBox 2, 1, 23, 80, 0, 1, 15, 1, 0
RANDOMIZE tops
            FOR I% = 1 TO probs
                LOCATE 1, 2: PRINT (probs - I%) + 1; " to go";
                x = INT(RND * tops) + 1
                y = INT(RND * tops) + 1
                DLBox 12, 20, 14, 60, 0, 1, 15, 1, 0
                IF x >= y THEN
                answer = x - y
                LOCATE 13, 23: PRINT x; " take away "; y; " equals ";
                END IF
                IF y > x THEN
                answer = y - x
                LOCATE 13, 23: PRINT y; " take away "; x; " equals ";
                END IF
                INPUT try
                IF try = answer THEN correct = correct + 1: PLAY "t240o3l8d#fgl8b-p8l8gl2b-": LOCATE 8, 37: PRINT "RIGHT!": SLEEP 1: LOCATE 8, 37: PRINT "      "
                IF try <> answer THEN
                PLAY "t255l16o1bo4dg#o2f"
                wrong = wrong + 1
                LOCATE 15, 30: PRINT "the answer is "; answer;
                SLEEP 2
                DLBox 2, 1, 23, 80, 0, 1, 15, 1, 0
                END IF
                LOCATE 1, 2: PRINT STRING$(40, 0);
            NEXT I%
DLBox 2, 1, 23, 80, 176, 1, 15, 1, 0
DLBox 8, 26, 11, 54, 0, 1, 15, 1, 0
LOCATE 9, 28: PRINT "you got -> "; correct; "correct"
TotalCorrect! = TotalCorrect! + correct
LOCATE 10, 28: PRINT "you got -> "; wrong; "wrong"
IF wrong = 0 THEN BEEP
DLBox 14, 26, 16, 54, 0, 1, 15, 1, 0
LOCATE 15, 28: LINE INPUT "press ENTER to continue "; junk$

END SUB

