It is a good fun program and would put a lot of people off not knowing how to castle,exit,move etc.
You have to play against it in a cavalier manner to make it interesting, due to the fact that the Queen comes out like Rambo on steroids giving White a strong position if playing sensibly.
I have also noticed that Black never seems to castle and does not seem to obey all the rules.
It has given me some interesting games and must be worth playing for beginners or fun situations.
If anyone does download it, then I would reccomend that you compile it for a quicker game.
Nice work, I know you have put a lot of effort into it.
DECLARE SUB MORSE (ASCII!)
DIM SHARED CHAR(57), SIZE(57)
FOR X = 0 TO 56
READ CHAR(X)
NEXT
FOR X = 0 TO 56
READ SIZE(X)
NEXT
DATA 18,00,00,00,00,30,45
DATA 45,00,00,51,33,42, 9,31,30,28
DATA 24,16, 0, 1, 3, 7,15, 7,00,00
DATA 17,00,12,22, 2, 1, 5, 1, 0, 4
DATA 3, 0, 0,14, 5, 2, 3, 1 ,7, 6
DATA 11, 2, 0, 1, 4, 8, 6, 9,13, 3
DATA 6,00,00,00,00, 6, 6
DATA 6,00,00, 6, 6, 6, 5, 5, 5, 5
DATA 5, 5, 5, 5, 5, 5, 5, 6,00,00
DATA 5,00, 6, 6, 2, 4, 4, 3, 1, 4
DATA 3, 4, 2, 4, 3, 4, 2, 2, 3, 4
DATA 4, 3, 3, 1, 3, 4, 3, 4, 4, 4
IF COMMAND$ = "" THEN INPUT "FILE? ", FILE$ ELSE FILE$ = COMMAND$
OPEN FILE$ FOR INPUT AS #1
WHILE NOT EOF(1)
INPUT #1, A$
FOR X = 1 TO LEN(A$)
B$ = UCASE$(MID$(A$, X, 1))
CALL MORSE(ASC(B$))
NEXT
PRINT " "
WEND
SUB MORSE (ASCII)
BITS = 0
IF ASCII = 32 THEN
SLEEP 1: PRINT " "
EXIT SUB
END IF
IF ASCII > 33 AND ASCII < 91 THEN
CODE = CHAR(ASCII - 34)
BITS = SIZE(ASCII - 34)
END IF
FOR I = 1 TO BITS
IF (CODE MOD 2) THEN SOUND 500, 9: PRINT "-"; ELSE SOUND 500, 3: PRINT ".";
SLEEP 1
CODE = INT(CODE / 2)
NEXT
IF BITS THEN
T = TIMER: D = .5
WHILE T + D >= TIMER: WEND
PRINT "/";
END IF
END SUB
RANDOMIZE TIMER
CLS
DIM playerbd(0 TO 9, 0 TO 9) AS STRING
DIM compbd(0 TO 9, 0 TO 9) AS STRING
DIM comphits(0 TO 9, 0 TO 9) AS STRING
PRINT "Co-ordinates range from 0 to 9"
PRINT "* represents part of ship"
PRINT "+ represents hit part of ship."
PRINT "------------------------------"
PRINT "PLACE SHIP [LENGTH 2]"
INPUT "X CO-ORDINATE [0-9]:", x
INPUT "Y CO-ORDINATE [0-9]:", y
INPUT "DIRECTION [N,S,E,W]:", DIRECTION$
playerbd(x, y) = "*"
IF LCASE$(DIRECTION$) = "w" THEN
playerbd(x - 1, y) = "*"
END IF
IF LCASE$(DIRECTION$) = "e" THEN
playerbd(x + 1, y) = "*"
END IF
IF LCASE$(DIRECTION$) = "s" THEN
playerbd(x, y + 1) = "*"
END IF
IF LCASE$(DIRECTION$) = "n" THEN
playerbd(x, y - 1) = "*"
END IF
PRINT "PLACE SHIP [LENGTH 3]"
INPUT "X CO-ORDINATE [0-9]:", x
INPUT "Y CO-ORDINATE [0-9]:", y
INPUT "DIRECTION [N,S,E,W]:", DIRECTION$
playerbd(x, y) = "*"
IF LCASE$(DIRECTION$) = "w" THEN
playerbd(x - 1, y) = "*"
playerbd(x - 2, y) = "*"
END IF
IF LCASE$(DIRECTION$) = "e" THEN
playerbd(x + 1, y) = "*"
playerbd(x + 2, y) = "*"
END IF
IF LCASE$(DIRECTION$) = "s" THEN
playerbd(x, y + 1) = "*"
playerbd(x, y + 2) = "*"
END IF
IF LCASE$(DIRECTION$) = "n" THEN
playerbd(x, y - 1) = "*"
playerbd(x, y - 2) = "*"
END IF
PRINT "PLACE SHIP [LENGTH 3]"
INPUT "X CO-ORDINATE [0-9]:", x
INPUT "Y CO-ORDINATE [0-9]:", y
INPUT "DIRECTION [N,S,E,W]:", DIRECTION$
playerbd(x, y) = "*"
IF LCASE$(DIRECTION$) = "w" THEN
playerbd(x - 1, y) = "*"
playerbd(x - 2, y) = "*"
END IF
IF LCASE$(DIRECTION$) = "e" THEN
playerbd(x + 1, y) = "*"
playerbd(x + 2, y) = "*"
END IF
IF LCASE$(DIRECTION$) = "s" THEN
playerbd(x, y + 1) = "*"
playerbd(x, y + 2) = "*"
END IF
IF LCASE$(DIRECTION$) = "n" THEN
playerbd(x, y - 1) = "*"
playerbd(x, y - 2) = "*"
END IF
PRINT "PLACE SHIP [LENGTH 4]"
INPUT "X CO-ORDINATE [0-9]:", x
INPUT "Y CO-ORDINATE [0-9]:", y
INPUT "DIRECTION [N,S,E,W]:", DIRECTION$
playerbd(x, y) = "*"
IF LCASE$(DIRECTION$) = "W" THEN
playerbd(x - 1, y) = "*"
playerbd(x - 2, y) = "*"
playerbd(x - 3, y) = "*"
END IF
IF LCASE$(DIRECTION$) = "E" THEN
playerbd(x + 1, y) = "*"
playerbd(x + 2, y) = "*"
playerbd(x + 3, y) = "*"
END IF
IF LCASE$(DIRECTION$) = "S" THEN
playerbd(x, y + 1) = "*"
playerbd(x, y + 2) = "*"
playerbd(x, y + 3) = "*"
END IF
IF LCASE$(DIRECTION$) = "N" THEN
playerbd(x, y - 1) = "*"
playerbd(x, y - 2) = "*"
playerbd(x, y - 3) = "*"
END IF
PRINT "PLACE SHIP [LENGTH 5]"
INPUT "X CO-ORDINATE [0-9]:", x
INPUT "Y CO-ORDINATE [0-9]:", y
INPUT "DIRECTION [N,S,E,W]:", DIRECTION$
playerbd(x, y) = "*"
IF LCASE$(DIRECTION$) = "w" THEN
playerbd(x - 1, y) = "*"
playerbd(x - 2, y) = "*"
playerbd(x - 3, y) = "*"
playerbd(x - 4, y) = "*"
END IF
IF LCASE$(DIRECTION$) = "e" THEN
playerbd(x + 1, y) = "*"
playerbd(x + 2, y) = "*"
playerbd(x + 3, y) = "*"
playerbd(x + 4, y) = "*"
END IF
IF LCASE$(DIRECTION$) = "s" THEN
playerbd(x, y + 1) = "*"
playerbd(x, y + 2) = "*"
playerbd(x, y + 3) = "*"
playerbd(x, y + 4) = "*"
END IF
IF LCASE$(DIRECTION$) = "n" THEN
playerbd(x, y - 1) = "*"
playerbd(x, y - 2) = "*"
playerbd(x, y - 3) = "*"
playerbd(x, y - 4) = "*"
END IF
a = INT(RND(1) * 10)
b = INT(RND(1) * 10)
FOR c = 1 TO 4
compbd(a, b) = "*"
DO
x = INT(RND(1) * 4)
IF x = 0 AND a - c >= 0 THEN
FOR d = 1 TO c
compbd(a - c, b) = "*"
NEXT
EXIT DO
END IF
IF x = 1 AND a + c <= 9 THEN
FOR d = 1 TO c
compbd(a + c, b) = "*"
NEXT
EXIT DO
END IF
IF x = 2 AND b - c >= 0 THEN
FOR d = 1 TO c
compbd(a, b - c) = "*"
NEXT
EXIT DO
END IF
IF x = 3 AND b + c <= 9 THEN
FOR d = 1 TO c
compbd(a, b + c) = "*"
NEXT
EXIT DO
END IF
LOOP
NEXT
c = 2
compbd(a, b) = "*"
DO
x = INT(RND(1) * 4)
IF x = 0 AND a - c >= 0 THEN
FOR d = 1 TO c
compbd(a - c, b) = "*"
NEXT
EXIT DO
END IF
IF x = 1 AND a + c <= 9 THEN
FOR d = 1 TO c
compbd(a + c, b) = "*"
NEXT
EXIT DO
END IF
IF x = 2 AND b - c >= 0 THEN
FOR d = 1 TO c
compbd(a, b - c) = "*"
NEXT
EXIT DO
END IF
IF x = 3 AND b + c <= 9 THEN
FOR d = 1 TO c
compbd(a, b + c) = "*"
NEXT
EXIT DO
END IF
LOOP
DO
PRINT SPACE$(2);"0123456789"
FOR a = 0 TO 9
PRINT a;
FOR b = 0 TO 9
IF b < 9 AND playerbd(b, a) = "*" THEN PRINT "*";
IF b < 9 AND playerbd(b, a) = "+" THEN PRINT "+";
IF b < 9 AND playerbd(b, a) = "" THEN PRINT " ";
IF b = 9 AND playerbd(b, a) = "*" THEN PRINT "*"
IF b = 9 AND playerbd(b, a) = "" THEN PRINT " "
IF b = 9 AND playerbd(b, a) = "+" THEN PRINT "+"
NEXT
NEXT
PRINT "-----------"
PRINT SPACE$(2);"0123456789"
FOR a = 0 TO 9
PRINT a,
FOR b = 0 TO 9
IF b < 9 AND comphits(b, a) = "+" THEN PRINT "+";
IF b < 9 AND comphits(b, a) = "" THEN PRINT " ";
IF b = 9 AND comphits(b, a) = "" THEN PRINT " "
IF b = 9 AND comphits(b, a) = "+" THEN PRINT "+"
NEXT
NEXT
INPUT "FIRE X CO-ORDINATE [0-9]:", x
INPUT "FIRE Y CO-ORDINATE [0-9]:", y
IF compbd(x, y) = "*" THEN
compbd(x, y) = "+"
comphits(x, y) = "+"
END IF
a = INT(RND(1) * 10)
b = INT(RND(1) * 10)
IF playerbd(a, b) = "*" THEN
playerbd(a, b) = "+"
END IF
countera = 0
counterb = 0
FOR a = 0 TO 9
FOR b = 0 TO 9
IF compbd(a, b) = "*" THEN countera = countera + 1
NEXT
NEXT
IF countera = 0 THEN
PRINT "YOU WIN"
EXIT DO
END IF
FOR a = 0 TO 9
FOR b = 0 TO 9
IF playerbd(a, b) = "*" THEN counterb = counterb + 1
NEXT
NEXT
IF counterb = 0 THEN
PRINT "YOU LOSE"
EXIT DO
END IF
LOOP
DECLARE SUB drawcursor (angle!)
DECLARE SUB drawinner (delta!)
DECLARE SUB drawouter ()
SCREEN 12
CONST pi = 3.141592654#
DIM SHARED dialsize
dialsize = 200 'This is the coolist part change the size of the clock!
DO
LOCATE 1, 4
PRINT "Outer Scale: "; EXP(((angle / (2 * pi)) - INT(angle / (2 * pi))) * LOG(10)),
PRINT "Inner Scale: "; EXP((((angle - delta) / (2 * pi)) - INT((angle - delta) / (2 * pi))) * LOG(10))
drawouter
drawinner delta
drawcursor angle
SELECT CASE INKEY$
CASE CHR$(0) + CHR$(80)
delta = delta + .01: CLS
CASE CHR$(0) + CHR$(72)
delta = delta - .01: CLS
CASE CHR$(0) + CHR$(77)
angle = angle + .01: CLS
CASE CHR$(0) + CHR$(75)
angle = angle - .01: CLS
END SELECT
LOOP
SUB drawcursor (angle)
cursorx = COS(angle) * dialsize
cursory = SIN(angle) * dialsize
LINE (320, 240)-(320 + cursorx, 240 + cursory), 4
END SUB
SUB drawinner (delta)
innersize = dialsize * .8
CIRCLE (320, 240), innersize, 7
FOR t = 10 TO 99
cool = LOG(t / 10) / LOG(10) * pi * 2 + delta
coolx = COS(cool) * innersize
cooly = SIN(cool) * innersize
IF t MOD 10 = 0 THEN
hatchsize = 1.2
ELSEIF t MOD 10 = 5 THEN
hatchsize = 1.1
ELSE
hatchsize = 1.05
END IF
cool2y = SIN(cool) * (innersize / hatchsize)
cool2x = COS(cool) * (innersize / hatchsize)
LINE (coolx + 320, cooly + 240)-(cool2x + 320, cool2y + 240)
NEXT t
END SUB
SUB drawouter
CIRCLE (320, 240), dialsize, 7
FOR t = 10 TO 99
cool = LOG(t / 10) / LOG(10) * pi * 2
coolx = COS(cool) * dialsize
cooly = SIN(cool) * dialsize
IF t MOD 10 = 0 THEN
hatchsize = 1.2
ELSEIF t MOD 10 = 5 THEN
hatchsize = 1.1
ELSE
hatchsize = 1.05
END IF
cool2y = SIN(cool) * (dialsize / hatchsize)
cool2x = COS(cool) * (dialsize / hatchsize)
LINE (coolx + 320, cooly + 240)-(cool2x + 320, cool2y + 240)
NEXT t
SUB drawinner (delta)
innersize = dialsize * .8
CIRCLE (320, 240), innersize, 7
FOR t = 10 TO 99
cool = LOG(t / 10) / LOG(10) * pi * 2 + delta
coolx = COS(cool) * innersize
cooly = SIN(cool) * innersize
IF t MOD 10 = 0 THEN
hatchsize = 1.2
ELSEIF t MOD 10 = 5 THEN
hatchsize = 1.1
ELSE
hatchsize = 1.05
END IF
cool2y = SIN(cool) * (innersize / hatchsize)
cool2x = COS(cool) * (innersize / hatchsize)
LINE (coolx + 320, cooly + 240)-(cool2x + 320, cool2y + 240)
NEXT t
END SUB
SUB drawouter
CIRCLE (320, 240), dialsize, 7
FOR t = 10 TO 99
cool = LOG(t / 10) / LOG(10) * pi * 2
coolx = COS(cool) * dialsize
cooly = SIN(cool) * dialsize
IF t MOD 10 = 0 THEN
hatchsize = 1.2
ELSEIF t MOD 10 = 5 THEN
hatchsize = 1.1
ELSE
hatchsize = 1.05
END IF
cool2y = SIN(cool) * (dialsize / hatchsize)
cool2x = COS(cool) * (dialsize / hatchsize)
LINE (coolx + 320, cooly + 240)-(cool2x + 320, cool2y + 240)
NEXT t
END SUB
------------------------------------------------
It is a shame that page flipping is not supported in screen 12 and 13 but a time delay and clearing the keyboard buffer can help. I hope you like the addition I made, which was something I could do. I will admit this type of mathematical programming has never been something I have learned; so projects like these are foreign to me. It appears you have a real gift for them.
Great job!
Pete
This message has been edited by The-Universe on Aug 28, 2007 10:57 PM This message has been edited by The-Universe on Aug 28, 2007 7:48 PM
DECLARE SUB DrawInner (delta!)
DECLARE SUB DrawCursor (angle!, delta!)
DECLARE SUB DrawOuter ()
SCREEN 12
DIM SHARED PI
DIM SHARED dialsize
DIM SHARED OldAngle, OldX, OldY, OldDelta
PI = 3.141592654#
dialsize = 200 'This is the coolist part change the size of the clock!
DIM SHARED H(10 TO 99, 4)' History
DIM SHARED HH(6 TO 90, 4)
DIM dD AS SINGLE, dC AS INTEGER: dD = .01: dC = 2
DrawInner .02: DrawCursor .02, .02: CLS
LOCATE 1, 1: PRINT "Log: ";
LOCATE 2, 1: PRINT "D: "
LOCATE 3, 1: PRINT "C: ";
LOCATE 4, 1: PRINT "Sin: ";
LOCATE 5, 1: PRINT "Cos: ";
DO
LOCATE 1, 7: PRINT (angle / (2 * PI)) - INT(angle / (2 * PI))
LOCATE 2, 7: PRINT EXP(((angle / (2 * PI)) - INT(angle / (2 * PI))) * LOG(10))
LOCATE 3, 7: PRINT EXP((((angle - delta) / (2 * PI)) - INT((angle - delta) / (2 * PI))) * LOG(10));
ang = EXP((((angle - delta) / (2 * PI)) - INT((angle - delta) / (2 * PI)) - 1) * LOG(10))
ang2 = 2 * ATN(ang / (1 + SQR(1 - ang * ang))) * 180 / PI
LOCATE 4, 7: PRINT ang2;
ang3 = 90 - ang2
LOCATE 5, 7: PRINT ang3;
DrawOuter
DrawInner delta
DrawCursor angle, delta
WHILE INKEY$ <> "": WEND: DO: k$ = UCASE$(INKEY$): LOOP WHILE k$ = ""
SELECT CASE k$
CASE CHR$(27): SYSTEM
CASE "F", "S": GOSUB AdjustSpeed
CASE CHR$(0) + CHR$(80): delta = delta + dD
CASE CHR$(0) + CHR$(72): delta = delta - dD
CASE CHR$(0) + CHR$(77): angle = angle + dD
CASE CHR$(0) + CHR$(75): angle = angle - dD
END SELECT
LOOP
AdjustSpeed:
SELECT CASE dC
CASE 1: IF k$ = "F" THEN dD = .01: dC = 2
CASE 2: IF k$ = "F" THEN dD = .1: dC = 3 ELSE dD = .001: dC = 1
CASE 3: IF k$ = "F" THEN dD = 1: dC = 4 ELSE dD = .01: dC = 2
CASE ELSE: IF k$ = "S" THEN dD = .1: dC = 3
END SELECT
w$ = "----": MID$(w$, dC, 1) = "o"
LOCATE 6, 1: PRINT w$
RETURN
SUB DrawCursor (angle, delta)
IF OldAngle = angle THEN
LINE (320, 240)-(OldX, OldY), 4
EXIT SUB
END IF
OldAngle = angle
cursorX = COS(angle) * dialsize * 1.18
cursorY = SIN(angle) * dialsize * 1.18
LINE (320, 240)-(OldX, OldY), 0
OldX = 320 + cursorX
OldY = 240 + cursorY
LINE (320, 240)-(OldX, OldY), 4
DrawOuter
DrawInner delta
LINE (320, 240)-(OldX, OldY), 4
END SUB
SUB DrawInner (delta)
innersize = dialsize * .8
sinesize = dialsize * .6
IF delta = OldDelta THEN
FOR T = 10 TO 99
COLOR 7: LINE (H(T, 1), H(T, 2))-(H(T, 3), H(T, 4))
NEXT T
FOR T = 6 TO 90
COLOR 7: LINE (HH(T, 1), HH(T, 2))-(HH(T, 3), HH(T, 4))
NEXT
CIRCLE (320, 240), innersize, 7
CIRCLE (320, 240), sinesize, 7
EXIT SUB
END IF
OldDelta = delta
FOR T = 10 TO 99
cool = LOG(T / 10) / LOG(10) * PI * 2 + delta
coolx = COS(cool) * innersize
cooly = SIN(cool) * innersize
IF T MOD 10 = 0 THEN
hatchsize = 1.15
ELSEIF T MOD 10 = 5 THEN
hatchsize = 1.08
ELSE
hatchsize = 1.05
END IF
cool2y = SIN(cool) * (innersize / hatchsize)
cool2x = COS(cool) * (innersize / hatchsize)
COLOR 0: LINE (H(T, 1), H(T, 2))-(H(T, 3), H(T, 4))
H(T, 1) = coolx + 320: H(T, 2) = cooly + 240
H(T, 3) = cool2x + 320: H(T, 4) = cool2y + 240
COLOR 7: LINE (H(T, 1), H(T, 2))-(H(T, 3), H(T, 4))
NEXT T
FOR T = 6 TO 90
sine = LOG(SIN(T * PI / 180)) / LOG(10) * PI * 2 + delta
sinex = COS(sine) * sinesize
siney = SIN(sine) * sinesize
IF T MOD 10 = 0 THEN
hatchsize = 1.15
ELSEIF T MOD 10 = 5 THEN
hatchsize = 1.08
ELSE
hatchsize = 1.05
END IF
sine2x = COS(sine) * (sinesize / hatchsize)
sine2y = SIN(sine) * (sinesize / hatchsize)
COLOR 0: LINE (HH(T, 1), HH(T, 2))-(HH(T, 3), HH(T, 4))
HH(T, 1) = sinex + 320: HH(T, 2) = siney + 240
HH(T, 3) = sine2x + 320: HH(T, 4) = sine2y + 240
COLOR 7: LINE (HH(T, 1), HH(T, 2))-(HH(T, 3), HH(T, 4))
NEXT
CIRCLE (320, 240), innersize, 7
CIRCLE (320, 240), sinesize, 7
END SUB
SUB DrawOuter
asdfsize = dialsize * 1.18
FOR T = 1 TO 100
asdf = (T / 100) * PI * 2
asdfx = COS(asdf) * asdfsize
asdfy = SIN(asdf) * asdfsize
IF T MOD 10 = 0 THEN
hatchsize = 1.15
ELSEIF T MOD 10 = 5 THEN
hatchsize = 1.08
ELSE
hatchsize = 1.05
END IF
asdf2y = SIN(asdf) * (asdfsize / hatchsize)
asdf2x = COS(asdf) * (asdfsize / hatchsize)
LINE (asdfx + 320, asdfy + 240)-(asdf2x + 320, asdf2y + 240)
NEXT
FOR T = 10 TO 99
dial = LOG(T / 10) / LOG(10) * PI * 2
dialx = COS(dial) * dialsize
dialy = SIN(dial) * dialsize
IF T MOD 10 = 0 THEN
hatchsize = 1.15
ELSEIF T MOD 10 = 5 THEN
hatchsize = 1.08
ELSE
hatchsize = 1.05
END IF
dial2y = SIN(dial) * (dialsize / hatchsize)
dial2x = COS(dial) * (dialsize / hatchsize)
LINE (dialx + 320, dialy + 240)-(dial2x + 320, dial2y + 240)
NEXT T
CIRCLE (320, 240), asdfsize, 7
CIRCLE (320, 240), dialsize, 7
END SUB
CLS
INPUT search$
SHELL "FIND /C /I " + CHR$(34) + search$ + CHR$(34) + " DICT.DAT > RESULTS.DAT"
OPEN "results.dat" FOR INPUT AS #1
INPUT #1, line$
INPUT #1, line$
CLOSE #1
SHELL "del results.dat"
IF INSTR(line$, " 0") = 0 THEN PRINT "Word is in dictionary.": END
search$ = LTRIM$(RTRIM$(UCASE$(search$)))
firstletter$ = LEFT$(search$, 1)
search$ = RIGHT$(search$, LEN(search$) - 1)
FOR i = 1 TO LEN(search$)
c$ = MID$(search$, i, 1)
SELECT CASE c$
CASE "B", "F", "P", "V"
soundex$ = soundex$ + "1"
CASE "C", "G", "J", "K", "Q", "S", "X", "Z"
soundex$ = soundex$ + "2"
CASE "D", "T"
soundex$ = soundex$ + "3"
CASE "L"
soundex$ = soundex$ + "4"
CASE "M", "N"
soundex$ = soundex$ + "5"
CASE "R"
soundex$ = soundex$ + "6"
END SELECT
NEXT
FOR i = 2 TO LEN(soundex$)
IF MID$(soundex$, i, 1) = MID$(soundex$, i - 1, 1) THEN
soundex$ = LEFT$(soundex$, i - 1) + MID$(soundex$, i + 1)
END IF
NEXT i
soundex$ = LEFT$(soundex$ + "000", 3)
soundex$ = firstletter$ + soundex$
OPEN "DICT.DAT" FOR INPUT AS #1
OPEN "DICT2.DAT" FOR INPUT AS #2
WHILE NOT (EOF(1))
INPUT #2, sndx$
INPUT #1, word$
IF sndx$ = soundex$ THEN PRINT word$,
WEND
END
I used this to copy the data. It freezes things up if you try to copy/paste it...
September 9 2007, 11:32 AM
1) Use 'View Source' in you browser.
2) Copy the data with the <br> tags as listed.
3) Save it to your QB directory as: "Dictraw.dat"
4) Run this:
CLS
OPEN "dictraw.dat" FOR INPUT AS #1
OPEN "dict.dat" FOR OUTPUT AS #2
DO UNTIL EOF(1)
LINE INPUT #1, a$
a$ = MID$(a$, 1, LEN(a$) - 4)
PRINT #2, a$
LOOP
SYSTEM
---------------------
Just delete the file you don't need or write your own NAME AS statement in the code, instead.
This message has been edited by The-Universe on Sep 9, 2007 1:34 PM
OPEN "DICT.DAT" FOR INPUT AS #1
OPEN "DICT2.DAT" FOR OUTPUT AS #2
WHILE NOT (EOF(1))
soundex$=""
INPUT #1, search$
search$ = LTRIM$(RTRIM$(UCASE$(search$)))
firstletter$ = LEFT$(search$, 1)
search$ = RIGHT$(search$, LEN(search$) - 1)
FOR i = 1 TO LEN(search$)
c$ = MID$(search$, i, 1)
SELECT CASE c$
CASE "B", "F", "P", "V"
soundex$ = soundex$ + "1"
CASE "C", "G", "J", "K", "Q", "S", "X", "Z"
soundex$ = soundex$ + "2"
CASE "D", "T"
soundex$ = soundex$ + "3"
CASE "L"
soundex$ = soundex$ + "4"
CASE "M", "N"
soundex$ = soundex$ + "5"
CASE "R"
soundex$ = soundex$ + "6"
END SELECT
NEXT
FOR i = 2 TO LEN(soundex$)
IF MID$(soundex$, i, 1) = MID$(soundex$, i - 1, 1) THEN
soundex$ = LEFT$(soundex$, i - 1) + MID$(soundex$, i + 1)
END IF
NEXT i
soundex$ = LEFT$(soundex$ + "000", 3)
soundex$ = firstletter$ + soundex$
PRINT #2, soundex$
WEND
END
OPEN "DICT.DAT" FOR INPUT AS #1
OPEN "DICT2.DAT" FOR OUTPUT AS #2
WHILE NOT (EOF(1))
soundex$ = ""
INPUT #1, search$
search$ = LTRIM$(RTRIM$(UCASE$(search$)))
firstletter$ = LEFT$(search$, 1)
search$ = RIGHT$(search$, LEN(search$) - 1)
FOR i = 1 TO LEN(search$)
c$ = MID$(search$, i, 1)
SELECT CASE c$
CASE "B", "F", "P", "V"
soundex$ = soundex$ + "1"
CASE "C", "G", "J", "K", "Q", "S", "X", "Z"
soundex$ = soundex$ + "2"
CASE "D", "T"
soundex$ = soundex$ + "3"
CASE "L"
soundex$ = soundex$ + "4"
CASE "M", "N"
soundex$ = soundex$ + "5"
CASE "R"
soundex$ = soundex$ + "6"
END SELECT
NEXT
FOR i = 2 TO LEN(soundex$)
IF MID$(soundex$, i, 1) = MID$(soundex$, i - 1, 1) THEN
soundex$ = LEFT$(soundex$, i - 1) + MID$(soundex$, i + 1)
END IF
NEXT i
soundex$ = LEFT$(soundex$ + "00000", 5)
soundex$ = firstletter$ + soundex$
PRINT #2, soundex$
WEND
DECLARE FUNCTION SOUNDEX$ (NAME$)
DECLARE FUNCTION FRONTV! (X$)
DECLARE FUNCTION VOWEL! (X$)
DECLARE FUNCTION VARSON! (X$)
OPEN "DICT.DAT" FOR INPUT AS #1
OPEN "DICT2.DAT" FOR OUTPUT AS #2
WHILE NOT (EOF(1))
INPUT #1, WORD$
WORD$ = SOUNDEX$(WORD$)
PRINT #2, WORD$
WEND
END
FUNCTION FRONTV (X$)
FRONTV = INSTR("EIY", X$)
END FUNCTION
FUNCTION SOUNDEX$ (NAME$)
NAME$ = UCASE$(NAME$)
TWO$ = MID$(NAME$, 1, 2)
IF TWO$ = "PN" OR TWO$ = "AR" OR TWO$ = "KN" OR TWO$ = "GN" OR TWO$ = "WR" OR TWO$ = "AE" THEN NAME$ = MID$(NAME$, 2)
IF TWO$ = "WH" THEN NAME$ = "W" + MID$(NAME$, 3)
IF LEFT$(NAME$, 1) = "X" THEN NAME$ = "S" + MID$(NAME$, 2)
L = LEN(NAME$)
FOR I = 1 TO L
SYMB$ = MID$(NAME$, I, 1)
IF I > 1 THEN PREV$ = MID$(NAME$, I - 1, 1) ELSE PREV$ = "."
IF I > 2 THEN PREV2$ = MID$(NAME$, I - 2, 1) ELSE PREV2$ = "."
IF I < L THEN NEXT$ = MID$(NAME$, I + 1, 1) ELSE NEXT$ = "."
IF I < L - 1 THEN NEXT2$ = MID$(NAME$, I + 2, 1) ELSE NEXT2$ = ""
IF I < L - 2 THEN NEXT3$ = MID$(NAME$, I + 3, 1) ELSE NEXT3$ = ""
IF SYMB$ <> "C" AND I > 1 AND PREV$ = SYMB$ THEN NEW = 0 ELSE NEW = -1
IF NEW THEN
IF VOWEL(SYMB$) AND I = 1 THEN
METAPH$ = METAPH$ + SYMB$
ELSE
SELECT CASE SYMB$
CASE "B"
IF I = L AND PREV$ = "M" THEN SILENT = -1 ELSE SILENT = 0
IF NOT SILENT THEN METAPH$ = METAPH$ + "B"
CASE "C"
IF NOT (PREV$ = "S" AND FRONTV(NEXT$)) THEN
IF NEXT$ = "I" AND NEXT2$ = "A" THEN
METAPH$ = METAPH$ + "X"
ELSE
IF FRONTV(NEXT$) THEN
METAPH$ = METAPH$ + "S"
ELSEIF NEXT$ = "H" AND PREV$ = "S" THEN
METAPH$ = METAPH$ + "K"
ELSEIF NEXT$ = "H" THEN
IF I = 0 AND VOWEL(NEXT2$) = 0 THEN
METAPH$ = METAPH$ + "K"
ELSE
METAPH$ = METAPH$ + "X"
END IF
ELSE
METAPH$ = METAPH$ + "K"
END IF
END IF
END IF
CASE "D"
IF NEXT$ = "G" AND FRONTV(NEXT2$) THEN
METAPH$ = METAPH$ + "J"
ELSE
METAPH$ = METAPH$ + "T"
END IF
CASE "G"
IF NEXT$ = "H" AND VOWEL(NEXT2$) THEN SILENT = -1 ELSE SILENT = 0
IF (I + 1 = L OR (NEXT$ = "N" AND NEXT2$ = "E" AND NEXT3$ = "D")) AND NEXT$ = "N" THEN SILENT = -1
IF PREV$ = "G" THEN HARD = -1 ELSE HARD = 0
IF NOT SILENT THEN
IF FRONTV(NEXT$) AND NOT HARD THEN
METAPH$ = METAPH$ + "J"
ELSE
METAPH$ = METAPH$ + "K"
END IF
END IF
CASE "H"
IF VARSON(PREV$) AND VOWEL(NEXT$) THEN METAPH$ = METAPH$ + "H"
CASE "F", "J", "L", "M", "N", "R"
METAPH$ = METAPH$ + SYMB$
CASE "K"
IF PREV$ <> "C" THEN METAPH$ = METAPH$ + "K"
CASE "P"
IF NEXT$ = "H" THEN
METAPH$ = METAPH$ + "F"
ELSE
METAPH$ = METAPH$ + "K"
END IF
CASE "Q"
METAPH$ = METAPH$ + "K"
CASE "S"
IF NEXT$ = "I" AND (NEXT2$ = "O" OR NEXT2$ = "A") THEN
METAPH$ = METAPH$ + "X"
ELSEIF NEXT$ = "H" THEN
METAPH$ = MEATPH$ + "X"
ELSE
METAPH$ = METAPH$ + "S"
END IF
CASE "T"
IF NEXT$ = "I" AND (NEXT$ = "O" OR NEXT$ = "A") THEN
METAPH$ = METAPH$ + "X"
ELSEIF NEXT$ = "H" THEN
METAPH$ = METAPH$ + "0"
ELSEIF NOT (NEXT$ = "C" AND NEXT2$ = "H") THEN
METAPH$ = METAPH$ + "T"
END IF
CASE "V"
METAPH$ = METAPH$ + "F"
CASE "W", "Y"
IF VOWEL(NEXT$) THEN METAPH$ = METAPH$ + SYMB$
CASE "X"
METAPH$ = METAPH$ + "KS"
CASE "Z"
METAPH$ = METAPH$ + "S"
END SELECT
END IF
END IF
NEXT
SOUNDEX$ = METAPH$
END FUNCTION
FUNCTION VARSON (X$)
VARSON = INSTR("CSPTG", X$)
END FUNCTION
FUNCTION VOWEL (X$)
VOWEL = INSTR("AEIOU", X$)
END FUNCTION
CLS
INPUT search$
search$ = LTRIM$(RTRIM$(UCASE$(search$)))
firstletter$ = LEFT$(search$, 1)
search$ = RIGHT$(search$, LEN(search$) - 1)
FOR i = 1 TO LEN(search$)
c$ = MID$(search$, i, 1)
SELECT CASE c$
CASE "B", "F", "P", "V"
soundex$ = soundex$ + "1"
CASE "C", "G", "J", "K", "Q", "S", "X", "Z"
soundex$ = soundex$ + "2"
CASE "D", "T"
soundex$ = soundex$ + "3"
CASE "L"
soundex$ = soundex$ + "4"
CASE "M", "N"
soundex$ = soundex$ + "5"
CASE "R"
soundex$ = soundex$ + "6"
END SELECT
NEXT
FOR i = 2 TO LEN(soundex$)
IF MID$(soundex$, i, 1) = MID$(soundex$, i - 1, 1) THEN
soundex$ = LEFT$(soundex$, i - 1) + MID$(soundex$, i + 1)
END IF
NEXT i
soundex$ = LEFT$(soundex$ + "00000", 5)
soundex$ = firstletter$ + soundex$
OPEN "DICT.DAT" FOR INPUT AS #1
OPEN "DICT2.DAT" FOR INPUT AS #2
OPEN "RESULTS.DAT" FOR OUTPUT AS #3
WHILE NOT (EOF(1))
INPUT #2, sndx$
INPUT #1, word$
IF sndx$ = soundex$ THEN PRINT #3, word$; " "
WEND
CLOSE #1
CLOSE #2
CLOSE #3
SHELL "FIND /I /C " + CHR$(34) + search$ + CHR$(32) + CHR$(34) + " results.dat > found"
OPEN "found" FOR INPUT AS #1
INPUT #1, line$
INPUT #1, line$
IF INSTR(line$, " 0") THEN SHELL "MORE RESULTS.DAT": END ELSE PRINT "IN DICTIONARY"
END
DECLARE FUNCTION FRONTV! (X$)
DECLARE FUNCTION SOUNDEX$ (NAME$)
DECLARE FUNCTION VARSON! (X$)
DECLARE FUNCTION VOWEL! (X$)
CLS
INPUT search$
search$ = LTRIM$(RTRIM$(UCASE$(search$)))
soundx$ = SOUNDEX$(search$)
OPEN "DICT.DAT" FOR INPUT AS #1
OPEN "DICT2.DAT" FOR INPUT AS #2
OPEN "RESULTS.DAT" FOR OUTPUT AS #3
WHILE NOT (EOF(1))
INPUT #2, sndx$
INPUT #1, word$
IF sndx$ = soundx$ THEN PRINT #3, word$; " "
WEND
CLOSE #1
CLOSE #2
CLOSE #3
SHELL "FIND /I /C " + CHR$(34) + search$ + CHR$(32) + CHR$(34) + " results.dat > found"
OPEN "found" FOR INPUT AS #1
INPUT #1, line$
INPUT #1, line$
IF INSTR(line$, " 0") THEN SHELL "MORE RESULTS.DAT": END ELSE PRINT "IN DICTIONARY"
END
FUNCTION FRONTV (X$)
FRONTV = INSTR("EIY", X$)
END FUNCTION
FUNCTION SOUNDEX$ (NAME$)
NAME$ = UCASE$(NAME$)
TWO$ = MID$(NAME$, 1, 2)
IF TWO$ = "PN" OR TWO$ = "AR" OR TWO$ = "KN" OR TWO$ = "GN" OR TWO$ = "WR" OR TWO$ = "AE" THEN NAME$ = MID$(NAME$, 2)
IF TWO$ = "WH" THEN NAME$ = "W" + MID$(NAME$, 3)
IF LEFT$(NAME$, 1) = "X" THEN NAME$ = "S" + MID$(NAME$, 2)
L = LEN(NAME$)
FOR I = 1 TO L
SYMB$ = MID$(NAME$, I, 1)
IF I > 1 THEN PREV$ = MID$(NAME$, I - 1, 1) ELSE PREV$ = "."
IF I > 2 THEN PREV2$ = MID$(NAME$, I - 2, 1) ELSE PREV2$ = "."
IF I < L THEN NEXT$ = MID$(NAME$, I + 1, 1) ELSE NEXT$ = "."
IF I < L - 1 THEN NEXT2$ = MID$(NAME$, I + 2, 1) ELSE NEXT2$ = ""
IF I < L - 2 THEN NEXT3$ = MID$(NAME$, I + 3, 1) ELSE NEXT3$ = ""
IF SYMB$ <> "C" AND I > 1 AND PREV$ = SYMB$ THEN NEW = 0 ELSE NEW = -1
IF NEW THEN
IF VOWEL(SYMB$) AND I = 1 THEN
METAPH$ = METAPH$ + SYMB$
ELSE
SELECT CASE SYMB$
CASE "B"
IF I = L AND PREV$ = "M" THEN SILENT = -1 ELSE SILENT = 0
IF NOT SILENT THEN METAPH$ = METAPH$ + "B"
CASE "C"
IF NOT (PREV$ = "S" AND FRONTV(NEXT$)) THEN
IF NEXT$ = "I" AND NEXT2$ = "A" THEN
METAPH$ = METAPH$ + "X"
ELSE
IF FRONTV(NEXT$) THEN
METAPH$ = METAPH$ + "S"
ELSEIF NEXT$ = "H" AND PREV$ = "S" THEN
METAPH$ = METAPH$ + "K"
ELSEIF NEXT$ = "H" THEN
IF I = 0 AND VOWEL(NEXT2$) = 0 THEN
METAPH$ = METAPH$ + "K"
ELSE
METAPH$ = METAPH$ + "X"
END IF
ELSE
METAPH$ = METAPH$ + "K"
END IF
END IF
END IF
CASE "D"
IF NEXT$ = "G" AND FRONTV(NEXT2$) THEN
METAPH$ = METAPH$ + "J"
ELSE
METAPH$ = METAPH$ + "T"
END IF
CASE "G"
IF NEXT$ = "H" AND VOWEL(NEXT2$) THEN SILENT = -1 ELSE SILENT = 0
IF (I + 1 = L OR (NEXT$ = "N" AND NEXT2$ = "E" AND NEXT3$ = "D")) AND NEXT$ = "N" THEN SILENT = -1
IF PREV$ = "G" THEN HARD = -1 ELSE HARD = 0
IF NOT SILENT THEN
IF FRONTV(NEXT$) AND NOT HARD THEN
METAPH$ = METAPH$ + "J"
ELSE
METAPH$ = METAPH$ + "K"
END IF
END IF
CASE "H"
IF VARSON(PREV$) AND VOWEL(NEXT$) THEN METAPH$ = METAPH$ + "H"
CASE "F", "J", "L", "M", "N", "R"
METAPH$ = METAPH$ + SYMB$
CASE "K"
IF PREV$ <> "C" THEN METAPH$ = METAPH$ + "K"
CASE "P"
IF NEXT$ = "H" THEN
METAPH$ = METAPH$ + "F"
ELSE
METAPH$ = METAPH$ + "K"
END IF
CASE "Q"
METAPH$ = METAPH$ + "K"
CASE "S"
IF NEXT$ = "I" AND (NEXT2$ = "O" OR NEXT2$ = "A") THEN
METAPH$ = METAPH$ + "X"
ELSEIF NEXT$ = "H" THEN
METAPH$ = MEATPH$ + "X"
ELSE
METAPH$ = METAPH$ + "S"
END IF
CASE "T"
IF NEXT$ = "I" AND (NEXT$ = "O" OR NEXT$ = "A") THEN
METAPH$ = METAPH$ + "X"
ELSEIF NEXT$ = "H" THEN
METAPH$ = METAPH$ + "0"
ELSEIF NOT (NEXT$ = "C" AND NEXT2$ = "H") THEN
METAPH$ = METAPH$ + "T"
END IF
CASE "V"
METAPH$ = METAPH$ + "F"
CASE "W", "Y"
IF VOWEL(NEXT$) THEN METAPH$ = METAPH$ + SYMB$
CASE "X"
METAPH$ = METAPH$ + "KS"
CASE "Z"
METAPH$ = METAPH$ + "S"
END SELECT
END IF
END IF
NEXT
SOUNDEX$ = METAPH$
END FUNCTION
FUNCTION VARSON (X$)
VARSON = INSTR("CSPTG", X$)
END FUNCTION
FUNCTION VOWEL (X$)
VOWEL = INSTR("AEIOU", X$)
END FUNCTION
DECLARE FUNCTION DISTANCE% (S$, T$)
DECLARE FUNCTION MINIMUM% (A%, B%, C%)
DEFINT A-Z
OPEN "DICT.DAT" FOR INPUT AS #1
OPEN "RESULTS.TMP" FOR OUTPUT AS #2
INPUT SEARCH$
SEARCH$ = LTRIM$(RTRIM$(UCASE$(SEARCH$)))
WHILE NOT EOF(1)
INPUT #1, WORD$
WORD$ = UCASE$(WORD$)
IF DISTANCE(WORD$, SEARCH$) < 2 THEN PRINT #2, WORD$; " "
WEND
CLOSE #1
CLOSE #2
SHELL "FIND /I /C " + CHR$(34) + SEARCH$ + CHR$(32) + CHR$(34) + " RESULTS.TMP > FOUND.TMP"
OPEN "FOUND.TMP" FOR INPUT AS #1
INPUT #1, LINE$: INPUT #1, LINE$
IF INSTR(LINE$, " 0") THEN SHELL "MORE RESULTS.TMP": END ELSE PRINT "IN DICTIONARY"
CLOSE #1
SHELL "DEL *.TMP"
END
FUNCTION DISTANCE (S$, T$)
' RETURNS THE LEVENSHTEIN DISTANCE BETWEEN TWO STRINGS
DIM D(0 TO LEN(S$), 0 TO LEN(T$))
FOR I = 0 TO LEN(S$)
D(I, 0) = I
NEXT
FOR J = 1 TO LEN(T$)
D(0, J) = J
NEXT
FOR I = 1 TO LEN(S$)
FOR J = 1 TO LEN(T$)
IF MID$(S$, I, 1) = MID$(T$, J, 1) THEN COST = 0 ELSE COST = 1
A = D(I - 1, J) + 1
IF J = LEN(T$) THEN B = 32767 ELSE B = D(I, J + 1) + 2
C = D(I - 1, J - 1) + COST
D(I, J) = MINIMUM(A, B, C)
NEXT
NEXT
DISTANCE = D(LEN(S$), LEN(T$))
END FUNCTION
FUNCTION MINIMUM (A, B, C)
IF A <= B AND A <= C THEN MINIMUM = A
IF B <= A AND B <= C THEN MINIMUM = B
IF C <= A AND C <= B THEN MINIMUM = C
END FUNCTION
SPELL.BAS -- Version 5: USES THE THE DAMERAU-LEVENSHTEIN DISTANCE
September 10 2007, 5:39 PM
DECLARE FUNCTION DISTANCE% (S$, T$)
DECLARE FUNCTION MINIMUM% (A%, B%, C%)
DEFINT A-Z
OPEN "DICT.DAT" FOR INPUT AS #1
OPEN "RESULTS.TMP" FOR OUTPUT AS #2
INPUT SEARCH$
SEARCH$ = LTRIM$(RTRIM$(UCASE$(SEARCH$)))
WHILE NOT EOF(1)
INPUT #1, WORD$
WORD$ = UCASE$(WORD$)
IF DISTANCE(WORD$, SEARCH$) < 2 THEN PRINT #2, WORD$; " "
WEND
CLOSE #1
CLOSE #2
SHELL "FIND /I /C " + CHR$(34) + SEARCH$ + CHR$(32) + CHR$(34) + " RESULTS.TMP > FOUND.TMP"
OPEN "FOUND.TMP" FOR INPUT AS #1
INPUT #1, LINE$: INPUT #1, LINE$
IF INSTR(LINE$, " 0") THEN SHELL "MORE RESULTS.TMP": END ELSE PRINT "IN DICTIONARY"
CLOSE #1
SHELL "DEL *.TMP"
END
FUNCTION DISTANCE (S$, T$)
' RETURNS THE DAMERAU-LEVENSHTEIN DISTANCE BETWEEN TWO STRINGS
DIM D(0 TO LEN(S$), 0 TO LEN(T$))
FOR I = 0 TO LEN(S$)
D(I, 0) = I
NEXT
FOR J = 1 TO LEN(T$)
D(0, J) = J
NEXT
FOR I = 1 TO LEN(S$)
FOR J = 1 TO LEN(T$)
IF MID$(S$, I, 1) = MID$(T$, J, 1) THEN COST = 0 ELSE COST = 1
A = D(I - 1, J) + 1
IF J = LEN(T$) THEN B = 32767 ELSE B = D(I, J + 1) + 2
C = D(I - 1, J - 1) + COST
D(I, J) = MINIMUM(A, B, C)
IF I > 1 AND J > 1 THEN IF MID$(S$, I, 1) = MID$(T$, J - 1, 1) AND MID$(S$, I - 1, 1) = MID$(T$, J, 1) THEN D(I, J) = MINIMUM(D(I, J), D(I - 2, J - 2) + COST, 32767)
NEXT
NEXT
DISTANCE = D(LEN(S$), LEN(T$))
END FUNCTION
FUNCTION MINIMUM (A, B, C)
IF A <= B AND A <= C THEN MINIMUM = A
IF B <= A AND B <= C THEN MINIMUM = B
IF C <= A AND C <= B THEN MINIMUM = C
END FUNCTION
DECLARE FUNCTION DISTANCE% (S$, T$)
DECLARE FUNCTION MINIMUM% (A%, B%, C%)
DEFINT A-Z
CONST ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
INPUT "FILE"; FILE$
INPUT "OUTFILE"; OUT$
OPEN FILE$ FOR INPUT AS #1
OPEN OUT$ FOR OUTPUT AS #2
WHILE NOT EOF(1)
I = 1
LINE INPUT #1, X$
WHILE RTRIM$(LTRIM$(X$)) <> ""
A$ = ""
B$ = ""
I = INSTR(X$, " ")
W$ = LEFT$(X$, I)
X$ = MID$(X$, I + 1)
IF I = 0 THEN W$ = X$: X$ = ""
FOR J = 1 TO LEN(W$)
IF INSTR(ALPHABET, MID$(W$, J, 1)) THEN EXIT FOR
A$ = A$ + MID$(W$, J, 1)
NEXT
W2$ = W$
W$ = MID$(W$, J)
FOR J = LEN(W$) TO 1 STEP -1
IF INSTR(ALPHABET, MID$(W$, J, 1)) THEN EXIT FOR
B$ = MID$(W$, J, 1) + B$
NEXT
W$ = LEFT$(W$, J)
CAPS = 0
IF W$ = UCASE$(W$) THEN
CAPS = 1
ELSEIF W$ = UCASE$(LEFT$(W$, 1)) + LCASE$(MID$(W$, 2)) THEN
CAPS = 2
END IF
W$ = LCASE$(W$)
REDIM SUGGEST$(0 TO 9)
Z = 0
PRINT W$; CHR$(32);
IF W$ = "" THEN PRINT #2, W2$; : GOTO 1
OPEN "DICT.DAT" FOR INPUT AS #3
WHILE NOT (EOF(3))
LINE INPUT #3, WORD$
SELECT CASE DISTANCE(WORD$, W$)
CASE 0
PRINT #2, W2$;
CLOSE #3
GOTO 1
CASE 1
IF Z <= 9 THEN
SUGGEST$(Z) = WORD$
Z = Z + 1
END IF
END SELECT
WEND
GOTO 2
1 GOTO 3
2 CLOSE #3
PRINT
PRINT W$; " is not in dictionary. Select number or -1 to suggest"
FOR I = 0 TO Z - 1
PRINT I; SUGGEST$(I)
NEXT
XYZ$ = ""
DO UNTIL XYZ$ <> "" AND VAL(XYZ$) > -2 AND VAL(XYZ$) < 10
INPUT XYZ$
LOOP
IF VAL(XYZ$) = -1 THEN LINE INPUT SUGGEST$(0): Z = 0 ELSE Z = VAL(XYZ$)
W$ = SUGGEST$(Z)
SELECT CASE CAPS
CASE 1
W$ = UCASE$(W$)
CASE 2
W$ = UCASE$(LEFT$(W$, 1)) + LCASE$(MID$(W$, 2))
END SELECT
PRINT #2, A$ + W$ + B$;
3 WEND
PRINT #2, ""
WEND
CLOSE
FUNCTION DISTANCE (S$, T$)
' RETURNS THE DAMERAU-LEVENSHTEIN DISTANCE BETWEEN TWO STRINGS
DIM D(0 TO LEN(S$), 0 TO LEN(T$))
IF S$ = T$ THEN DISTANCE = 0: EXIT FUNCTION
FOR I = 0 TO LEN(S$)
D(I, 0) = I
NEXT
FOR J = 1 TO LEN(T$)
D(0, J) = J
NEXT
FOR I = 1 TO LEN(S$)
FOR J = 1 TO LEN(T$)
IF MID$(S$, I, 1) = MID$(T$, J, 1) THEN COST = 0 ELSE COST = 1
A = D(I - 1, J) + 1
IF J = LEN(T$) THEN B = 32767 ELSE B = D(I, J + 1) + 2
C = D(I - 1, J - 1) + COST
D(I, J) = MINIMUM(A, B, C)
IF I > 1 AND J > 1 THEN IF MID$(S$, I, 1) = MID$(T$, J - 1, 1) AND MID$(S$, I - 1, 1) = MID$(T$, J, 1) THEN D(I, J) = MINIMUM(D(I, J), D(I - 2, J - 2) + COST, 32767)
NEXT
NEXT
DISTANCE = D(LEN(S$), LEN(T$))
END FUNCTION
FUNCTION MINIMUM (A, B, C)
IF A <= B AND A <= C THEN MINIMUM = A
IF B <= A AND B <= C THEN MINIMUM = B
IF C <= A AND C <= B THEN MINIMUM = C
END FUNCTION
DECLARE SUB AI ()
DECLARE SUB PLAYGAME ()
DECLARE SUB MOVEPILE (N%, START%, FINISH%)
DECLARE SUB MOVEDISK (START%, FINISH%)
DECLARE SUB SHOWDISKS ()
DEFINT A-Z
CONST NUMDISKS = 8
DIM SHARED TOWERS(0 TO 2, 1 TO NUMDISKS), TOP(0 TO 2), COLORS(1 TO NUMDISKS)
CLS
TOP(0) = NUMDISKS: TOP(1) = 0: TOP(2) = 0
FOR I = 1 TO NUMDISKS
TOWERS(0, I) = NUMDISKS - I + 1
READ COLORS(I)
NEXT
DATA 6, 9, 4, 10, 11, 12, 13, 14
DATA 6, 9, 4, 10, 11, 12, 13, 14
LOCATE 1, 26
PRINT CHR$(218); STRING$(14, CHR$(196)); CHR$(191)
LOCATE 2, 26
PRINT CHR$(179); "TOWER OF HANOI"; CHR$(179)
LOCATE 3, 26
PRINT CHR$(192); STRING$(14, CHR$(196)); CHR$(217)
PRINT STRING$(80, CHR$(196))
PRINT
PRINT "1: AI"
PRINT "2: HUMAN"
PRINT STRING$(20, CHR$(196))
WHILE CHOICE <> 1 AND CHOICE <> 2
INPUT "CHOOSE ONE: ", CHOICE
WEND
IF CHOICE = 1 THEN CALL AI ELSE CALL PLAYGAME
SUB AI
CALL SHOWDISKS
CALL MOVEPILE(8, 0, 2)
END SUB
SUB MOVEDISK (START, FINISH)
TOWERS(FINISH, TOP(FINISH) + 1) = TOWERS(START, TOP(START))
TOP(FINISH) = TOP(FINISH) + 1
TOWERS(START, TOP(START)) = 0
TOP(START) = TOP(START) - 1
CALL SHOWDISKS
T! = TIMER
WHILE TIMER - T! < .2:
IF INKEY$ = CHR$(27) THEN END
WEND
END SUB
SUB MOVEPILE (N, START, FINISH)
IF N > 1 THEN CALL MOVEPILE(N - 1, START, 3 - START - FINISH)
CALL MOVEDISK(START, FINISH)
IF N > 1 THEN CALL MOVEPILE(N - 1, 3 - START - FINISH, FINISH)
END SUB
SUB PLAYGAME
CALL SHOWDISKS
DO
LOCATE 1, 1
COLOR 7
PRINT "TYPE NUMBER OF START PEG FOLLOWED BY NUMBER OF END PEG"
PRINT "LEFT = 1", "MIDDLE = 2", "RIGHT=3"
DO
KEY$ = INKEY$
SELECT CASE KEY$
CASE CHR$(27)
END
CASE "1"
START = 0
EXIT DO
CASE "2"
START = 1
EXIT DO
CASE "3"
START = 2
EXIT DO
END SELECT
LOOP
DO
KEY$ = INKEY$
SELECT CASE KEY$
CASE CHR$(27)
END
CASE "1"
FINISH = 0
EXIT DO
CASE "2"
FINISH = 1
EXIT DO
CASE "3"
FINISH = 2
EXIT DO
END SELECT
LOOP
IF TOP(FINISH) > 0 THEN
IF TOWERS(START, TOP(START)) >= TOWERS(FINISH, TOP(FINISH)) THEN GOTO 1
END IF
CALL MOVEDISK(START, FINISH)
IF TOP(0) = 0 AND TOP(1) = 0 THEN EXIT DO
IF TOP(0) = 0 AND TOP(2) = 0 THEN EXIT DO
1 LOOP
END SUB
SUB SHOWDISKS
CLS
LOCATE 25, 1
PRINT STRING$(80, CHR$(196));
FOR I = 1 TO TOP(0)
LOCATE 25 - I, I + 1
X = TOWERS(0, I)
IF X = 0 THEN EXIT FOR
COLOR COLORS(X): PRINT STRING$(X * 2, CHR$(219));
NEXT
FOR I = 1 TO TOP(1)
LOCATE 25 - I, I + NUMDISKS * 3
X = TOWERS(1, I)
IF X = 0 THEN EXIT FOR
COLOR COLORS(X): PRINT STRING$(X * 2, CHR$(219));
NEXT
FOR I = 1 TO TOP(2)
LOCATE 25 - I, I + NUMDISKS * 6
X = TOWERS(2, I)
IF X = 0 THEN EXIT FOR
COLOR COLORS(X): PRINT STRING$(X * 2, CHR$(219));
NEXT
DECLARE SUB AUTO ()
DECLARE SUB PLAYGAME ()
DECLARE SUB MOVEPILE (N%, START%, FINISH%)
DECLARE SUB MOVEDISK (START%, FINISH%)
DECLARE SUB SHOWDISKS ()
DEFINT A-Z
CONST NUMDISKS = 8
DIM SHARED TOWERS(0 TO 2, 1 TO NUMDISKS), TOP(0 TO 2), COLORS(1 TO NUMDISKS)
CLS
TOP(0) = NUMDISKS: TOP(1) = 0: TOP(2) = 0
FOR I = 1 TO NUMDISKS
TOWERS(0, I) = NUMDISKS - I + 1
READ COLORS(I)
NEXT
DATA 6, 9, 4, 10, 11, 12, 13, 14
DATA 6, 9, 4, 10, 11, 12, 13, 14
LOCATE 1, 26
PRINT CHR$(218); STRING$(14, CHR$(196)); CHR$(191)
LOCATE 2, 26
PRINT CHR$(179); "TOWER OF HANOI"; CHR$(179)
LOCATE 3, 26
PRINT CHR$(192); STRING$(14, CHR$(196)); CHR$(217)
PRINT STRING$(80, CHR$(196))
PRINT
PRINT "1: AUTO"
PRINT "2: HUMAN"
PRINT STRING$(20, CHR$(196))
WHILE CHOICE <> 1 AND CHOICE <> 2
INPUT "CHOOSE ONE: ", CHOICE
WEND
IF CHOICE = 1 THEN CALL AUTO ELSE CALL PLAYGAME
SUB AUTO
CALL SHOWDISKS
CALL MOVEPILE(8, 0, 2)
END SUB
SUB MOVEDISK (START, FINISH)
TOWERS(FINISH, TOP(FINISH) + 1) = TOWERS(START, TOP(START))
TOP(FINISH) = TOP(FINISH) + 1
TOWERS(START, TOP(START)) = 0
TOP(START) = TOP(START) - 1
CALL SHOWDISKS
T! = TIMER
WHILE TIMER - T! < .2:
IF INKEY$ = CHR$(27) THEN END
WEND
END SUB
SUB MOVEPILE (N, START, FINISH)
IF N > 1 THEN CALL MOVEPILE(N - 1, START, 3 - START - FINISH)
CALL MOVEDISK(START, FINISH)
IF N > 1 THEN CALL MOVEPILE(N - 1, 3 - START - FINISH, FINISH)
END SUB
SUB PLAYGAME
CALL SHOWDISKS
DO
LOCATE 1, 1
COLOR 7
PRINT "TYPE NUMBER OF START PEG FOLLOWED BY NUMBER OF END PEG"
PRINT "LEFT = 1", "MIDDLE = 2", "RIGHT=3"
DO
KEY$ = INKEY$
SELECT CASE KEY$
CASE CHR$(27)
END
CASE "1"
START = 0
EXIT DO
CASE "2"
START = 1
EXIT DO
CASE "3"
START = 2
EXIT DO
END SELECT
LOOP
DO
KEY$ = INKEY$
SELECT CASE KEY$
CASE CHR$(27)
END
CASE "1"
FINISH = 0
EXIT DO
CASE "2"
FINISH = 1
EXIT DO
CASE "3"
FINISH = 2
EXIT DO
END SELECT
LOOP
IF TOP(START) = 0 THEN GOTO 1
IF TOP(FINISH) > 0 THEN
IF TOWERS(START, TOP(START)) >= TOWERS(FINISH, TOP(FINISH)) THEN GOTO 1
END IF
CALL MOVEDISK(START, FINISH)
IF TOP(0) = 0 AND TOP(1) = 0 THEN EXIT DO
IF TOP(0) = 0 AND TOP(2) = 0 THEN EXIT DO
1 LOOP
END SUB
SUB SHOWDISKS
CLS
LOCATE 25, 1
PRINT STRING$(80, CHR$(196));
FOR I = 1 TO TOP(0)
LOCATE 25 - I, I + 1
X = TOWERS(0, I)
IF X = 0 THEN EXIT FOR
COLOR COLORS(X): PRINT STRING$(X * 2, CHR$(219));
NEXT
FOR I = 1 TO TOP(1)
LOCATE 25 - I, I + NUMDISKS * 3
X = TOWERS(1, I)
IF X = 0 THEN EXIT FOR
COLOR COLORS(X): PRINT STRING$(X * 2, CHR$(219));
NEXT
FOR I = 1 TO TOP(2)
LOCATE 25 - I, I + NUMDISKS * 6
X = TOWERS(2, I)
IF X = 0 THEN EXIT FOR
COLOR COLORS(X): PRINT STRING$(X * 2, CHR$(219));
NEXT
DECLARE SUB INSTRUCT ()
DECLARE SUB AUTO ()
DECLARE SUB PLAYGAME ()
DECLARE SUB MOVEPILE (N%, START%, FINISH%)
DECLARE SUB MOVEDISC (START%, FINISH%)
DECLARE SUB SHOWDISCS ()
DEFINT A-Z
CONST NUMDISCS = 8
DIM SHARED TOWERS(0 TO 2, 1 TO NUMDISCS), TOP(0 TO 2), COLORS(1 TO NUMDISCS), NUMMOVES AS LONG
CLS
TOP(0) = NUMDISCS: TOP(1) = 0: TOP(2) = 0
FOR I = 1 TO NUMDISCS
TOWERS(0, I) = NUMDISCS - I + 1
READ COLORS(I)
NEXT
DATA 6, 9, 4, 10, 11, 12, 13, 14
DATA 6, 9, 4, 10, 11, 12, 13, 14
LOCATE 1, 26
PRINT CHR$(218); STRING$(14, CHR$(196)); CHR$(191)
LOCATE 2, 26
PRINT CHR$(179); "TOWER OF HANOI"; CHR$(179)
LOCATE 3, 26
PRINT CHR$(192); STRING$(14, CHR$(196)); CHR$(217)
PRINT STRING$(80, CHR$(196))
PRINT
PRINT "1: AUTO"
PRINT "2: HUMAN"
PRINT STRING$(20, CHR$(196))
WHILE CHOICE <> 1 AND CHOICE <> 2
INPUT "CHOOSE ONE: ", CHOICE
WEND
IF CHOICE = 1 THEN CALL AUTO ELSE CALL PLAYGAME
SUB AUTO
CALL SHOWDISCS
CALL MOVEPILE(8, 0, 2)
END SUB
SUB INSTRUCT
PRINT "The TOWER OF HANOI is a mathematical game or puzzle. It consists"
PRINT "of three pegs and a number of discs which can slide onto any peg."
PRINT "The puzzle starts with the discs stacked in order of size on one peg."
PRINT
PRINT "The object of the game is to move the entire stack onto another peg,"
PRINT "obeying the following rules:"
PRINT TAB(2); CHR$(248); " Only one disc may be moved at a time."
PRINT TAB(2); CHR$(248); " Each move consists of taking the upper disc from"
PRINT TAB(4); "one peg and sliding it onto another peg, on top of any discs"
PRINT TAB(4); "that may already be on that peg."
PRINT TAB(2); CHR$(248); " No disc may be placed on top of another disc."
PRINT "PRESS ANY KEY TO CONTINUE..."
NULL$ = INPUT$(1)
END SUB
SUB MOVEDISC (START, FINISH)
DIM T AS SINGLE
TOWERS(FINISH, TOP(FINISH) + 1) = TOWERS(START, TOP(START))
TOP(FINISH) = TOP(FINISH) + 1
TOWERS(START, TOP(START)) = 0
TOP(START) = TOP(START) - 1
NUMMOVES = NUMMOVES + 1
CALL SHOWDISCS
T = TIMER
WHILE TIMER - T < .2:
IF INKEY$ = CHR$(27) THEN END
WEND
END SUB
SUB MOVEPILE (N, START, FINISH)
IF N > 1 THEN CALL MOVEPILE(N - 1, START, 3 - START - FINISH)
CALL MOVEDISC(START, FINISH)
IF N > 1 THEN CALL MOVEPILE(N - 1, 3 - START - FINISH, FINISH)
END SUB
SUB PLAYGAME
DO
INPUT "WOULD YOU LIKE INSTRUCTIONS"; NULL$
NULL$ = UCASE$(LEFT$(LTRIM$(NULL$), 1))
IF NULL$ = "Y" THEN CALL INSTRUCT: EXIT DO
IF NULL$ = "N" THEN EXIT DO
LOOP
CALL SHOWDISCS
DO
LOCATE 1, 1
COLOR 7
PRINT "TYPE NUMBER OF START PEG FOLLOWED BY NUMBER OF END PEG"
PRINT "LEFT = 1", "MIDDLE = 2", "RIGHT=3"
DO
KEY$ = INKEY$
SELECT CASE KEY$
CASE CHR$(27)
END
CASE "1"
START = 0
EXIT DO
CASE "2"
START = 1
EXIT DO
CASE "3"
START = 2
EXIT DO
END SELECT
LOOP
DO
KEY$ = INKEY$
SELECT CASE KEY$
CASE CHR$(27)
END
CASE "1"
FINISH = 0
EXIT DO
CASE "2"
FINISH = 1
EXIT DO
CASE "3"
FINISH = 2
EXIT DO
END SELECT
LOOP
IF TOP(START) = 0 THEN PRINT "There are no discs on that peg.": GOTO 1
IF START = FINISH THEN PRINT "The start peg is the same as the end peg.": GOTO 1
IF TOP(FINISH) > 0 THEN
IF TOWERS(START, TOP(START)) > TOWERS(FINISH, TOP(FINISH)) THEN PRINT "You may not put a larger disc on top of a smaller disc.": GOTO 1
END IF
CALL MOVEDISC(START, FINISH)
IF TOP(0) = 0 AND TOP(1) = 0 THEN EXIT DO
IF TOP(0) = 0 AND TOP(2) = 0 THEN EXIT DO
1 LOOP
END SUB
SUB SHOWDISCS
CLS
LOCATE 1, 60: PRINT "MOVES: "; NUMMOVES
LOCATE 25, 1
PRINT STRING$(80, CHR$(196));
FOR I = 1 TO TOP(0)
LOCATE 25 - I, I + 1
X = TOWERS(0, I)
IF X = 0 THEN EXIT FOR
COLOR COLORS(X): PRINT STRING$(X * 2, CHR$(219));
NEXT
FOR I = 1 TO TOP(1)
LOCATE 25 - I, I + NUMDISCS * 3
X = TOWERS(1, I)
IF X = 0 THEN EXIT FOR
COLOR COLORS(X): PRINT STRING$(X * 2, CHR$(219));
NEXT
FOR I = 1 TO TOP(2)
LOCATE 25 - I, I + NUMDISCS * 6
X = TOWERS(2, I)
IF X = 0 THEN EXIT FOR
COLOR COLORS(X): PRINT STRING$(X * 2, CHR$(219));
NEXT
TOWER OF HANOI FOR DUMB PLAYERS -- PROFESSIONAL EDITION
February 6 2008, 2:34 PM
DECLARE SUB INSTRUCT ()
DECLARE SUB AUTO ()
DECLARE SUB PLAYGAME ()
DECLARE SUB MOVEPILE (N%, START%, FINISH%)
DECLARE SUB MOVEDISC (START%, FINISH%)
DECLARE SUB SHOWDISCS ()
DEFINT A-Z
CONST NUMDISCS = 8 ' alter this line to change number of discs
DIM SHARED TOWERS(0 TO 2, 1 TO NUMDISCS), TOP(0 TO 2), COLORS(1 TO NUMDISCS), NUMMOVES AS LONG
CLS
TOP(0) = NUMDISCS: TOP(1) = 0: TOP(2) = 0
FOR I = 1 TO NUMDISCS
TOWERS(0, I) = NUMDISCS - I + 1
READ COLORS(I)
NEXT
DATA 6, 9, 4, 10, 11, 12, 13, 14
DATA 6, 9, 4, 10, 11, 12, 13, 14
LOCATE 1, 26
PRINT CHR$(218); STRING$(14, CHR$(196)); CHR$(191)
LOCATE 2, 26
PRINT CHR$(179); "TOWER OF HANOI"; CHR$(179)
LOCATE 3, 26
PRINT CHR$(192); STRING$(14, CHR$(196)); CHR$(217)
PRINT STRING$(80, CHR$(196))
PRINT
PRINT "1: AUTO"
PRINT "2: HUMAN"
PRINT STRING$(20, CHR$(196))
WHILE CHOICE <> 1 AND CHOICE <> 2
INPUT "CHOOSE ONE: ", CHOICE
WEND
IF CHOICE = 1 THEN CALL AUTO ELSE CALL PLAYGAME
SUB AUTO
CALL SHOWDISCS
CALL MOVEPILE(NUMDISCS, 0, 2)
END SUB
SUB INSTRUCT
PRINT "The TOWER OF HANOI is a mathematical game or puzzle. It consists"
PRINT "of three pegs and a number of discs which can slide onto any peg."
PRINT "The puzzle starts with the discs stacked in order of size on one peg."
PRINT
PRINT "The object of the game is to move the entire stack onto another peg,"
PRINT "obeying the following rules:"
PRINT TAB(2); CHR$(248); " Only one disc may be moved at a time."
PRINT TAB(2); CHR$(248); " Each move consists of taking the upper disc from"
PRINT TAB(4); "one peg and sliding it onto another peg, on top of any discs"
PRINT TAB(4); "that may already be on that peg."
PRINT TAB(2); CHR$(248); " No disc may be placed on top of another disc."
PRINT "PRESS ANY KEY TO CONTINUE..."
NULL$ = INPUT$(1)
END SUB
SUB MOVEDISC (START, FINISH)
DIM T AS SINGLE
TOWERS(FINISH, TOP(FINISH) + 1) = TOWERS(START, TOP(START))
TOP(FINISH) = TOP(FINISH) + 1
TOWERS(START, TOP(START)) = 0
TOP(START) = TOP(START) - 1
NUMMOVES = NUMMOVES + 1
CALL SHOWDISCS
T = TIMER
WHILE TIMER - T < .2:
IF INKEY$ = CHR$(27) THEN END
WEND
END SUB
SUB MOVEPILE (N, START, FINISH)
IF N > 1 THEN CALL MOVEPILE(N - 1, START, 3 - START - FINISH)
CALL MOVEDISC(START, FINISH)
IF N > 1 THEN CALL MOVEPILE(N - 1, 3 - START - FINISH, FINISH)
END SUB
SUB PLAYGAME
DO
INPUT "WOULD YOU LIKE INSTRUCTIONS"; NULL$
NULL$ = UCASE$(LEFT$(LTRIM$(NULL$), 1))
IF NULL$ = "Y" THEN CALL INSTRUCT: EXIT DO
IF NULL$ = "N" THEN EXIT DO
LOOP
CALL SHOWDISCS
DO
LOCATE 1, 1
COLOR 7
PRINT "TYPE NUMBER OF START PEG FOLLOWED BY NUMBER OF END PEG"
PRINT "LEFT = 1", "MIDDLE = 2", "RIGHT=3"
DO
KEY$ = INKEY$
SELECT CASE KEY$
CASE CHR$(27)
END
CASE "1"
START = 0
EXIT DO
CASE "2"
START = 1
EXIT DO
CASE "3"
START = 2
EXIT DO
END SELECT
LOOP
DO
KEY$ = INKEY$
SELECT CASE KEY$
CASE CHR$(27)
END
CASE "1"
FINISH = 0
EXIT DO
CASE "2"
FINISH = 1
EXIT DO
CASE "3"
FINISH = 2
EXIT DO
END SELECT
LOOP
IF TOP(START) = 0 THEN PRINT "There are no discs on that peg.": GOTO 1
IF START = FINISH THEN PRINT "The start peg is the same as the end peg.": GOTO 1
IF TOP(FINISH) > 0 THEN
IF TOWERS(START, TOP(START)) > TOWERS(FINISH, TOP(FINISH)) THEN PRINT "You may not put a larger disc on top of a smaller disc.": GOTO 1
END IF
CALL MOVEDISC(START, FINISH)
IF TOP(0) = 0 AND TOP(1) = 0 THEN EXIT DO
IF TOP(0) = 0 AND TOP(2) = 0 THEN EXIT DO
1 LOOP
END SUB
SUB SHOWDISCS
CLS
LOCATE 1, 60: PRINT "MOVES: "; NUMMOVES
LOCATE 25, 1
PRINT STRING$(80, CHR$(196));
FOR I = 1 TO TOP(0)
LOCATE 25 - I, I + 1
X = TOWERS(0, I)
IF X = 0 THEN EXIT FOR
COLOR COLORS(X): PRINT STRING$(X * 2, CHR$(219));
NEXT
FOR I = 1 TO TOP(1)
LOCATE 25 - I, I + NUMDISCS * 3
X = TOWERS(1, I)
IF X = 0 THEN EXIT FOR
COLOR COLORS(X): PRINT STRING$(X * 2, CHR$(219));
NEXT
FOR I = 1 TO TOP(2)
LOCATE 25 - I, I + NUMDISCS * 6
X = TOWERS(2, I)
IF X = 0 THEN EXIT FOR
COLOR COLORS(X): PRINT STRING$(X * 2, CHR$(219));
NEXT
Spell Checker -- Version 6 (DAMERAU-LEVENSHTEIN DISTANCE)
September 10 2007, 6:48 PM
DECLARE FUNCTION DISTANCE% (S$, T$)
DECLARE FUNCTION MINIMUM% (A%, B%, C%)
DEFINT A-Z
OPEN "DICT.DAT" FOR INPUT AS #1
OPEN "RESULTS.TMP" FOR OUTPUT AS #2
INPUT SEARCH$
SEARCH$ = LTRIM$(RTRIM$(UCASE$(SEARCH$)))
WHILE NOT EOF(1)
INPUT #1, WORD$
WORD$ = UCASE$(WORD$)
IF DISTANCE(WORD$, SEARCH$) < 3 THEN PRINT #2, WORD$; " "
WEND
CLOSE #1
CLOSE #2
SHELL "FIND /I /C " + CHR$(34) + SEARCH$ + CHR$(32) + CHR$(34) + " RESULTS.TMP > FOUND.TMP"
OPEN "FOUND.TMP" FOR INPUT AS #1
INPUT #1, LINE$: INPUT #1, LINE$
IF INSTR(LINE$, " 0") THEN SHELL "MORE RESULTS.TMP": END ELSE PRINT "IN DICTIONARY"
CLOSE #1
SHELL "DEL *.TMP"
END
FUNCTION DISTANCE (S$, T$)
' RETURNS THE DAMERAU-LEVENSHTEIN DISTANCE BETWEEN TWO STRINGS
DIM D(0 TO LEN(S$), 0 TO LEN(T$))
FOR I = 0 TO LEN(S$)
D(I, 0) = I
NEXT
FOR J = 1 TO LEN(T$)
D(0, J) = J
NEXT
FOR I = 1 TO LEN(S$)
FOR J = 1 TO LEN(T$)
IF MID$(S$, I, 1) = MID$(T$, J, 1) THEN COST = 0 ELSE COST = 1
A = D(I - 1, J) + 1
IF J = LEN(T$) THEN B = 32767 ELSE B = D(I, J - 1) + 1
C = D(I - 1, J - 1) + COST
D(I, J) = MINIMUM(A, B, C)
IF I > 1 AND J > 1 THEN
IF MID$(S$, I, 1) = MID$(T$, J - 1, 1) AND MID$(S$, I - 1, 1) = MID$(T$, J, 1) THEN
D(I, J) = MINIMUM(D(I, J), D(I - 2, J - 2) + COST, 32767)
END IF
END IF
NEXT
NEXT
DISTANCE = D(LEN(S$), LEN(T$))
END FUNCTION
FUNCTION MINIMUM (A, B, C)
MI = A
IF B < MI THEN MI = B
IF C < MI THEN MI = C
MINIMUM = MI
END FUNCTION
DECLARE SUB SCRAMBLE ()
DECLARE SUB GIVEUP ()
DECLARE SUB UP ()
DECLARE SUB DOWN ()
DECLARE SUB ROTATE (ROW%)
DEFINT A-Z
DIM SHARED PUZZLE(0 TO 5, 0 TO 5)
DIM COLORS(-1 TO 5)
CLS
FOR I = 0 TO 5
READ COLORS(I)
FOR J = 0 TO 5
PUZZLE(I, J) = J
NEXT
NEXT
DATA 8, 15, 12, 14, 10, 9
PUZZLE(5, 5) = -1
DO
CLS
FOR I = 0 TO 5
PRINT I + 1;
FOR J = 0 TO 5
COLOR COLORS(PUZZLE(I, J))
PRINT CHR$(219);
NEXT
COLOR 7: PRINT
NEXT
PRINT
PRINT "Instructions:"
PRINT STRING$(13, 196)
PRINT " "; CHR$(254); " The object of the game is to restore the puzzle back to its initial state"
PRINT SPACE$(3); "from a scrambled state."
PRINT " "; CHR$(254); " To scramble the puzzle, press S."
PRINT " "; CHR$(254); " To give up and reset the puzzle, type R."
PRINT " "; CHR$(254); " To shift a row right, press the number of that row."
PRINT " "; CHR$(254); " To move a tile up into the blank space, press the up arrow key."
PRINT " "; CHR$(254); " To move a tile down into the blank space, press the down arrow key."
N$ = ""
WHILE N$ = ""
N$ = INKEY$
WEND
SELECT CASE N$
CASE "R", "r"
CALL GIVEUP
CASE "S", "s"
CALL SCRAMBLE
CASE "1"
CALL ROTATE(0)
CASE "2"
CALL ROTATE(1)
CASE "3"
CALL ROTATE(2)
CASE "4"
CALL ROTATE(3)
CASE "5"
CALL ROTATE(4)
CASE "6"
CALL ROTATE(5)
CASE CHR$(0) + CHR$(72)
CALL UP
CASE CHR$(0) + CHR$(80)
CALL DOWN
CASE CHR$(27)
END
END SELECT
LOOP
SUB DOWN
FOR I = 0 TO 5
FOR J = 0 TO 5
K = PUZZLE(I, J)
IF K = -1 THEN GOTO 2
NEXT
NEXT
2 IF I = 0 THEN EXIT SUB
SWAP PUZZLE(I - 1, J), PUZZLE(I, J)
END SUB
SUB GIVEUP
FOR I = 0 TO 5
FOR J = 0 TO 5
PUZZLE(I, J) = J
NEXT
NEXT
PUZZLE(5, 5) = -1
END SUB
SUB ROTATE (ROW)
FOR I = 1 TO 5
SWAP PUZZLE(ROW, 0), PUZZLE(ROW, I)
NEXT
END SUB
SUB SCRAMBLE
FOR I = 1 TO 1000
J = INT(RND(1) * 7)
SELECT CASE J
CASE 0 TO 5
CALL ROTATE(J)
CASE 6
CALL UP
CASE 7
CALL DOWN
END SELECT
NEXT
END SUB
SUB UP
FOR I = 0 TO 5
FOR J = 0 TO 5
K = PUZZLE(I, J)
IF K = -1 THEN GOTO 1
NEXT
NEXT
1 IF I = 5 THEN EXIT SUB
SWAP PUZZLE(I + 1, J), PUZZLE(I, J)
END SUB
DECLARE SUB SCRAMBLE ()
DECLARE SUB GIVEUP ()
DECLARE SUB UP ()
DECLARE SUB DOWN ()
DECLARE SUB ROTATE (ROW%)
DEFINT A-Z
DIM SHARED PUZZLE(0 TO 5, 0 TO 5)
DIM COLORS(-1 TO 5)
CLS
FOR I = 0 TO 5
READ COLORS(I)
FOR J = 0 TO 5
PUZZLE(I, J) = J
NEXT
NEXT
DATA 8, 15, 12, 14, 10, 9
PUZZLE(5, 5) = -1
DO
CLS
FOR I = 0 TO 5
PRINT I + 1;
FOR J = 0 TO 5
COLOR COLORS(PUZZLE(I, J))
PRINT CHR$(219);
NEXT
COLOR 7: PRINT
NEXT
PRINT
PRINT "Instructions:"
PRINT STRING$(13, 196)
PRINT " "; CHR$(254); " The object of the game is to restore the puzzle back to its initial state"
PRINT SPACE$(3); "from a scrambled state."
PRINT " "; CHR$(254); " To scramble the puzzle, press S."
PRINT " "; CHR$(254); " To give up and reset the puzzle, type R."
PRINT " "; CHR$(254); " To shift a row right, press the number of that row."
PRINT " "; CHR$(254); " To move a tile up into the blank space, press the up arrow key."
PRINT " "; CHR$(254); " To move a tile down into the blank space, press the down arrow key."
N$ = ""
WHILE N$ = ""
N$ = INKEY$
WEND
SELECT CASE N$
CASE "R", "r"
CALL GIVEUP
CASE "S", "s"
CALL SCRAMBLE
CASE "1"
CALL ROTATE(0)
CASE "2"
CALL ROTATE(1)
CASE "3"
CALL ROTATE(2)
CASE "4"
CALL ROTATE(3)
CASE "5"
CALL ROTATE(4)
CASE "6"
CALL ROTATE(5)
CASE CHR$(0) + CHR$(72)
CALL UP
CASE CHR$(0) + CHR$(80)
CALL DOWN
CASE CHR$(27)
END
END SELECT
LOOP
SUB DOWN
FOR I = 0 TO 5
FOR J = 0 TO 5
K = PUZZLE(I, J)
IF K = -1 THEN GOTO 2
NEXT
NEXT
2 IF I = 0 THEN EXIT SUB
SWAP PUZZLE(I - 1, J), PUZZLE(I, J)
END SUB
SUB GIVEUP
FOR I = 0 TO 5
FOR J = 0 TO 5
PUZZLE(I, J) = J
NEXT
NEXT
PUZZLE(5, 5) = -1
END SUB
SUB ROTATE (ROW)
FOR I = 1 TO 5
SWAP PUZZLE(ROW, 0), PUZZLE(ROW, I)
NEXT
END SUB
SUB SCRAMBLE
FOR I = 1 TO 1000
J = INT(RND(1) * 8)
SELECT CASE J
CASE 0 TO 5
CALL ROTATE(J)
CASE 6
CALL UP
CASE 7
CALL DOWN
END SELECT
NEXT
END SUB
DECLARE SUB SCRAMBLE ()
DECLARE SUB GIVEUP ()
DECLARE SUB UP ()
DECLARE SUB DOWN ()
DECLARE SUB ROTATE (ROW%)
DEFINT A-Z
DIM SHARED PUZZLE(0 TO 5, 0 TO 5)
DIM COLORS(-1 TO 5)
CLS
FOR I = 0 TO 5
READ COLORS(I)
FOR J = 0 TO 5
PUZZLE(I, J) = J
NEXT
NEXT
DATA 8, 15, 12, 14, 10, 9
PUZZLE(5, 5) = -1
DO
CLS
FOR I = 0 TO 5
PRINT I + 1;
FOR J = 0 TO 5
COLOR COLORS(PUZZLE(I, J))
PRINT CHR$(219);
NEXT
COLOR 7: PRINT
NEXT
PRINT
PRINT "Instructions:"
PRINT STRING$(13, 196)
PRINT " "; CHR$(254); " The object of the game is to restore the puzzle back to its initial state"
PRINT SPACE$(3); "from a scrambled state."
PRINT " "; CHR$(254); " To scramble the puzzle, press S."
PRINT " "; CHR$(254); " To give up and reset the puzzle, type R."
PRINT " "; CHR$(254); " To shift a row right, press the number of that row."
PRINT " "; CHR$(254); " To move a tile up into the blank space, press the up arrow key."
PRINT " "; CHR$(254); " To move a tile down into the blank space, press the down arrow key."
N$ = ""
WHILE N$ = ""
N$ = INKEY$
WEND
SELECT CASE N$
CASE "R", "r"
CALL GIVEUP
CASE "S", "s"
CALL SCRAMBLE
CASE "1"
CALL ROTATE(0)
CASE "2"
CALL ROTATE(1)
CASE "3"
CALL ROTATE(2)
CASE "4"
CALL ROTATE(3)
CASE "5"
CALL ROTATE(4)
CASE "6"
CALL ROTATE(5)
CASE CHR$(0) + CHR$(72)
CALL UP
CASE CHR$(0) + CHR$(80)
CALL DOWN
CASE CHR$(27)
END
END SELECT
LOOP
SUB DOWN
FOR I = 0 TO 5
FOR J = 0 TO 5
K = PUZZLE(I, J)
IF K = -1 THEN GOTO 2
NEXT
NEXT
2 IF I = 0 THEN EXIT SUB
SWAP PUZZLE(I - 1, J), PUZZLE(I, J)
END SUB
SUB GIVEUP
FOR I = 0 TO 5
FOR J = 0 TO 5
PUZZLE(I, J) = J
NEXT
NEXT
PUZZLE(5, 5) = -1
END SUB
SUB ROTATE (ROW)
FOR I = 1 TO 5
SWAP PUZZLE(ROW, 0), PUZZLE(ROW, I)
NEXT
END SUB
SUB SCRAMBLE
FOR I = 1 TO 1000
J = INT(RND(1) * 8)
SELECT CASE J
CASE 0 TO 5
CALL ROTATE(J)
CASE 6
CALL UP
CASE 7
CALL DOWN
END SELECT
NEXT
END SUB
SUB UP
FOR I = 0 TO 5
FOR J = 0 TO 5
K = PUZZLE(I, J)
IF K = -1 THEN GOTO 1
NEXT
NEXT
1 IF I = 5 THEN EXIT SUB
SWAP PUZZLE(I + 1, J), PUZZLE(I, J)
END SUB
DECLARE SUB ROTCUBE (AXIS%)
DECLARE SUB SCRAMBLE ()
DECLARE FUNCTION GETFAC% (X%, Y%)
DECLARE SUB DISPLAY ()
DECLARE SUB ROTATE (FAC%, ROT%)
DECLARE SUB INIT ()
DECLARE SUB MIDLAYER (FAC%)
DECLARE SUB MOUSE (N%)
DEFINT A-Z
TYPE REGTYPE
AX AS INTEGER
BX AS INTEGER
CX AS INTEGER
DX AS INTEGER
BP AS INTEGER
SI AS INTEGER
DI AS INTEGER
FLAGS AS INTEGER
DS AS INTEGER
ES AS INTEGER
END TYPE
DIM SHARED REGS AS REGTYPE
DIM SHARED C(1 TO 6, 1 TO 3, 1 TO 3), F(1 TO 6, 1 TO 4)
DIM SHARED X(1 TO 6, 1 TO 3, 1 TO 3), Y(1 TO 6, 1 TO 3, 1 TO 3)
CALL INIT
CALL MOUSE(0) 'MOUSE RESET
CALL MOUSE(1) 'SHOW MOUSE
DO
CALL DISPLAY
REGS.BX = 0
WHILE REGS.BX = 0
CALL MOUSE(3)
IF INKEY$ = CHR$(27) THEN END
WEND
FAC = GETFAC(REGS.CX \ 8 + 1, REGS.DX \ 8 + 1)
PRINT FAC
SELECT CASE FAC
CASE -1
CALL SCRAMBLE
CASE -2
CALL INIT
CASE -3
CALL ROTCUBE(1)
CASE -4
CALL ROTCUBE(2)
CASE -5
CALL ROTCUBE(3)
CASE 1 TO 6
IF REGS.BX = 1 THEN CALL ROTATE(FAC, 1)
IF REGS.BX = 2 THEN CALL ROTATE(FAC, 3)
END SELECT
T! = TIMER + .25
WHILE T! > TIMER: WEND
LOOP
SUB DISPLAY
CLS
FOR I = 3 TO 1 STEP -1
LOCATE , 4
FOR J = 3 TO 1 STEP -1
COLOR C(1, J, I)
PRINT CHR$(219);
NEXT
PRINT
NEXT
LOCATE 4
FOR I = 1 TO 3
FOR J = 3 TO 1 STEP -1
COLOR C(3, J, I)
PRINT CHR$(219);
NEXT
PRINT
NEXT
LOCATE 4
FOR I = 1 TO 3
LOCATE , 4
FOR J = 1 TO 3
COLOR C(5, I, J)
PRINT CHR$(219);
NEXT
PRINT
NEXT
LOCATE 4
FOR I = 3 TO 1 STEP -1
LOCATE , 7
FOR J = 3 TO 1 STEP -1
COLOR C(4, I, J)
PRINT CHR$(219);
NEXT
PRINT
NEXT
LOCATE 4
FOR I = 3 TO 1 STEP -1
LOCATE , 10
FOR J = 3 TO 1 STEP -1
COLOR C(6, J, I)
PRINT CHR$(219);
NEXT
PRINT
NEXT
LOCATE 7
FOR I = 3 TO 1 STEP -1
LOCATE , 4
FOR J = 1 TO 3
COLOR C(2, I, J)
PRINT CHR$(219);
NEXT
PRINT
NEXT
COLOR 7
LOCATE 11, 1
PRINT CHR$(218); STRING$(8, 196); CHR$(191)
PRINT CHR$(179); "Scramble"; CHR$(179)
PRINT CHR$(192); STRING$(8, 196); CHR$(217)
LOCATE 11, 11
PRINT CHR$(218); STRING$(10, 196); CHR$(191)
LOCATE , 11
PRINT CHR$(179); "Reset Cube"; CHR$(179)
LOCATE , 11
PRINT CHR$(192); STRING$(10, 196); CHR$(217)
LOCATE 11, 23
PRINT CHR$(218); STRING$(10, 196); CHR$(191)
LOCATE , 23
PRINT CHR$(179); " Rotate X "; CHR$(179)
LOCATE , 23
PRINT CHR$(192); STRING$(10, 196); CHR$(217)
LOCATE 11, 35
PRINT CHR$(218); STRING$(10, 196); CHR$(191)
LOCATE , 35
PRINT CHR$(179); " Rotate Y "; CHR$(179)
LOCATE , 35
PRINT CHR$(192); STRING$(10, 196); CHR$(217)
LOCATE 11, 47
PRINT CHR$(218); STRING$(10, 196); CHR$(191)
LOCATE , 47
PRINT CHR$(179); " Rotate Z "; CHR$(179)
LOCATE , 47
PRINT CHR$(192); STRING$(10, 196); CHR$(217)
END SUB
FUNCTION GETFAC (X, Y)
IF X >= 4 AND X <= 6 AND Y >= 1 AND Y <= 3 THEN GETFAC = 1: EXIT FUNCTION
IF X >= 4 AND X <= 6 AND Y >= 7 AND Y <= 9 THEN GETFAC = 2: EXIT FUNCTION
IF X >= 1 AND X <= 3 AND Y >= 4 AND Y <= 6 THEN GETFAC = 3: EXIT FUNCTION
IF X >= 7 AND X <= 9 AND Y >= 4 AND Y <= 6 THEN GETFAC = 4: EXIT FUNCTION
IF X >= 4 AND X <= 6 AND Y >= 4 AND Y <= 6 THEN GETFAC = 5: EXIT FUNCTION
IF X >= 10 AND X <= 12 AND Y >= 4 AND Y <= 6 THEN GETFAC = 6: EXIT FUNCTION
IF X >= 1 AND X <= 10 AND Y >= 11 AND Y <= 14 THEN GETFAC = -1: EXIT FUNCTION
IF X >= 11 AND X <= 22 AND Y >= 11 AND Y <= 14 THEN GETFAC = -2: EXIT FUNCTION
IF X >= 23 AND X <= 34 AND Y >= 11 AND Y <= 14 THEN GETFAC = -3: EXIT FUNCTION
IF X >= 35 AND X <= 46 AND Y >= 11 AND Y <= 14 THEN GETFAC = -4: EXIT FUNCTION
IF X >= 47 AND X <= 58 AND Y >= 11 AND Y <= 14 THEN GETFAC = -5: EXIT FUNCTION
END FUNCTION
SUB INIT
FOR N = 1 TO 6
FOR I = 1 TO 3
FOR J = 1 TO 3
C(N, I, J) = N
NEXT
NEXT
NEXT
END SUB
C(F(FAC, 3), 1, 3) = C(F(FAC, 4), 3, 1)
C(F(FAC, 3), 2, 3) = C(F(FAC, 4), 2, 1)
C(F(FAC, 3), 3, 3) = C(F(FAC, 4), 1, 1)
C(F(FAC, 4), 3, 1) = T1: C(F(FAC, 4), 2, 1) = T2
C(F(FAC, 4), 1, 1) = T3 'RECOVER TEMPS
NEXT
END SUB
SUB ROTCUBE (AXIS)
SELECT CASE AXIS
CASE 1
CALL ROTATE(5, 1)
CALL MIDLAYER(5)
CALL ROTATE(6, 3)
CASE 2
CALL ROTATE(3, 1)
CALL MIDLAYER(3)
CALL ROTATE(4, 3)
CASE 3
CALL ROTATE(1, 1)
CALL MIDLAYER(1)
CALL ROTATE(2, 3)
END SELECT
END SUB
SUB SCRAMBLE
FOR I = 1 TO 1000
A = INT(RND * 6) + 1
B = INT(RND * 3) + 1
CALL ROTATE(A, B)
NEXT
END SUB
This message has been edited by iorr5t on Oct 7, 2007 2:12 PM
DEFINT A-Z 'default integers
DECLARE SUB Init ()
DECLARE SUB Redraw ()
DECLARE SUB Grafic ()
DECLARE SUB MouseLimit ()
DECLARE SUB mouse (axx)
DECLARE SUB Rotate (fac, rot)
DECLARE SUB MidLayer (fac)
DECLARE SUB PrStr (st$, row)
DECLARE SUB Solve ()
DECLARE SUB RotCube ()
DECLARE SUB Rotpr (fac, rot)
DECLARE SUB Edges1 ()
DECLARE SUB Corners1 ()
DECLARE SUB Edges2 ()
DECLARE SUB Edges2a ()
DECLARE SUB Corners3 ()
DECLARE SUB Edges3 ()
DECLARE SUB Twirls ()
DECLARE SUB Flips ()
DIM SHARED face(6) AS STRING * 7
DIM SHARED ang(3) AS STRING * 3
DIM SHARED blank AS STRING * 22
DIM SHARED c(6, 3, 3), f(6, 4)
DIM SHARED x(6, 3, 3), y(6, 3, 3)
DIM SHARED a(1 TO 17)
FOR i = 1 TO 17: READ a(i): NEXT
DATA -18288,0,13261,-23762,26
DATA -30418,7198,11776,3721,30
DATA -30418,8214,-13568,0,0,0,0
DIM SHARED b(1 TO 8)
FOR i = 1 TO 8: READ b(i): NEXT
DATA -18288,0,-18032,0,-17776,0
DATA 13261,203
DIM SHARED pause, count
SCREEN 12 'VGA 640x480
mouse 0 'Reset mouse driver
MouseLimit
Grafic 'draw initial cube
DO 'the program loop
mouse 1 'show mouse
DO: mouse 3
LOOP UNTIL a(15) > 0
TIM! = TIMER + .33 'float tim
DO: LOOP UNTIL TIMER > TIM!
click = a(15)
cxx = a(16): dxx = a(17)
mouse 2 'hide mouse
IF click < 2 THEN
fac = INT((cxx + 8) / 56)
rot = INT((dxx - 16) / 16)
LOCATE 1, 1: PRINT fac; rot
IF fac > 0 AND fac < 8 THEN
IF rot > 0 AND rot < 5 THEN
IF fac = 7 THEN
IF rot = 1 THEN Init 'Reset
IF rot > 2 THEN Solve
IF rot = 2 THEN
pause = 1 - pause
IF pause = 1 THEN
PrStr "Pause ON ", 1
ELSE
PrStr "Pause OFF", 1
END IF
END IF
ELSE
IF rot < 4 THEN
Rotate fac, rot 'rotate face
ELSE 'rotate cube
IF fac < 3 THEN opp = 3 - fac
IF fac > 2 THEN opp = 7 - fac
IF fac > 4 THEN opp = 11 - fac
Rotate fac, 1'face clock
Rotate opp, 3'opp. anti
MidLayer fac 'middle,clock
END IF
END IF
END IF
END IF
Redraw 'recolour all squares
END IF
LOOP UNTIL click = 2
CLS : SCREEN 0 'back to text
SUB Corners1
' Rotate cube about vertical to 4 positions.
' At each, note correct u/f/r, find it (8 poss.
' locations) and moves it to d/f/r initially.
PrStr "Top layer corners", 3: uc = c(1, 2, 2)
FOR n = 1 TO 4: fc = c(5, 2, 2): rc = c(4, 2, 2)
'U & F & R centre colours. u/f/r corner
'must have same 3 colours, i, j & k.
'Even if u/f/r is correct , move it to d/f/r
i = c(1, 3, 1): j = c(5, 1, 3): k = c(4, 3, 3)
IF i = uc OR j = uc OR k = uc THEN '|copy
IF i = fc OR j = fc OR k = fc THEN '|
IF i = rc OR j = rc OR k = rc THEN '|
PrStr "Move u/f/r to d/f/r ", 4
PrStr "ie. R-1DR ", 5
Rotpr 4, 3: Rotpr 2, 1: Rotpr 4, 1
END IF '|copy
END IF '|
END IF '|
'if u/b/r is correct u/f/r, move it to d/f/r
i = c(1, 3, 3): j = c(6, 1, 3): k = c(4, 3, 1)
'copy 3 IF statements
IF i = uc OR j = uc OR k = uc THEN '|copy
IF i = fc OR j = fc OR k = fc THEN '|
IF i = rc OR j = rc OR k = rc THEN '|
PrStr "Move u/b/r to d/f/r ", 4
PrStr "ie. B-1D-1B ", 5
Rotpr 6, 3: Rotpr 2, 3: Rotpr 6, 1
'copy 3 END IFs
END IF '|copy
END IF '|
END IF '|
'if u/b/l is correct u/f/r, move it to d/f/r
i = c(1, 1, 3): j = c(6, 3, 3): k = c(3, 3, 1)
'copy 3 IF statements
IF i = uc OR j = uc OR k = uc THEN '|copy
IF i = fc OR j = fc OR k = fc THEN '|
IF i = rc OR j = rc OR k = rc THEN '|
PrStr "Move u/b/l to d/f/r ", 4
PrStr "ie. L-1D2L ", 5
Rotpr 3, 3: Rotpr 2, 2: Rotpr 3, 1
'copy 3 END IFs
END IF '|copy
END IF '|
END IF '|
'if u/f/l is correct u/f/r, move it to d/f/r
i = c(1, 1, 1): j = c(5, 1, 1): k = c(3, 1, 1)
'copy 3 IF statements
IF i = uc OR j = uc OR k = uc THEN '|copy
IF i = fc OR j = fc OR k = fc THEN '|
IF i = rc OR j = rc OR k = rc THEN '|
PrStr "Move u/f/l to d/f/r ", 4
PrStr "ie. LDL-1 ", 5
Rotpr 3, 1: Rotpr 2, 1: Rotpr 3, 3
'copy 3 END IFs
END IF '|copy
END IF '|
END IF '|
'if d/b/r is correct u/f/r, move it to d/f/r
i = c(2, 1, 1): j = c(6, 1, 1): k = c(4, 1, 1)
'copy 3 IF statements
IF i = uc OR j = uc OR k = uc THEN '|copy
IF i = fc OR j = fc OR k = fc THEN '|
IF i = rc OR j = rc OR k = rc THEN '|
PrStr "Move d/b/r to d/f/r ", 4
PrStr "ie. D-1 ", 5
Rotpr 2, 3
'copy 3 END IFs
END IF '|copy
END IF '|
END IF '|
'if d/b/l is correct u/f/r, move it to d/f/r
i = c(2, 1, 3): j = c(6, 3, 1): k = c(3, 3, 3)
'copy 3 IF statements
IF i = uc OR j = uc OR k = uc THEN '|copy
IF i = fc OR j = fc OR k = fc THEN '|
IF i = rc OR j = rc OR k = rc THEN '|
PrStr "Move d/b/l to d/f/r ", 4
PrStr "ie. D2 ", 5
Rotpr 2, 2
'copy 3 END IFs
END IF '|copy
END IF '|
END IF '|
'if d/f/l is correct u/f/r, move it to d/f/r
i = c(2, 3, 3): j = c(5, 3, 1): k = c(3, 1, 3)
'copy 3 IF statements
IF i = uc OR j = uc OR k = uc THEN '|copy
IF i = fc OR j = fc OR k = fc THEN '|
IF i = rc OR j = rc OR k = rc THEN '|
PrStr "Move d/f/l to d/f/r ", 4
PrStr "ie. D ", 5
Rotpr 2, 1
'copy 3 END IFs
END IF '|copy
END IF '|
END IF '|
' --------- u/f/r cube now at d/f/r. ----------
' --------- So move to it to u/f/r ----------
PrStr "Move d/f/r to u/f/r ", 4
IF c(2, 3, 1) = uc THEN 'if uc colour on D
'face, it must be moved to R face
PrStr "ie. R-1DRD2 ", 5
Rotpr 4, 3: Rotpr 2, 1: Rotpr 4, 1: Rotpr 2, 2
END IF
IF c(5, 3, 3) = uc THEN 'if uc colour on F
PrStr "ie. FDF-1 ", 5
Rotpr 5, 1: Rotpr 2, 1: Rotpr 5, 3'move to u/r
END IF
IF c(4, 1, 3) = uc THEN 'if uc colour on R
PrStr "ie. R-1D-1R ", 5
Rotpr 4, 3: Rotpr 2, 3: Rotpr 4, 1'move to u/r
END IF
IF n < 4 THEN RotCube
NEXT n
PrStr blank, 3: PrStr blank, 4
PrStr blank, 5: PrStr blank, 6
END SUB
SUB Corners3
PrStr "Sort top corners", 3: n = 0: order = 0
DO UNTIL (order > 900 AND order < 1100) OR order = 1111
n = n + 1 'number of loop
IF n > 1 THEN RotCube 'rotate whole cube
'is u/r/f in correct position ?
t1 = c(4, 2, 2): t2 = c(5, 2, 2)'r & f colours
i = c(1, 3, 1): j = c(5, 1, 3): k = c(4, 3, 3)
IF i = t1 OR j = t1 OR k = t1 THEN
IF i = t2 OR j = t2 OR k = t2 THEN order = 1000
END IF
'is u/r/b in correct position ?
t1 = c(4, 2, 2): t2 = c(6, 2, 2)'r & b colours
i = c(1, 3, 3): j = c(4, 3, 1): k = c(6, 1, 3)
IF i = t1 OR j = t1 OR k = t1 THEN
IF i = t2 OR j = t2 OR k = t2 THEN order = order + 100
END IF
'is u/l/b in correct position ?
t1 = c(3, 2, 2): t2 = c(6, 2, 2)'l & b colours
i = c(1, 1, 3): j = c(3, 3, 1): k = c(6, 3, 3)
IF i = t1 OR j = t1 OR k = t1 THEN
IF i = t2 OR j = t2 OR k = t2 THEN order = order + 10
END IF
'is u/l/f in correct position ?
t1 = c(5, 2, 2): t2 = c(3, 2, 2)'l & f colours
i = c(1, 1, 1): j = c(3, 1, 1): k = c(5, 1, 1)
IF i = t1 OR j = t1 OR k = t1 THEN
IF i = t2 OR j = t2 OR k = t2 THEN order = order + 1
END IF
IF order = 0 THEN 'no corners correct
PrStr "Rotate top layer only ", 4
Rotpr 1, 1: n = 0: PrStr blank, 4: PrStr blank, 6
END IF 'ie. need to go around loop again
LOOP
LOCATE 2, 58: PRINT "Order is "; order
SELECT CASE order
CASE 1000: 'only u/r/f correct so other 3
'must circulate - clock or anticlock?
lc = c(3, 2, 2): bc = c(6, 2, 2)'l & b colours
IF c(1, 1, 1) = lc OR c(3, 1, 1) = lc OR c(5, 1, 1) = lc THEN
IF c(1, 1, 1) = bc OR c(3, 1, 1) = bc OR c(5, 1, 1) = bc THEN
PrStr "ie. L-1URU-1LUR-1U-1 ", 5
'u/l/f goes clockw. to u/l/b
Rotpr 3, 3: Rotpr 1, 1: Rotpr 4, 1: Rotpr 1, 3
Rotpr 3, 1: Rotpr 1, 1: Rotpr 4, 3: Rotpr 1, 3
END IF
END IF
IF c(1, 3, 3) = lc OR c(4, 3, 1) = lc OR c(6, 1, 3) = lc THEN
IF c(1, 3, 3) = bc OR c(4, 3, 1) = bc OR c(6, 1, 3) = bc THEN
PrStr "ie. URU-1L-1UR-1U-1L ", 5
'u/r/b goes anticl. to u/l/b
Rotpr 1, 1: Rotpr 4, 1: Rotpr 1, 3: Rotpr 3, 3
Rotpr 1, 1: Rotpr 4, 3: Rotpr 1, 3: Rotpr 3, 1
END IF
END IF
CASE 1001: 'u/r/f and u/l/f correct
PrStr "ie. FU-1B-1UF-1U-1BU2 ", 5
Rotpr 5, 1: Rotpr 1, 3: Rotpr 6, 3: Rotpr 1, 1
Rotpr 5, 3: Rotpr 1, 3: Rotpr 6, 1: Rotpr 1, 2
CASE 1010: 'u/r/f and u/l/b correct
PrStr "ie. UFURU-1R-1F-1 ", 5
Rotpr 1, 1: Rotpr 5, 1: Rotpr 1, 1: Rotpr 4, 1
Rotpr 1, 3: Rotpr 4, 3: Rotpr 5, 3
END SELECT
PrStr blank, 3: PrStr blank, 4
PrStr blank, 5: PrStr blank, 6
END SUB
SUB Edges1
'locate u/f edge cube (23 other possible
'positions/orientations) and move to u/f
PrStr "Top layer edges", 3: uc = c(1, 2, 2) 'U &
FOR n = 1 TO 4: fc = c(5, 2, 2) '..F Centre colours
'if at u/f but flipped. (If not flipped, leave it)
IF c(1, 2, 1) = fc AND c(5, 1, 2) = uc THEN
PrStr "Flip u/f cube ", 4: PrStr "ie. F2LD-1L-1F", 5
Rotpr 5, 2: Rotpr 3, 1: Rotpr 2, 3: Rotpr 3, 3: Rotpr 5, 1
END IF
'if at r/f (2 orientations at each position)
IF c(4, 2, 3) = uc AND c(5, 2, 3) = fc THEN
PrStr "Move r/f to u/f", 4: PrStr "ie. F-1 ", 5
Rotpr 5, 3
END IF
IF c(4, 2, 3) = fc AND c(5, 2, 3) = uc THEN
PrStr "Move r/f to u/f", 4: PrStr "ie. FLD-1L-1F", 5
Rotpr 5, 1: Rotpr 3, 1: Rotpr 2, 3: Rotpr 3, 3: Rotpr 5, 1
END IF
'if at d/f
IF c(2, 3, 2) = uc AND c(5, 3, 2) = fc THEN
PrStr "Move d/f to u/f", 4: PrStr "ie. F2 ", 5
Rotpr 5, 2
END IF
IF c(2, 3, 2) = fc AND c(5, 3, 2) = uc THEN
PrStr "Move d/f to u/f", 4: PrStr "ie. LD-1L-1F ", 5
Rotpr 3, 1: Rotpr 2, 3: Rotpr 3, 3: Rotpr 5, 1
END IF
'if at l/f
IF c(3, 1, 2) = uc AND c(5, 2, 1) = fc THEN
PrStr "Move l/f to u/f", 4: PrStr "ie. F ", 5
Rotpr 5, 1
END IF
IF c(3, 1, 2) = fc AND c(5, 2, 1) = uc THEN
PrStr "Move l/f to u/f", 4: PrStr "ie.F-1LD-1L-1F", 5
Rotpr 5, 3: Rotpr 3, 1: Rotpr 2, 3: Rotpr 3, 3: Rotpr 5, 1
END IF
'if at d/l
IF c(2, 2, 3) = fc AND c(3, 2, 3) = uc THEN
PrStr "Move d/l to u/f", 4: PrStr "ie. L-1FL ", 5
Rotpr 3, 3: Rotpr 5, 1: Rotpr 3, 1
END IF
IF c(2, 2, 3) = uc AND c(3, 2, 3) = fc THEN
PrStr "Move d/l to u/f", 4: PrStr "ie. DF2 ", 5
Rotpr 2, 1: Rotpr 5, 2
END IF
'if at d/b
IF c(2, 1, 2) = uc AND c(6, 2, 1) = fc THEN
PrStr "Move d/b to u/f", 4: PrStr "ie. D2F2 ", 5
Rotpr 2, 2: Rotpr 5, 2
END IF
IF c(2, 1, 2) = fc AND c(6, 2, 1) = uc THEN
PrStr "Move d/b to u/f", 4: PrStr "ie. DL-1FL ", 5
Rotpr 2, 1: Rotpr 3, 3: Rotpr 5, 1: Rotpr 3, 1
END IF
'if at d/r
IF c(2, 2, 1) = fc AND c(4, 1, 2) = uc THEN
PrStr "Move d/r to u/f", 4: PrStr "ie. RF-1R-1 ", 5
Rotpr 4, 1: Rotpr 5, 3: Rotpr 4, 3
END IF
IF c(2, 2, 1) = uc AND c(4, 1, 2) = fc THEN
PrStr "Move d/r to u/f", 4: PrStr "ie. D-1F2 ", 5
Rotpr 2, 3: Rotpr 5, 2
END IF
'if at b/r
IF c(4, 2, 1) = fc AND c(6, 1, 2) = uc THEN
PrStr "Move b/r to u/f", 4: PrStr "ie. RD-1F2R-1", 5
Rotpr 4, 1: Rotpr 2, 3: Rotpr 5, 2: Rotpr 4, 3
END IF
IF c(4, 2, 1) = uc AND c(6, 1, 2) = fc THEN
PrStr "Move b/r to u/f", 4: PrStr "ie. R2F-1R2 ", 5
Rotpr 4, 2: Rotpr 5, 3: Rotpr 4, 2
END IF
'if at b/l
IF c(3, 3, 2) = fc AND c(6, 3, 2) = uc THEN
PrStr "Move b/l to u/f", 4: PrStr "ie. L-1DF2L ", 5
Rotpr 3, 3: Rotpr 2, 1: Rotpr 5, 2: Rotpr 3, 1
END IF
IF c(3, 3, 2) = uc AND c(6, 3, 2) = fc THEN
PrStr "Move b/l to u/f", 4: PrStr "ie. L2FL2 ", 5
Rotpr 3, 2: Rotpr 5, 1: Rotpr 3, 2
END IF
'if at l/u
IF c(3, 2, 1) = fc AND c(1, 1, 2) = uc THEN
PrStr "Move l/u to u/f", 4: PrStr "ie. L2DF2 ", 5
Rotpr 3, 2: Rotpr 2, 1: Rotpr 5, 2
END IF
IF c(3, 2, 1) = uc AND c(1, 1, 2) = fc THEN
PrStr "Move l/u to u/f", 4: PrStr "ie. LF ", 5
Rotpr 3, 1: Rotpr 5, 1
END IF
'if at b/u
IF c(6, 2, 3) = fc AND c(1, 2, 3) = uc THEN
PrStr "Move b/u to u/f", 4: PrStr "ie. B2D2F2 ", 5
Rotpr 6, 2: Rotpr 2, 2: Rotpr 5, 2
END IF
IF c(6, 2, 3) = uc AND c(1, 2, 3) = fc THEN
PrStr "Move b/u to u/f", 4: PrStr "ie. BL-1DLF2 ", 5
Rotpr 6, 1: Rotpr 3, 3: Rotpr 2, 1: Rotpr 3, 1: Rotpr 5, 2
END IF
'if at r/u
IF c(4, 3, 2) = fc AND c(1, 3, 2) = uc THEN
PrStr "Move r/u to u/f", 4: PrStr "ie. R2D-1F2 ", 5
Rotpr 4, 2: Rotpr 2, 3: Rotpr 5, 2
END IF
IF c(4, 3, 2) = uc AND c(1, 3, 2) = fc THEN
PrStr "Move r/u to u/f", 4: PrStr "ie. R-1F-1 ", 5
Rotpr 4, 3: Rotpr 5, 3
END IF
IF n < 4 THEN RotCube
NEXT n
PrStr blank, 3: PrStr blank, 4: PrStr blank, 5: PrStr blank, 6
END SUB
SUB Edges2
PrStr "Invert whole cube", 3'about L face axis
MidLayer 5: MidLayer 5 'need 2 x 90 deg.
Rotate 6, 2: Rotpr 5, 2: PrStr blank, 6
'The sorted layer is now on the bottom.
PrStr "Middle layer edges", 3 'tell the user
'Rotating about vert. to 4 separate positions
FOR n = 1 TO 4: lc = c(3, 2, 2): fc = c(5, 2, 2)
'First check 4 middle edge positions for l/f.
'if l/f in correct position and orientation,
'leave it. Otherwise, move it to top layer.
'First, if l/f in position but flipped
IF c(3, 1, 2) = fc AND c(5, 2, 1) = lc THEN
PrStr "l/f to top layer ", 4
PrStr "ie. FU2RUR-1U2F-1 ", 5
Rotpr 5, 1: Rotpr 1, 2: Rotpr 4, 1: Rotpr 1, 1
Rotpr 4, 3: Rotpr 1, 2: Rotpr 5, 3
END IF
'Now, check other 3 vertical edge positions
'if l/f at r/f, move to top layer
IF c(4, 2, 3) = fc OR c(5, 2, 3) = fc THEN
IF c(4, 2, 3) = lc OR c(5, 2, 3) = lc THEN
PrStr "r/f to top layer ", 4
PrStr "ie RU2BUB-1U2R-1 ", 5
Rotpr 4, 1: Rotpr 1, 2: Rotpr 6, 1: Rotpr 1, 1
Rotpr 6, 3: Rotpr 1, 2: Rotpr 4, 3
END IF
END IF
'if l/f at r/b, move to top layer
IF c(4, 2, 1) = fc OR c(6, 1, 2) = fc THEN
IF c(4, 2, 1) = lc OR c(6, 1, 2) = lc THEN
PrStr "r/b to top layer ", 4
PrStr "ie. BU2LUL-1U2B-1 ", 5
Rotpr 6, 1: Rotpr 1, 2: Rotpr 3, 1: Rotpr 1, 1
Rotpr 3, 3: Rotpr 1, 2: Rotpr 6, 3
END IF
END IF
'if l/f at l/b, move to top layer
IF c(3, 3, 2) = fc OR c(6, 3, 2) = fc THEN
IF c(3, 3, 2) = lc OR c(6, 3, 2) = lc THEN
PrStr "l/b to top layer ", 4
PrStr "ie. LU2FUF-1U2L-1 ", 5
Rotpr 3, 1: Rotpr 1, 2: Rotpr 5, 1: Rotpr 1, 1
Rotpr 5, 3: Rotpr 1, 2: Rotpr 3, 3
END IF
END IF
'NOW, find l/f in top layer, transfer to u/r,
'then to l/f using Edges2a()
IF c(4, 3, 2) = fc OR c(1, 3, 2) = fc THEN
IF c(4, 3, 2) = lc OR c(1, 3, 2) = lc THEN
Edges2a 'candidate already at u/l
END IF
END IF
IF c(6, 2, 3) = fc OR c(1, 2, 3) = fc THEN
IF c(6, 2, 3) = lc OR c(1, 2, 3) = lc THEN
PrStr "u/b to u/r ", 4
Rotpr 1, 1: Edges2a 'candidate at u/l
END IF
END IF
IF c(3, 2, 1) = fc OR c(1, 1, 2) = fc THEN
IF c(3, 2, 1) = lc OR c(1, 1, 2) = lc THEN
PrStr "u/l to u/r ", 4
Rotpr 1, 2: Edges2a 'candidate at u/l
END IF
END IF
IF c(5, 1, 2) = fc OR c(1, 2, 1) = fc THEN
IF c(5, 1, 2) = lc OR c(1, 2, 1) = lc THEN
PrStr "u/f to u/r ", 4
Rotpr 1, 3: Edges2a 'candidate at u/f
END IF
END IF
IF n < 4 THEN RotCube
NEXT n
PrStr blank, 3: PrStr blank, 4
PrStr blank, 5: PrStr blank, 6
END SUB
SUB Edges2a 'After Edges2() puts l/f cube to
' u/r position, this puts it in correct
' position and correct orientation.
PrStr "u/r to l/f ", 4
IF c(1, 3, 2) = c(3, 2, 2) THEN 'U face of u/r
PrStr "ie. FU2RUR-1U2F-1 ", 5 'is lc
Rotpr 5, 1: Rotpr 1, 2: Rotpr 4, 1: Rotpr 1, 1
Rotpr 4, 3: Rotpr 1, 2: Rotpr 5, 3
ELSE 'ie. U face of u/r = fc colour
PrStr "ie. UFU2RU-1R-1U2F-1 ", 5
Rotpr 1, 1: Rotpr 5, 1: Rotpr 1, 2: Rotpr 4, 1
Rotpr 1, 3: Rotpr 4, 3: Rotpr 1, 2: Rotpr 5, 3
END IF
END SUB
SUB Edges3
PrStr "Sort top edge cubes", 3: correct = 0
'first note centre colours of faces F, R, B & L
fc = c(5, 2, 2): rc = c(4, 2, 2): bc = c(6, 2, 2): lc = c(3, 2, 2)
'find which cubes are in correct position
IF c(1, 2, 1) = fc OR c(5, 1, 2) = fc THEN correct = 1000
IF c(1, 3, 2) = rc OR c(4, 3, 2) = rc THEN correct = correct + 100
IF c(1, 2, 3) = bc OR c(6, 2, 3) = bc THEN correct = correct + 10
IF c(1, 1, 2) = lc OR c(3, 2, 1) = lc THEN correct = correct + 1
IF correct = 0 THEN 'none of cubes in right place
IF c(1, 2, 1) = rc OR c(5, 1, 2) = rc THEN 'if u/r at u/f
RotCube 'rotate whole cube. note new centre colours
fc = c(5, 2, 2): rc = c(4, 2, 2): bc = c(6, 2, 2): lc = c(3, 2, 2)
END IF
IF c(1, 2, 1) = bc OR c(5, 1, 2) = bc THEN 'if u/b at u/f
PrStr "R2L2DR2L2U2R2L2DR2L2 ", 5'swap opposite pairs
Rotpr 4, 2: Rotpr 3, 2: Rotpr 2, 1: Rotpr 4, 2
Rotpr 3, 2: Rotpr 1, 2: Rotpr 4, 2: Rotpr 3, 2
Rotpr 2, 1: Rotpr 4, 2: Rotpr 3, 2
END IF
IF c(1, 2, 1) = lc OR c(5, 1, 2) = lc THEN 'if u/l at u/f
PrStr "RBUB-1U-1R2F-1U-1FUR ", 5'swap adjacent pairs
Rotpr 4, 1: Rotpr 6, 1: Rotpr 1, 1: Rotpr 6, 3
Rotpr 1, 3: Rotpr 4, 2: Rotpr 5, 3: Rotpr 1, 3
Rotpr 5, 1: Rotpr 1, 1: Rotpr 4, 1
END IF
END IF
SELECT CASE correct 'One cube only correct. Rotate
'whole cube to put it at u/r position
CASE 1000: RotCube: RotCube: RotCube
CASE 10: RotCube
CASE 1: RotCube: RotCube
END SELECT 'in effect, now correct = 100
bc = c(6, 2, 2): lc = c(3, 2, 2)'centre colours of B & L
IF c(1, 2, 1) = bc OR c(5, 1, 2) = bc THEN 'if u/b at u/f
PrStr "L2U-1F-1BL2FB-1U-1L2 ", 5 'circulate anticlock
Rotpr 3, 2: Rotpr 1, 3: Rotpr 5, 3: Rotpr 6, 1: Rotpr 3, 2
Rotpr 5, 1: Rotpr 6, 3: Rotpr 1, 3: Rotpr 3, 2
END IF
IF c(1, 2, 1) = lc OR c(5, 1, 2) = lc THEN 'if u/l at u/f
PrStr "ie. L2UF-1BL2FB-1UL2 ", 5 'circulate clockwise
Rotpr 3, 2: Rotpr 1, 1: Rotpr 5, 3: Rotpr 6, 1: Rotpr 3, 2
Rotpr 5, 1: Rotpr 6, 3: Rotpr 1, 1: Rotpr 3, 2
END IF
PrStr blank, 3: PrStr blank, 4
PrStr blank, 5: PrStr blank, 6
END SUB
SUB Flips 'flips top edge cubes
uc = c(1, 2, 2) 'colour of U centre
DO UNTIL c(1, 2, 1) = uc AND c(1, 1, 2) = uc AND c(1, 2, 3) = uc AND c(1, 3, 2) = uc
n = 0 'ie. until all top faces match uc
DO UNTIL c(1, 2, 1) = c(5, 2, 2) OR n = 4
n = n + 1: RotCube 'until u/f needs flip
LOOP 'if n reaches 4, all are correct
'cubes needing flip always occur in pairs
IF n < 4 THEN 'u/f needs flip. Find other
IF c(1, 3, 2) = c(4, 2, 2) THEN
other = 4 'u/r needs flip
PrStr "u/f & u/r need flip ", 2
ELSE
IF c(1, 2, 3) = c(6, 2, 2) THEN
other = 6 'u/b needs flip
PrStr "u/f & u/b need flip ", 2
ELSE
other = 3 'u/l needs flip
PrStr "u/f & u/l need flip ", 2
END IF
END IF
PrStr "Flip pair top edges ", 4
PrStr "Firstly FUD-1L2U2D2R ", 5
Rotpr 5, 1: Rotpr 1, 1: Rotpr 2, 3: Rotpr 3, 2
Rotpr 1, 2: Rotpr 2, 2: Rotpr 4, 1
PrStr "2nd of pair to u/r ", 5
IF other = 4 THEN Rotpr 1, 1
IF other = 6 THEN Rotpr 1, 2
IF other = 3 THEN Rotpr 1, 3
PrStr "Now R-1D2U2L2DU-1F-1", 5
Rotpr 4, 3: Rotpr 2, 2: Rotpr 1, 2: Rotpr 3, 2
Rotpr 2, 1: Rotpr 1, 3: Rotpr 5, 3
IF other = 4 THEN Rotpr 1, 3
IF other = 6 THEN Rotpr 1, 2
IF other = 3 THEN Rotpr 1, 1
PrStr blank, 2
END IF
LOOP
PrStr blank, 3: PrStr blank, 4
PrStr blank, 5: PrStr blank, 6
END SUB
SUB Grafic
' face name strings in face(6) array
face(1) = " UP ": face(2) = " DOWN "
face(3) = " LEFT ": face(4) = " RIGHT "
face(5) = " FRONT ": face(6) = " BACK "
ang(1) = "+90": ang(2) = "180": ang(3) = "-90"
' blank = " " '22 spaces
blank = SPACE$(22)
' each face's adjacent faces, anticlockwise
f(1, 1) = 5: f(1, 2) = 4: f(1, 3) = 6: f(1, 4) = 3
f(2, 1) = 4: f(2, 2) = 5: f(2, 3) = 3: f(2, 4) = 6
f(3, 1) = 1: f(3, 2) = 6: f(3, 3) = 2: f(3, 4) = 5
f(4, 1) = 6: f(4, 2) = 1: f(4, 3) = 5: f(4, 4) = 2
f(5, 1) = 3: f(5, 2) = 2: f(5, 3) = 4: f(5, 4) = 1
f(6, 1) = 2: f(6, 2) = 3: f(6, 3) = 1: f(6, 4) = 4
CLS : COLOR 15 'now print top table
PrStr "Rightclick to QUIT ", 7
LOCATE 6, 7: PRINT "Rotate whole cube 90"
LOCATE 6, 34: PRINT "Clock wise"
FOR n = 1 TO 6
LOCATE 1, n * 7: PRINT face(n)
LOCATE 2, n * 7 + 2: PRINT n
LOCATE 3, n * 7 + 2: PRINT ang(1)
LOCATE 4, n * 7 + 2: PRINT ang(2)
LOCATE 5, n * 7 + 2: PRINT ang(3)
LINE (n * 56 - 9, 32)-STEP(50, 16), 15, B
LINE (n * 56 - 9, 48)-STEP(50, 16), 15, B
LINE (n * 56 - 9, 64)-STEP(50, 16), 15, B
LINE (n * 56 - 9, 80)-STEP(50, 16), 15, B
NEXT n
LOCATE 3, 50: PRINT "RESET"
LINE (383, 32)-STEP(56, 16), 15, B
LOCATE 4, 50: PRINT "PAUSE"
LINE (383, 48)-STEP(56, 16), 15, B
LOCATE 5, 50: PRINT "SOLVE"
LINE (383, 64)-STEP(56, 32), 15, B
' now print face labels
LOCATE 11, 7: PRINT face(1)
LOCATE 11, 28: PRINT face(1)
LOCATE 25, 67: PRINT face(2)
LOCATE 25, 48: PRINT face(2)
LOCATE 27, 8: PRINT face(3)
LOCATE 9, 69: PRINT face(4)
LOCATE 27, 27: PRINT face(5)
LOCATE 9, 46: PRINT face(6)
LOCATE 8, 15: PRINT "OUTSIDE VIEW"
LOCATE 27, 55: PRINT "INSIDE VIEW"
' draw the cube - 9 times
dx = 40: dx3 = 3 * dx: dy = 24: dy3 = 3 * dy
xs = 20: ys = 24: ys2 = 2 * ys: ys6 = 6 * ys: c = 15
FOR xl = 159 TO 161: xr = xl + 320
FOR yl = 288 TO 290: yr = yl - 30
FOR i = 0 TO 3:
LINE (xl - i * dx, yl - i * dy)-STEP(0, ys6), c
LINE (xl - i * dx, yl - i * dy)-STEP(dx3, -dy3), c
LINE (xl + i * dx, yl - i * dy)-STEP(0, ys6), c
LINE (xl + i * dx, yl - i * dy)-STEP(-dx3, -dy3), c
LINE (xl, yl + i * ys2)-STEP(dx3, -dy3), c
LINE (xl, yl + i * ys2)-STEP(-dx3, -dy3), c
LINE (xr - i * dx, yr + i * dy)-STEP(0, -ys6), c
LINE (xr - i * dx, yr + i * dy)-STEP(dx3, dy3), c
LINE (xr + i * dx, yr + i * dy)-STEP(0, -ys6), c
LINE (xr + i * dx, yr + i * dy)-STEP(-dx3, dy3), c
LINE (xr, yr - i * ys2)-STEP(dx3, dy3), c
LINE (xr, yr - i * ys2)-STEP(-dx3, dy3), c
NEXT i: NEXT yl: NEXT xl
sx = xl - xr: sy = yl - yr'draw dashed lines
LINE (xr, yr - ys6)-STEP(sx, sy), c, , &H700
LINE (xr + dx3, yr - dy3)-STEP(sx, sy), c, , &H700
LINE (xr + dx3, yr + dy3)-STEP(sx, sy), c, , &H700
LINE (xr, yr + ys6)-STEP(sx, sy), c, , &H700
LINE (xr - dx3, yr - dy3)-STEP(sx / 3, sy / 3), c, , &H700
LINE (xr - dx3, yr + dy3)-STEP(sx / 4, sy / 4), c, , &H700
' starting coords to paint each square
FOR i = 1 TO 3: FOR j = 1 TO 3
x(1, i, j) = xl + i * dx - j * dx
y(1, i, j) = yl + dy - i * dy - j * dy
x(2, i, j) = xr - j * dx + i * dx
y(2, i, j) = yr - dy + i * dy + j * dy
x(3, i, j) = xl + xs - i * dx
y(3, i, j) = yl - ys + j * ys2 - i * dy
x(4, i, j) = xr - xs + j * dx
y(4, i, j) = yr + ys - i * ys2 + j * dy
x(5, i, j) = xl - xs + j * dx
y(5, i, j) = yl - ys + i * ys2 - j * dy
x(6, i, j) = xr + xs - i * dx
y(6, i, j) = yr + ys - j * ys2 + i * dy
NEXT j: NEXT i
Init 'set original colours
Redraw 'paint all squares
END SUB
SUB Init
FOR n = 1 TO 6: FOR i = 1 TO 3: FOR j = 1 TO 3
c(n, i, j) = n: NEXT j: NEXT i: NEXT n
END SUB
SUB mouse (axx) 'Reset, show or hide mouse
a(2) = axx 'sets register ax
DEF SEG = VARSEG(a(1)) 'find address
CALL ABSOLUTE(VARPTR(a(1)))
DEF SEG 'bx,cx,dx now in a(15 to 17)
END SUB
SUB MouseLimit 'Restrict mouse to top panel
b(2) = 7: b(4) = 60: b(6) = 420 'ax,cx,dx
DEF SEG = VARSEG(b(1)) 'find address
CALL ABSOLUTE(VARPTR(b(1)))
DEF SEG 'x moves restricted
b(2) = 8: b(4) = 40: b(6) = 88 'ax,cx,dx
DEF SEG = VARSEG(b(1)) 'find address
CALL ABSOLUTE(VARPTR(b(1)))
DEF SEG 'y moves restricted
END SUB
SUB PrStr (st$, row) 'Prints a string, col 58
LOCATE row, 58: PRINT st$
END SUB
SUB Redraw 'recolour all squares
FOR n = 1 TO 6: FOR i = 1 TO 3: FOR j = 1 TO 3
PAINT (x(n, i, j), y(n, i, j)), c(n, i, j), 15
NEXT j: NEXT i: NEXT n
END SUB
DEFINT A-Z 'default integers
DECLARE SUB Scramble ()
DECLARE SUB Init ()
DECLARE SUB Redraw ()
DECLARE SUB Grafic ()
DECLARE SUB MouseLimit ()
DECLARE SUB mouse (axx)
DECLARE SUB Rotate (fac, rot)
DECLARE SUB MidLayer (fac)
DECLARE SUB PrStr (st$, row)
DECLARE SUB Solve ()
DECLARE SUB RotCube ()
DECLARE SUB Rotpr (fac, rot)
DECLARE SUB Edges1 ()
DECLARE SUB Corners1 ()
DECLARE SUB Edges2 ()
DECLARE SUB Edges2a ()
DECLARE SUB Corners3 ()
DECLARE SUB Edges3 ()
DECLARE SUB Twirls ()
DECLARE SUB Flips ()
DIM SHARED face(6) AS STRING * 7
DIM SHARED ang(3) AS STRING * 3
DIM SHARED blank AS STRING * 22
DIM SHARED c(6, 3, 3), f(6, 4)
DIM SHARED x(6, 3, 3), y(6, 3, 3)
DIM SHARED a(1 TO 17)
RANDOMIZE TIMER
FOR I = 1 TO 17: READ a(I): NEXT
DATA -18288,0,13261,-23762,26
DATA -30418,7198,11776,3721,30
DATA -30418,8214,-13568,0,0,0,0
DIM SHARED B(1 TO 8)
FOR I = 1 TO 8: READ B(I): NEXT
DATA -18288,0,-18032,0,-17776,0
DATA 13261,203
DIM SHARED pause, count
SCREEN 12 'VGA 640x480
mouse 0 'Reset mouse driver
MouseLimit
Grafic 'draw initial cube
DO 'the program loop
mouse 1 'show mouse
DO: mouse 3
LOOP UNTIL a(15) > 0
TIM! = TIMER + .33 'float tim
DO: LOOP UNTIL TIMER > TIM!
click = a(15)
cxx = a(16): dxx = a(17)
mouse 2 'hide mouse
IF click < 2 THEN
FAC = INT((cxx + 8) / 56)
rot = INT((dxx - 16) / 16)
LOCATE 1, 1: PRINT FAC; rot
IF FAC > 0 AND FAC < 8 THEN
IF rot > 0 AND rot < 5 THEN
IF FAC = 7 THEN
IF rot = 1 THEN Init 'Reset
IF rot = 3 THEN Solve
IF rot = 4 THEN Scramble
IF rot = 2 THEN
pause = 1 - pause
IF pause = 1 THEN
PrStr "Pause ON ", 1
ELSE
PrStr "Pause OFF", 1
END IF
END IF
ELSE
IF rot < 4 THEN
ROTATE FAC, rot 'rotate face
ELSE 'rotate cube
IF FAC < 3 THEN opp = 3 - FAC
IF FAC > 2 THEN opp = 7 - FAC
IF FAC > 4 THEN opp = 11 - FAC
ROTATE FAC, 1'face clock
ROTATE opp, 3'opp. anti
MidLayer FAC 'middle,clock
END IF
END IF
END IF
END IF
Redraw 'recolour all squares
END IF
LOOP UNTIL click = 2
CLS : SCREEN 0 'back to text
SUB Corners1
'Rotate cube about vertical to 4 positions.
'At each, note correct u/f/r, find it (8 poss.
'locations) and moves it to d/f/r initially.
PrStr "Top layer corners", 3: uc = c(1, 2, 2)
FOR n = 1 TO 4: fc = c(5, 2, 2): rc = c(4, 2, 2)
'U & F & R centre colours. u/f/r corner
'must have same 3 colours, i, j & k.
'Even if u/f/r is correct , move it to d/f/r
I = c(1, 3, 1): J = c(5, 1, 3): k = c(4, 3, 3)
IF I = uc OR J = uc OR k = uc THEN '|copy
IF I = fc OR J = fc OR k = fc THEN '|
IF I = rc OR J = rc OR k = rc THEN '|
PrStr "Move u/f/r to d/f/r ", 4
PrStr "ie. R-1DR ", 5
Rotpr 4, 3: Rotpr 2, 1: Rotpr 4, 1
END IF '|copy
END IF '|
END IF '|
'if u/b/r is correct u/f/r, move it to d/f/r
I = c(1, 3, 3): J = c(6, 1, 3): k = c(4, 3, 1)
'copy 3 IF statements
IF I = uc OR J = uc OR k = uc THEN '|copy
IF I = fc OR J = fc OR k = fc THEN '|
IF I = rc OR J = rc OR k = rc THEN '|
PrStr "Move u/b/r to d/f/r ", 4
PrStr "ie. B-1D-1B ", 5
Rotpr 6, 3: Rotpr 2, 3: Rotpr 6, 1
'copy 3 END IFs
END IF '|copy
END IF '|
END IF '|
'if u/b/l is correct u/f/r, move it to d/f/r
I = c(1, 1, 3): J = c(6, 3, 3): k = c(3, 3, 1)
'copy 3 IF statements
IF I = uc OR J = uc OR k = uc THEN '|copy
IF I = fc OR J = fc OR k = fc THEN '|
IF I = rc OR J = rc OR k = rc THEN '|
PrStr "Move u/b/l to d/f/r ", 4
PrStr "ie. L-1D2L ", 5
Rotpr 3, 3: Rotpr 2, 2: Rotpr 3, 1
'copy 3 END IFs
END IF '|copy
END IF '|
END IF '|
'if u/f/l is correct u/f/r, move it to d/f/r
I = c(1, 1, 1): J = c(5, 1, 1): k = c(3, 1, 1)
'copy 3 IF statements
IF I = uc OR J = uc OR k = uc THEN '|copy
IF I = fc OR J = fc OR k = fc THEN '|
IF I = rc OR J = rc OR k = rc THEN '|
PrStr "Move u/f/l to d/f/r ", 4
PrStr "ie. LDL-1 ", 5
Rotpr 3, 1: Rotpr 2, 1: Rotpr 3, 3
'copy 3 END IFs
END IF '|copy
END IF '|
END IF '|
'if d/b/r is correct u/f/r, move it to d/f/r
I = c(2, 1, 1): J = c(6, 1, 1): k = c(4, 1, 1)
'copy 3 IF statements
IF I = uc OR J = uc OR k = uc THEN '|copy
IF I = fc OR J = fc OR k = fc THEN '|
IF I = rc OR J = rc OR k = rc THEN '|
PrStr "Move d/b/r to d/f/r ", 4
PrStr "ie. D-1 ", 5
Rotpr 2, 3
'copy 3 END IFs
END IF '|copy
END IF '|
END IF '|
'if d/b/l is correct u/f/r, move it to d/f/r
I = c(2, 1, 3): J = c(6, 3, 1): k = c(3, 3, 3)
'copy 3 IF statements
IF I = uc OR J = uc OR k = uc THEN '|copy
IF I = fc OR J = fc OR k = fc THEN '|
IF I = rc OR J = rc OR k = rc THEN '|
PrStr "Move d/b/l to d/f/r ", 4
PrStr "ie. D2 ", 5
Rotpr 2, 2
'copy 3 END IFs
END IF '|copy
END IF '|
END IF '|
'if d/f/l is correct u/f/r, move it to d/f/r
I = c(2, 3, 3): J = c(5, 3, 1): k = c(3, 1, 3)
'copy 3 IF statements
IF I = uc OR J = uc OR k = uc THEN '|copy
IF I = fc OR J = fc OR k = fc THEN '|
IF I = rc OR J = rc OR k = rc THEN '|
PrStr "Move d/f/l to d/f/r ", 4
PrStr "ie. D ", 5
Rotpr 2, 1
'copy 3 END IFs
END IF '|copy
END IF '|
END IF '|
'--------- u/f/r cube now at d/f/r. ----------
'--------- So move to it to u/f/r ----------
PrStr "Move d/f/r to u/f/r ", 4
IF c(2, 3, 1) = uc THEN 'if uc colour on D
'face, it must be moved to R face
PrStr "ie. R-1DRD2 ", 5
Rotpr 4, 3: Rotpr 2, 1: Rotpr 4, 1: Rotpr 2, 2
END IF
IF c(5, 3, 3) = uc THEN 'if uc colour on F
PrStr "ie. FDF-1 ", 5
Rotpr 5, 1: Rotpr 2, 1: Rotpr 5, 3'move to u/r
END IF
IF c(4, 1, 3) = uc THEN 'if uc colour on R
PrStr "ie. R-1D-1R ", 5
Rotpr 4, 3: Rotpr 2, 3: Rotpr 4, 1'move to u/r
END IF
IF n < 4 THEN RotCube
NEXT n
PrStr blank, 3: PrStr blank, 4
PrStr blank, 5: PrStr blank, 6
END SUB
SUB Corners3
PrStr "Sort top corners", 3: n = 0: order = 0
DO UNTIL (order > 900 AND order < 1100) OR order = 1111
n = n + 1 'number of loop
IF n > 1 THEN RotCube 'rotate whole cube
'is u/r/f in correct position ?
t1 = c(4, 2, 2): t2 = c(5, 2, 2)'r & f colours
I = c(1, 3, 1): J = c(5, 1, 3): k = c(4, 3, 3)
IF I = t1 OR J = t1 OR k = t1 THEN
IF I = t2 OR J = t2 OR k = t2 THEN order = 1000
END IF
'is u/r/b in correct position ?
t1 = c(4, 2, 2): t2 = c(6, 2, 2)'r & b colours
I = c(1, 3, 3): J = c(4, 3, 1): k = c(6, 1, 3)
IF I = t1 OR J = t1 OR k = t1 THEN
IF I = t2 OR J = t2 OR k = t2 THEN order = order + 100
END IF
'is u/l/b in correct position ?
t1 = c(3, 2, 2): t2 = c(6, 2, 2)'l & b colours
I = c(1, 1, 3): J = c(3, 3, 1): k = c(6, 3, 3)
IF I = t1 OR J = t1 OR k = t1 THEN
IF I = t2 OR J = t2 OR k = t2 THEN order = order + 10
END IF
'is u/l/f in correct position ?
t1 = c(5, 2, 2): t2 = c(3, 2, 2)'l & f colours
I = c(1, 1, 1): J = c(3, 1, 1): k = c(5, 1, 1)
IF I = t1 OR J = t1 OR k = t1 THEN
IF I = t2 OR J = t2 OR k = t2 THEN order = order + 1
END IF
IF order = 0 THEN 'no corners correct
PrStr "Rotate top layer only ", 4
Rotpr 1, 1: n = 0: PrStr blank, 4: PrStr blank, 6
END IF 'ie. need to go around loop again
LOOP
LOCATE 2, 58: PRINT "Order is "; order
SELECT CASE order
CASE 1000: 'only u/r/f correct so other 3
'must circulate - clock or anticlock?
lc = c(3, 2, 2): bc = c(6, 2, 2)'l & b colours
IF c(1, 1, 1) = lc OR c(3, 1, 1) = lc OR c(5, 1, 1) = lc THEN
IF c(1, 1, 1) = bc OR c(3, 1, 1) = bc OR c(5, 1, 1) = bc THEN
PrStr "ie. L-1URU-1LUR-1U-1 ", 5
'u/l/f goes clockw. to u/l/b
Rotpr 3, 3: Rotpr 1, 1: Rotpr 4, 1: Rotpr 1, 3
Rotpr 3, 1: Rotpr 1, 1: Rotpr 4, 3: Rotpr 1, 3
END IF
END IF
IF c(1, 3, 3) = lc OR c(4, 3, 1) = lc OR c(6, 1, 3) = lc THEN
IF c(1, 3, 3) = bc OR c(4, 3, 1) = bc OR c(6, 1, 3) = bc THEN
PrStr "ie. URU-1L-1UR-1U-1L ", 5
'u/r/b goes anticl. to u/l/b
Rotpr 1, 1: Rotpr 4, 1: Rotpr 1, 3: Rotpr 3, 3
Rotpr 1, 1: Rotpr 4, 3: Rotpr 1, 3: Rotpr 3, 1
END IF
END IF
CASE 1001: 'u/r/f and u/l/f correct
PrStr "ie. FU-1B-1UF-1U-1BU2 ", 5
Rotpr 5, 1: Rotpr 1, 3: Rotpr 6, 3: Rotpr 1, 1
Rotpr 5, 3: Rotpr 1, 3: Rotpr 6, 1: Rotpr 1, 2
CASE 1010: 'u/r/f and u/l/b correct
PrStr "ie. UFURU-1R-1F-1 ", 5
Rotpr 1, 1: Rotpr 5, 1: Rotpr 1, 1: Rotpr 4, 1
Rotpr 1, 3: Rotpr 4, 3: Rotpr 5, 3
END SELECT
PrStr blank, 3: PrStr blank, 4
PrStr blank, 5: PrStr blank, 6
END SUB
SUB Edges1
'locate u/f edge cube (23 other possible
'positions/orientations) and move to u/f
PrStr "Top layer edges", 3: uc = c(1, 2, 2) 'U &
FOR n = 1 TO 4: fc = c(5, 2, 2) '..F Centre colours
'if at u/f but flipped. (If not flipped, leave it)
IF c(1, 2, 1) = fc AND c(5, 1, 2) = uc THEN
PrStr "Flip u/f cube ", 4: PrStr "ie. F2LD-1L-1F", 5
Rotpr 5, 2: Rotpr 3, 1: Rotpr 2, 3: Rotpr 3, 3: Rotpr 5, 1
END IF
'if at r/f (2 orientations at each position)
IF c(4, 2, 3) = uc AND c(5, 2, 3) = fc THEN
PrStr "Move r/f to u/f", 4: PrStr "ie. F-1 ", 5
Rotpr 5, 3
END IF
IF c(4, 2, 3) = fc AND c(5, 2, 3) = uc THEN
PrStr "Move r/f to u/f", 4: PrStr "ie. FLD-1L-1F", 5
Rotpr 5, 1: Rotpr 3, 1: Rotpr 2, 3: Rotpr 3, 3: Rotpr 5, 1
END IF
'if at d/f
IF c(2, 3, 2) = uc AND c(5, 3, 2) = fc THEN
PrStr "Move d/f to u/f", 4: PrStr "ie. F2 ", 5
Rotpr 5, 2
END IF
IF c(2, 3, 2) = fc AND c(5, 3, 2) = uc THEN
PrStr "Move d/f to u/f", 4: PrStr "ie. LD-1L-1F ", 5
Rotpr 3, 1: Rotpr 2, 3: Rotpr 3, 3: Rotpr 5, 1
END IF
'if at l/f
IF c(3, 1, 2) = uc AND c(5, 2, 1) = fc THEN
PrStr "Move l/f to u/f", 4: PrStr "ie. F ", 5
Rotpr 5, 1
END IF
IF c(3, 1, 2) = fc AND c(5, 2, 1) = uc THEN
PrStr "Move l/f to u/f", 4: PrStr "ie.F-1LD-1L-1F", 5
Rotpr 5, 3: Rotpr 3, 1: Rotpr 2, 3: Rotpr 3, 3: Rotpr 5, 1
END IF
'if at d/l
IF c(2, 2, 3) = fc AND c(3, 2, 3) = uc THEN
PrStr "Move d/l to u/f", 4: PrStr "ie. L-1FL ", 5
Rotpr 3, 3: Rotpr 5, 1: Rotpr 3, 1
END IF
IF c(2, 2, 3) = uc AND c(3, 2, 3) = fc THEN
PrStr "Move d/l to u/f", 4: PrStr "ie. DF2 ", 5
Rotpr 2, 1: Rotpr 5, 2
END IF
'if at d/b
IF c(2, 1, 2) = uc AND c(6, 2, 1) = fc THEN
PrStr "Move d/b to u/f", 4: PrStr "ie. D2F2 ", 5
Rotpr 2, 2: Rotpr 5, 2
END IF
IF c(2, 1, 2) = fc AND c(6, 2, 1) = uc THEN
PrStr "Move d/b to u/f", 4: PrStr "ie. DL-1FL ", 5
Rotpr 2, 1: Rotpr 3, 3: Rotpr 5, 1: Rotpr 3, 1
END IF
'if at d/r
IF c(2, 2, 1) = fc AND c(4, 1, 2) = uc THEN
PrStr "Move d/r to u/f", 4: PrStr "ie. RF-1R-1 ", 5
Rotpr 4, 1: Rotpr 5, 3: Rotpr 4, 3
END IF
IF c(2, 2, 1) = uc AND c(4, 1, 2) = fc THEN
PrStr "Move d/r to u/f", 4: PrStr "ie. D-1F2 ", 5
Rotpr 2, 3: Rotpr 5, 2
END IF
'if at b/r
IF c(4, 2, 1) = fc AND c(6, 1, 2) = uc THEN
PrStr "Move b/r to u/f", 4: PrStr "ie. RD-1F2R-1", 5
Rotpr 4, 1: Rotpr 2, 3: Rotpr 5, 2: Rotpr 4, 3
END IF
IF c(4, 2, 1) = uc AND c(6, 1, 2) = fc THEN
PrStr "Move b/r to u/f", 4: PrStr "ie. R2F-1R2 ", 5
Rotpr 4, 2: Rotpr 5, 3: Rotpr 4, 2
END IF
'if at b/l
IF c(3, 3, 2) = fc AND c(6, 3, 2) = uc THEN
PrStr "Move b/l to u/f", 4: PrStr "ie. L-1DF2L ", 5
Rotpr 3, 3: Rotpr 2, 1: Rotpr 5, 2: Rotpr 3, 1
END IF
IF c(3, 3, 2) = uc AND c(6, 3, 2) = fc THEN
PrStr "Move b/l to u/f", 4: PrStr "ie. L2FL2 ", 5
Rotpr 3, 2: Rotpr 5, 1: Rotpr 3, 2
END IF
'if at l/u
IF c(3, 2, 1) = fc AND c(1, 1, 2) = uc THEN
PrStr "Move l/u to u/f", 4: PrStr "ie. L2DF2 ", 5
Rotpr 3, 2: Rotpr 2, 1: Rotpr 5, 2
END IF
IF c(3, 2, 1) = uc AND c(1, 1, 2) = fc THEN
PrStr "Move l/u to u/f", 4: PrStr "ie. LF ", 5
Rotpr 3, 1: Rotpr 5, 1
END IF
'if at b/u
IF c(6, 2, 3) = fc AND c(1, 2, 3) = uc THEN
PrStr "Move b/u to u/f", 4: PrStr "ie. B2D2F2 ", 5
Rotpr 6, 2: Rotpr 2, 2: Rotpr 5, 2
END IF
IF c(6, 2, 3) = uc AND c(1, 2, 3) = fc THEN
PrStr "Move b/u to u/f", 4: PrStr "ie. BL-1DLF2 ", 5
Rotpr 6, 1: Rotpr 3, 3: Rotpr 2, 1: Rotpr 3, 1: Rotpr 5, 2
END IF
'if at r/u
IF c(4, 3, 2) = fc AND c(1, 3, 2) = uc THEN
PrStr "Move r/u to u/f", 4: PrStr "ie. R2D-1F2 ", 5
Rotpr 4, 2: Rotpr 2, 3: Rotpr 5, 2
END IF
IF c(4, 3, 2) = uc AND c(1, 3, 2) = fc THEN
PrStr "Move r/u to u/f", 4: PrStr "ie. R-1F-1 ", 5
Rotpr 4, 3: Rotpr 5, 3
END IF
IF n < 4 THEN RotCube
NEXT n
PrStr blank, 3: PrStr blank, 4: PrStr blank, 5: PrStr blank, 6
END SUB
SUB Edges2
PrStr "Invert whole cube", 3'about L face axis
MidLayer 5: MidLayer 5 'need 2 x 90 deg.
ROTATE 6, 2: Rotpr 5, 2: PrStr blank, 6
'The sorted layer is now on the bottom.
PrStr "Middle layer edges", 3 'tell the user
'Rotating about vert. to 4 separate positions
FOR n = 1 TO 4: lc = c(3, 2, 2): fc = c(5, 2, 2)
'First check 4 middle edge positions for l/f.
'if l/f in correct position and orientation,
'leave it. Otherwise, move it to top layer.
'First, if l/f in position but flipped
IF c(3, 1, 2) = fc AND c(5, 2, 1) = lc THEN
PrStr "l/f to top layer ", 4
PrStr "ie. FU2RUR-1U2F-1 ", 5
Rotpr 5, 1: Rotpr 1, 2: Rotpr 4, 1: Rotpr 1, 1
Rotpr 4, 3: Rotpr 1, 2: Rotpr 5, 3
END IF
'Now, check other 3 vertical edge positions
'if l/f at r/f, move to top layer
IF c(4, 2, 3) = fc OR c(5, 2, 3) = fc THEN
IF c(4, 2, 3) = lc OR c(5, 2, 3) = lc THEN
PrStr "r/f to top layer ", 4
PrStr "ie RU2BUB-1U2R-1 ", 5
Rotpr 4, 1: Rotpr 1, 2: Rotpr 6, 1: Rotpr 1, 1
Rotpr 6, 3: Rotpr 1, 2: Rotpr 4, 3
END IF
END IF
'if l/f at r/b, move to top layer
IF c(4, 2, 1) = fc OR c(6, 1, 2) = fc THEN
IF c(4, 2, 1) = lc OR c(6, 1, 2) = lc THEN
PrStr "r/b to top layer ", 4
PrStr "ie. BU2LUL-1U2B-1 ", 5
Rotpr 6, 1: Rotpr 1, 2: Rotpr 3, 1: Rotpr 1, 1
Rotpr 3, 3: Rotpr 1, 2: Rotpr 6, 3
END IF
END IF
'if l/f at l/b, move to top layer
IF c(3, 3, 2) = fc OR c(6, 3, 2) = fc THEN
IF c(3, 3, 2) = lc OR c(6, 3, 2) = lc THEN
PrStr "l/b to top layer ", 4
PrStr "ie. LU2FUF-1U2L-1 ", 5
Rotpr 3, 1: Rotpr 1, 2: Rotpr 5, 1: Rotpr 1, 1
Rotpr 5, 3: Rotpr 1, 2: Rotpr 3, 3
END IF
END IF
'NOW, find l/f in top layer, transfer to u/r,
'then to l/f using Edges2a()
IF c(4, 3, 2) = fc OR c(1, 3, 2) = fc THEN
IF c(4, 3, 2) = lc OR c(1, 3, 2) = lc THEN
Edges2a 'candidate already at u/l
END IF
END IF
IF c(6, 2, 3) = fc OR c(1, 2, 3) = fc THEN
IF c(6, 2, 3) = lc OR c(1, 2, 3) = lc THEN
PrStr "u/b to u/r ", 4
Rotpr 1, 1: Edges2a 'candidate at u/l
END IF
END IF
IF c(3, 2, 1) = fc OR c(1, 1, 2) = fc THEN
IF c(3, 2, 1) = lc OR c(1, 1, 2) = lc THEN
PrStr "u/l to u/r ", 4
Rotpr 1, 2: Edges2a 'candidate at u/l
END IF
END IF
IF c(5, 1, 2) = fc OR c(1, 2, 1) = fc THEN
IF c(5, 1, 2) = lc OR c(1, 2, 1) = lc THEN
PrStr "u/f to u/r ", 4
Rotpr 1, 3: Edges2a 'candidate at u/f
END IF
END IF
IF n < 4 THEN RotCube
NEXT n
PrStr blank, 3: PrStr blank, 4
PrStr blank, 5: PrStr blank, 6
END SUB
SUB Edges2a 'After Edges2() puts l/f cube to
'u/r position, this puts it in correct
'position and correct orientation.
PrStr "u/r to l/f ", 4
IF c(1, 3, 2) = c(3, 2, 2) THEN 'U face of u/r
PrStr "ie. FU2RUR-1U2F-1 ", 5 'is lc
Rotpr 5, 1: Rotpr 1, 2: Rotpr 4, 1: Rotpr 1, 1
Rotpr 4, 3: Rotpr 1, 2: Rotpr 5, 3
ELSE 'ie. U face of u/r = fc colour
PrStr "ie. UFU2RU-1R-1U2F-1 ", 5
Rotpr 1, 1: Rotpr 5, 1: Rotpr 1, 2: Rotpr 4, 1
Rotpr 1, 3: Rotpr 4, 3: Rotpr 1, 2: Rotpr 5, 3
END IF
END SUB
SUB Edges3
PrStr "Sort top edge cubes", 3: correct = 0
'first note centre colours of faces F, R, B & L
fc = c(5, 2, 2): rc = c(4, 2, 2): bc = c(6, 2, 2): lc = c(3, 2, 2)
'find which cubes are in correct position
IF c(1, 2, 1) = fc OR c(5, 1, 2) = fc THEN correct = 1000
IF c(1, 3, 2) = rc OR c(4, 3, 2) = rc THEN correct = correct + 100
IF c(1, 2, 3) = bc OR c(6, 2, 3) = bc THEN correct = correct + 10
IF c(1, 1, 2) = lc OR c(3, 2, 1) = lc THEN correct = correct + 1
IF correct = 0 THEN 'none of cubes in right place
IF c(1, 2, 1) = rc OR c(5, 1, 2) = rc THEN 'if u/r at u/f
RotCube 'rotate whole cube. note new centre colours
fc = c(5, 2, 2): rc = c(4, 2, 2): bc = c(6, 2, 2): lc = c(3, 2, 2)
END IF
IF c(1, 2, 1) = bc OR c(5, 1, 2) = bc THEN 'if u/b at u/f
PrStr "R2L2DR2L2U2R2L2DR2L2 ", 5'swap opposite pairs
Rotpr 4, 2: Rotpr 3, 2: Rotpr 2, 1: Rotpr 4, 2
Rotpr 3, 2: Rotpr 1, 2: Rotpr 4, 2: Rotpr 3, 2
Rotpr 2, 1: Rotpr 4, 2: Rotpr 3, 2
END IF
IF c(1, 2, 1) = lc OR c(5, 1, 2) = lc THEN 'if u/l at u/f
PrStr "RBUB-1U-1R2F-1U-1FUR ", 5'swap adjacent pairs
Rotpr 4, 1: Rotpr 6, 1: Rotpr 1, 1: Rotpr 6, 3
Rotpr 1, 3: Rotpr 4, 2: Rotpr 5, 3: Rotpr 1, 3
Rotpr 5, 1: Rotpr 1, 1: Rotpr 4, 1
END IF
END IF
SELECT CASE correct 'One cube only correct. Rotate
'whole cube to put it at u/r position
CASE 1000: RotCube: RotCube: RotCube
CASE 10: RotCube
CASE 1: RotCube: RotCube
END SELECT 'in effect, now correct = 100
bc = c(6, 2, 2): lc = c(3, 2, 2)'centre colours of B & L
IF c(1, 2, 1) = bc OR c(5, 1, 2) = bc THEN 'if u/b at u/f
PrStr "L2U-1F-1BL2FB-1U-1L2 ", 5 'circulate anticlock
Rotpr 3, 2: Rotpr 1, 3: Rotpr 5, 3: Rotpr 6, 1: Rotpr 3, 2
Rotpr 5, 1: Rotpr 6, 3: Rotpr 1, 3: Rotpr 3, 2
END IF
IF c(1, 2, 1) = lc OR c(5, 1, 2) = lc THEN 'if u/l at u/f
PrStr "ie. L2UF-1BL2FB-1UL2 ", 5 'circulate clockwise
Rotpr 3, 2: Rotpr 1, 1: Rotpr 5, 3: Rotpr 6, 1: Rotpr 3, 2
Rotpr 5, 1: Rotpr 6, 3: Rotpr 1, 1: Rotpr 3, 2
END IF
PrStr blank, 3: PrStr blank, 4
PrStr blank, 5: PrStr blank, 6
END SUB
SUB Flips 'flips top edge cubes
uc = c(1, 2, 2) 'colour of U centre
DO UNTIL c(1, 2, 1) = uc AND c(1, 1, 2) = uc AND c(1, 2, 3) = uc AND c(1, 3, 2) = uc
n = 0 'ie. until all top faces match uc
DO UNTIL c(1, 2, 1) = c(5, 2, 2) OR n = 4
n = n + 1: RotCube 'until u/f needs flip
LOOP 'if n reaches 4, all are correct
'cubes needing flip always occur in pairs
IF n < 4 THEN 'u/f needs flip. Find other
IF c(1, 3, 2) = c(4, 2, 2) THEN
other = 4 'u/r needs flip
PrStr "u/f & u/r need flip ", 2
ELSE
IF c(1, 2, 3) = c(6, 2, 2) THEN
other = 6 'u/b needs flip
PrStr "u/f & u/b need flip ", 2
ELSE
other = 3 'u/l needs flip
PrStr "u/f & u/l need flip ", 2
END IF
END IF
PrStr "Flip pair top edges ", 4
PrStr "Firstly FUD-1L2U2D2R ", 5
Rotpr 5, 1: Rotpr 1, 1: Rotpr 2, 3: Rotpr 3, 2
Rotpr 1, 2: Rotpr 2, 2: Rotpr 4, 1
PrStr "2nd of pair to u/r ", 5
IF other = 4 THEN Rotpr 1, 1
IF other = 6 THEN Rotpr 1, 2
IF other = 3 THEN Rotpr 1, 3
PrStr "Now R-1D2U2L2DU-1F-1", 5
Rotpr 4, 3: Rotpr 2, 2: Rotpr 1, 2: Rotpr 3, 2
Rotpr 2, 1: Rotpr 1, 3: Rotpr 5, 3
IF other = 4 THEN Rotpr 1, 3
IF other = 6 THEN Rotpr 1, 2
IF other = 3 THEN Rotpr 1, 1
PrStr blank, 2
END IF
LOOP
PrStr blank, 3: PrStr blank, 4
PrStr blank, 5: PrStr blank, 6
END SUB
SUB Grafic
'face name strings in face(6) array
face(1) = " UP ": face(2) = " DOWN "
face(3) = " LEFT ": face(4) = " RIGHT "
face(5) = " FRONT ": face(6) = " BACK "
ang(1) = "+90": ang(2) = "180": ang(3) = "-90"
'blank = " " '22 spaces
blank = SPACE$(22)
'each face's adjacent faces, anticlockwise
f(1, 1) = 5: f(1, 2) = 4: f(1, 3) = 6: f(1, 4) = 3
f(2, 1) = 4: f(2, 2) = 5: f(2, 3) = 3: f(2, 4) = 6
f(3, 1) = 1: f(3, 2) = 6: f(3, 3) = 2: f(3, 4) = 5
f(4, 1) = 6: f(4, 2) = 1: f(4, 3) = 5: f(4, 4) = 2
f(5, 1) = 3: f(5, 2) = 2: f(5, 3) = 4: f(5, 4) = 1
f(6, 1) = 2: f(6, 2) = 3: f(6, 3) = 1: f(6, 4) = 4
CLS : COLOR 15 'now print top table
PrStr "Rightclick to QUIT ", 7
LOCATE 6, 7: PRINT "Rotate whole cube 90"
LOCATE 6, 34: PRINT "Clock wise"
FOR n = 1 TO 6
LOCATE 1, n * 7: PRINT face(n)
LOCATE 2, n * 7 + 2: PRINT n
LOCATE 3, n * 7 + 2: PRINT ang(1)
LOCATE 4, n * 7 + 2: PRINT ang(2)
LOCATE 5, n * 7 + 2: PRINT ang(3)
LINE (n * 56 - 9, 32)-STEP(50, 16), 15, B
LINE (n * 56 - 9, 48)-STEP(50, 16), 15, B
LINE (n * 56 - 9, 64)-STEP(50, 16), 15, B
LINE (n * 56 - 9, 80)-STEP(50, 16), 15, B
NEXT n
LOCATE 3, 50: PRINT "RESET"
LINE (383, 32)-STEP(56, 16), 15, B
LOCATE 4, 50: PRINT "PAUSE"
LINE (383, 48)-STEP(56, 16), 15, B
LOCATE 5, 50: PRINT "SOLVE"
LINE (383, 64)-STEP(56, 16), 15, B
LOCATE 6, 50: PRINT "SCRMBL"
LINE (383, 80)-STEP(56, 16), 15, B
'now print face labels
LOCATE 11, 7: PRINT face(1)
LOCATE 11, 28: PRINT face(1)
LOCATE 25, 67: PRINT face(2)
LOCATE 25, 48: PRINT face(2)
LOCATE 27, 8: PRINT face(3)
LOCATE 9, 69: PRINT face(4)
LOCATE 27, 27: PRINT face(5)
LOCATE 9, 46: PRINT face(6)
LOCATE 8, 15: PRINT "OUTSIDE VIEW"
LOCATE 27, 55: PRINT "INSIDE VIEW"
'draw the cube - 9 times
dx = 40: dx3 = 3 * dx: dy = 24: dy3 = 3 * dy
xs = 20: ys = 24: ys2 = 2 * ys: ys6 = 6 * ys: c = 15
FOR xl = 159 TO 161: xr = xl + 320
FOR yl = 288 TO 290: yr = yl - 30
FOR I = 0 TO 3:
LINE (xl - I * dx, yl - I * dy)-STEP(0, ys6), c
LINE (xl - I * dx, yl - I * dy)-STEP(dx3, -dy3), c
LINE (xl + I * dx, yl - I * dy)-STEP(0, ys6), c
LINE (xl + I * dx, yl - I * dy)-STEP(-dx3, -dy3), c
LINE (xl, yl + I * ys2)-STEP(dx3, -dy3), c
LINE (xl, yl + I * ys2)-STEP(-dx3, -dy3), c
LINE (xr - I * dx, yr + I * dy)-STEP(0, -ys6), c
LINE (xr - I * dx, yr + I * dy)-STEP(dx3, dy3), c
LINE (xr + I * dx, yr + I * dy)-STEP(0, -ys6), c
LINE (xr + I * dx, yr + I * dy)-STEP(-dx3, dy3), c
LINE (xr, yr - I * ys2)-STEP(dx3, dy3), c
LINE (xr, yr - I * ys2)-STEP(-dx3, dy3), c
NEXT I: NEXT yl: NEXT xl
sx = xl - xr: sy = yl - yr'draw dashed lines
LINE (xr, yr - ys6)-STEP(sx, sy), c, , &H700
LINE (xr + dx3, yr - dy3)-STEP(sx, sy), c, , &H700
LINE (xr + dx3, yr + dy3)-STEP(sx, sy), c, , &H700
LINE (xr, yr + ys6)-STEP(sx, sy), c, , &H700
LINE (xr - dx3, yr - dy3)-STEP(sx / 3, sy / 3), c, , &H700
LINE (xr - dx3, yr + dy3)-STEP(sx / 4, sy / 4), c, , &H700
'starting coords to paint each square
FOR I = 1 TO 3: FOR J = 1 TO 3
x(1, I, J) = xl + I * dx - J * dx
y(1, I, J) = yl + dy - I * dy - J * dy
x(2, I, J) = xr - J * dx + I * dx
y(2, I, J) = yr - dy + I * dy + J * dy
x(3, I, J) = xl + xs - I * dx
y(3, I, J) = yl - ys + J * ys2 - I * dy
x(4, I, J) = xr - xs + J * dx
y(4, I, J) = yr + ys - I * ys2 + J * dy
x(5, I, J) = xl - xs + J * dx
y(5, I, J) = yl - ys + I * ys2 - J * dy
x(6, I, J) = xr + xs - I * dx
y(6, I, J) = yr + ys - J * ys2 + I * dy
NEXT J: NEXT I
Init 'set original colours
Redraw 'paint all squares
END SUB
SUB Init
FOR n = 1 TO 6: FOR I = 1 TO 3: FOR J = 1 TO 3
c(n, I, J) = n: NEXT J: NEXT I: NEXT n
END SUB
c(f(FAC, 4), 3, 2) = t1: c(f(FAC, 4), 2, 2) = t2
c(f(FAC, 4), 1, 2) = t3
END SUB
SUB mouse (axx) 'Reset, show or hide mouse
a(2) = axx 'sets register ax
DEF SEG = VARSEG(a(1)) 'find address
CALL ABSOLUTE(VARPTR(a(1)))
DEF SEG 'bx,cx,dx now in a(15 to 17)
END SUB
SUB MouseLimit 'Restrict mouse to top panel
B(2) = 7: B(4) = 60: B(6) = 420 'ax,cx,dx
DEF SEG = VARSEG(B(1)) 'find address
CALL ABSOLUTE(VARPTR(B(1)))
DEF SEG 'x moves restricted
B(2) = 8: B(4) = 40: B(6) = 88 'ax,cx,dx
DEF SEG = VARSEG(B(1)) 'find address
CALL ABSOLUTE(VARPTR(B(1)))
DEF SEG 'y moves restricted
END SUB
SUB PrStr (st$, row) 'Prints a string, col 58
LOCATE row, 58: PRINT st$
END SUB
SUB Redraw 'recolour all squares
FOR n = 1 TO 6: FOR I = 1 TO 3: FOR J = 1 TO 3
PAINT (x(n, I, J), y(n, I, J)), c(n, I, J), 15
NEXT J: NEXT I: NEXT n
END SUB
DECLARE FUNCTION FACTOR& (N&)
DEFLNG A-Z
CLS
WIDTH , 50
INPUT N
DO
X = FACTOR(N)
IF X = -1 THEN LOCATE , 40: PRINT N: END
PRINT X; "<"; STRING$(39 - POS(1), 196); CHR$(194); N
PRINT TAB(39); CHR$(179)
N = N \ X
LOOP
DEFLNG A-Z
FUNCTION FACTOR (N)
FOR I = 2 TO SQR(N)
IF (N MOD I) = 0 THEN FACTOR = I: EXIT FUNCTION
NEXT
FACTOR = -1
END FUNCTION
Program to quiz you on the symbols of chemical elements
October 21 2007, 3:45 PM
TYPE ELEMENT
NAME AS STRING * 20
SYMBOL AS STRING * 2
END TYPE
DIM ELEMENTS(1 TO 40) AS ELEMENT
CLS
RANDOMIZE TIMER
FOR I = 1 TO 40
READ ELEMENTS(I).NAME, ELEMENTS(I).SYMBOL
NEXT
DO
X = INT(RND(1) * 40) + 1
PRINT "What is the chemical symbol for "; RTRIM$(ELEMENTS(X).NAME);
INPUT ANSWER$
IF LTRIM$(RTRIM$(ANSWER$)) = RTRIM$(ELEMENTS(X).SYMBOL) THEN
PRINT "CORRECT"
ELSE
PRINT "Sorry, the answer is "; ELEMENTS(X).SYMBOL
END IF
LOOP
DATA Oxygen, O
DATA Mercury, Hg
DATA Gold, Au
DATA Lead, Pb
DATA Sulfur, S
DATA Antimony, Sb
DATA Sodium, Na
DATA Hydrogen, H
DATA Bromine, Br
DATA Potassium, K
DATA Helium, He
DATA Nitrogen, N
DATA Uranium, U
DATA Boron, B
DATA Iron, Fe
DATA Carbon, C
DATA Chlorine, Cl
DATA Silver, Ag
DATA Barium, Ba
DATA Flourine, F
DATA Argon, Ar
DATA Silicon, Si
DATA Aluminum, Al
DATA Neon, Ne
DATA Arsenic, As
DATA Lithium, Li
DATA Magnesium, Mg
DATA Phosphorus, P
DATA Iodine, I
DATA Zinc, Zn
DATA Copper, Cu
DATA Nickel, Ni
DATA Krypton, Kr
DATA Xenon, Xe
DATA Cobalt, Co
DATA Manganese, Mn
DATA Radon, Rn
DATA Calcium, Ca
DATA Titanium, Ti
DATA Plutonium, Pu
This message has been edited by iorr5t on Oct 22, 2007 7:05 AM
DECLARE SUB LLISTSTMT ()
DECLARE SUB LPRINTSTMT ()
DECLARE SUB INITGETSYM (N AS INTEGER)
DECLARE SUB VALIDLINENUM ()
DECLARE SUB DOCMD ()
DECLARE SUB CLEARVARS ()
DECLARE SUB LISTSTMT ()
DECLARE SUB GOTOSTMT ()
DECLARE SUB IFSTMT ()
DECLARE SUB INPUTSTMT ()
DECLARE SUB PRINTSTMT ()
DECLARE SUB SKIPTOEOL ()
DECLARE SUB IDSTMT ()
DECLARE SUB GETSYM ()
DECLARE SUB EXPECT (S AS STRING)
DECLARE SUB GOTOLINE ()
DECLARE FUNCTION EXPRESSION% ()
DECLARE FUNCTION ADDEXPR% ()
DECLARE FUNCTION TERM% ()
DECLARE FUNCTION FACTOR% ()
DECLARE FUNCTION GETVARINDEX% ()
DECLARE FUNCTION ACCEPT% (S AS STRING)
DECLARE SUB GETCH ()
DECLARE SUB READSTR ()
DECLARE SUB READIDENT ()
DECLARE SUB READINT ()
DIM SHARED CH$, THELIN$, PGM$(2000), TOK$
DIM SHARED VARS(26) AS INTEGER, CURLINE AS INTEGER, NUM AS INTEGER
DIM SHARED TEXTP AS INTEGER, ERRORS AS INTEGER
DO
ERRORS = 0
LINE INPUT "> ", PGM$(0)
IF PGM$(0) <> "" THEN
CALL INITGETSYM(0)
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
CALL VALIDLINENUM
PGM$(NUM) = MID$(PGM$(0), TEXTP, LEN(PGM$(0)) - TEXTP + 1)
ELSE
CALL DOCMD
END IF
END IF
LOOP
FUNCTION ACCEPT% (S AS STRING)
ACCEPT% = 0
IF TOK$ = S THEN ACCEPT% = 1: CALL GETSYM
END FUNCTION
FUNCTION ADDEXPR%
DIM N
N = TERM%
ADDEL:
IF TOK$ = "+" THEN CALL GETSYM: N = N + TERM%: GOTO ADDEL
IF TOK$ = "-" THEN CALL GETSYM: N = N - TERM%: GOTO ADDEL
ADDEXPR% = N
END FUNCTION
SUB CLEARVARS
DIM I AS INTEGER
FOR I = 1 TO 26
VARS(I) = 0
NEXT I
END SUB
SUB DOCMD
DIM I AS INTEGER
AGAIN:
IF ERRORS <> 0 THEN EXIT SUB
WHILE TOK$ = ""
IF CURLINE = 0 OR CURLINE >= 1999 THEN EXIT SUB
CALL INITGETSYM(CURLINE + 1)
WEND
IF ACCEPT("STOP") OR ACCEPT("END") THEN EXIT SUB
IF ACCEPT("NEW") THEN
CALL CLEARVARS
FOR I = 1 TO 1999
PGM$(I) = ""
NEXT I
EXIT SUB
END IF
IF ACCEPT("BYE") THEN END
IF ACCEPT("LIST") THEN CALL LISTSTMT: GOTO AGAIN
IF ACCEPT("LLIST") THEN CALL LLISTSTMT: GOTO AGAIN
IF ACCEPT("RUN") THEN
CALL CLEARVARS
CALL INITGETSYM(1)
GOTO AGAIN
END IF
IF ACCEPT("GOTO") THEN CALL GOTOSTMT: GOTO AGAIN
IF ACCEPT("IF") THEN CALL IFSTMT: GOTO AGAIN
IF ACCEPT("INPUT") THEN CALL INPUTSTMT: GOTO AGAIN
IF ACCEPT("PRINT") THEN CALL PRINTSTMT: GOTO AGAIN
IF ACCEPT("LPRINT") THEN CALL LPRINTSTMT: GOTO AGAIN
IF ACCEPT("REM") THEN CALL SKIPTOEOL: GOTO AGAIN
IF LEFT$(TOK$, 1) >= "A" AND LEFT$(TOK$, 1) <= "Z" THEN
CALL IDSTMT
GOTO AGAIN
END IF
PRINT "UNKNOWN TOKEN "; TOK$; " AT LINE "; CURLINE
END SUB
SUB EXPECT (S AS STRING)
IF ACCEPT(S) <> 0 THEN EXIT SUB
ERRORS = 1
PRINT "EXPECTING "; S; " BUT FOUND "; TOK$
END SUB
FUNCTION EXPRESSION%
DIM N
N = ADDEXPR%
EXPRL:
IF TOK$ = "=" THEN CALL GETSYM: N = N = ADDEXPR%: GOTO EXPRL
IF TOK$ = "<" THEN CALL GETSYM: N = N < ADDEXPR%: GOTO EXPRL
IF TOK$ = ">" THEN CALL GETSYM: N = N > ADDEXPR%: GOTO EXPRL
IF TOK$ = "<>" THEN CALL GETSYM: N = N <> ADDEXPR%: GOTO EXPRL
IF TOK$ = "<=" THEN CALL GETSYM: N = N <= ADDEXPR%: GOTO EXPRL
IF TOK$ = ">=" THEN CALL GETSYM: N = N >= ADDEXPR%: GOTO EXPRL
EXPRESSION% = N
END FUNCTION
FUNCTION FACTOR%
IF ACCEPT("-") THEN
FACTOR% = -FACTOR%
EXIT FUNCTION
END IF
IF ACCEPT("(") THEN
FACTOR% = EXPRESSION
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
FACTOR% = NUM
CALL GETSYM
EXIT FUNCTION
END IF
IF LEFT$(TOK$, 1) >= "A" AND LEFT$(TOK$, 1) <= "Z" THEN
FACTOR% = VARS(GETVARINDEX)
EXIT FUNCTION
END IF
PRINT "UNEXPECTED SYM "; TOK$; " IN FACTOR": ERRORS = 1
END FUNCTION
SUB GETCH
IF TEXTP > LEN(THELIN$) THEN CH$ = "": EXIT SUB
CH$ = MID$(THELIN$, TEXTP, 1)
TEXTP = TEXTP + 1
END SUB
SUB GETSYM
TOK$ = ""
WHILE CH$ <= " "
IF CH$ = "" THEN EXIT SUB
CALL GETCH
WEND
TOK$ = CH$
IF INSTR(",;=+-*/()", CH$) > 0 THEN CALL GETCH: EXIT SUB
IF CH$ = "<" THEN
CALL GETCH
IF CH$ = "=" OR CH$ = ">" THEN
TOK$ = TOK$ + CH$
CALL GETCH
END IF
EXIT SUB
END IF
IF CH$ = ">" THEN
CALL GETCH
IF CH$ = "=" THEN TOK$ = TOK$ + CH$: CALL GETCH
EXIT SUB
END IF
IF CH$ = CHR$(34) THEN CALL READSTR: EXIT SUB
IF CH$ >= "A" AND CH$ <= "Z" THEN CALL READIDENT: EXIT SUB
IF CH$ >= "0" AND CH$ <= "9" THEN CALL READINT: EXIT SUB
PRINT "WHAT->"; CH$: ERRORS = 1
END SUB
FUNCTION GETVARINDEX%
IF LEFT$(TOK$, 1) < "A" OR LEFT$(TOK$, 1) > "Z" THEN
PRINT "NOT A VARIABLE": ERRORS = 1: EXIT FUNCTION
END IF
GETVARINDEX% = ASC(LEFT$(TOK$, 1)) - ASC("A")
CALL GETSYM
END FUNCTION
SUB GOTOLINE
CALL VALIDLINENUM
CALL INITGETSYM(NUM)
END SUB
SUB GOTOSTMT
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
CALL GOTOLINE
EXIT SUB
END IF
PRINT "LINE NUMBER MUST FOLLOW GOTO": ERRORS = 1
END SUB
SUB IDSTMT
DIM VAR AS INTEGER
VAR = GETVARINDEX
CALL EXPECT("=")
VARS(VAR) = EXPRESSION
END SUB
SUB IFSTMT
DIM B AS INTEGER
IF EXPRESSION = 0 THEN CALL SKIPTOEOL: EXIT SUB
B = ACCEPT("THEN")
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
CALL GOTOLINE
END IF
END SUB
SUB INITGETSYM (N AS INTEGER)
CURLINE = N
TEXTP = 1
THELIN$ = PGM$(CURLINE)
CH$ = " "
CALL GETSYM
END SUB
SUB INPUTSTMT
DIM VAR AS INTEGER
IF TOK$ = CHR$(34) THEN
PRINT MID$(TOK$, 2, LEN(TOK$) - 1);
CALL GETSYM
CALL EXPECT(",")
ELSE
PRINT "? ";
END IF
VAR = GETVARINDEX
INPUT VARS(VAR)
END SUB
SUB LISTSTMT
DIM I AS INTEGER
FOR I = 1 TO 1999
IF PGM$(I) <> "" THEN PRINT I; " "; PGM$(I)
NEXT I
PRINT
END SUB
SUB LLISTSTMT
DIM I AS INTEGER
FOR I = 1 TO 1999
IF PGM$(I) <> "" THEN LPRINT I; " "; PGM$(I)
NEXT I
PRINT
END SUB
SUB LPRINTSTMT
DIM LPRINTNL AS INTEGER
LPRINTNL = 1
DO WHILE TOK$ <> ""
LPRINTNL = 1
IF LEFT$(TOK$, 1) = CHR$(34) THEN
LPRINT MID$(TOK$, 2, LEN(TOK$) - 1);
CALL GETSYM
ELSE
LPRINT EXPRESSION;
END IF
IF ACCEPT(",") = 0 AND ACCEPT(";") = 0 THEN EXIT DO
PRINTNL = 0
LOOP
IF PRINTNL <> 0 THEN LPRINT
END SUB
SUB PRINTSTMT
DIM PRINTNL AS INTEGER
PRINTNL = 1
DO WHILE TOK$ <> ""
PRINTNL = 1
IF LEFT$(TOK$, 1) = CHR$(34) THEN
PRINT MID$(TOK$, 2, LEN(TOK$) - 1);
CALL GETSYM
ELSE
PRINT EXPRESSION;
END IF
IF ACCEPT(",") = 0 AND ACCEPT(";") = 0 THEN EXIT DO
PRINTNL = 0
LOOP
IF PRINTNL <> 0 THEN PRINT
END SUB
SUB READIDENT
TOK$ = ""
WHILE CH$ >= "A" AND CH$ <= "Z"
TOK$ = TOK$ + CH$
CALL GETCH
WEND
END SUB
SUB READINT
TOK$ = ""
WHILE CH$ >= "0" AND CH$ <= "9"
TOK$ = TOK$ + CH$
CALL GETCH
WEND
NUM = VAL(TOK$)
END SUB
SUB READSTR
TOK$ = CHR$(34)
CALL GETCH
WHILE CH$ <> CHR$(34)
IF CH$ = "" THEN
PRINT "STRING NOT TERMINATED": ERRORS = 1: EXIT SUB
END IF
TOK$ = TOK$ + CH$
CALL GETCH
WEND
CALL GETCH
END SUB
SUB SKIPTOEOL
WHILE CH$ <> ""
CALL GETCH
WEND
CALL GETSYM
END SUB
FUNCTION TERM%
DIM N
N = FACTOR%
TERML:
IF TOK$ = "*" THEN CALL GETSYM: N = N * FACTOR%: GOTO TERML
IF TOK$ = "/" THEN CALL GETSYM: N = N / FACTOR%: GOTO TERML
TERM% = N
END FUNCTION
SUB VALIDLINENUM
IF NUM > 0 AND NUM <= 1999 THEN EXIT SUB
PRINT "LINE NUMBER OUT OF RANGE": ERRORS = 1
END SUB
FUNCTIONÂ FACTOR%
IFÂ ACCEPT("-")Â THEN
  FACTOR% = -EXPRESSION
  EXIT FUNCTION
ENDÂ IF
IFÂ ACCEPT("(")Â THEN
FACTOR%Â =Â EXPRESSION
CALLÂ EXPECT(")")
EXITÂ FUNCTION
ENDÂ IF
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
FACTOR%Â =Â NUM
CALLÂ GETSYM
EXITÂ FUNCTION
ENDÂ IF
IF LEFT$(TOK$, 1) >= "A" AND LEFT$(TOK$, 1) <= "Z" THEN
FACTOR%Â =Â VARS(GETVARINDEX)
EXITÂ FUNCTION
ENDÂ IF
PRINTÂ "UNEXPECTEDÂ SYMÂ ";Â TOK$;Â "Â INÂ FACTOR":Â ERRORSÂ =Â 1
ENDÂ FUNCTION
DEFINTÂ A-Z
SUBÂ FORSTMT
  DIM VAR AS INTEGER
  VAR = GETVARINDEX
  IF LOOPP >= 0 THEN
    IF CURLINE = LOOPLINES(LOOPP) THEN CALL SKIPTOEOL: EXIT SUB
    FOR I = 0 TO LOOPP
      IF LOOPVARS(LOOPP) = VAR THEN PRINT "FOR INDEX VARIABLE ALREADY IN USE": ERRORS = 1: EXIT SUB
    NEXT
  END IF
  CALL EXPECT("=")
  VARS(VAR) = EXPRESSION
  LOOPP = LOOPP + 1
  LOOPVARS(LOOPP) = VAR
  LOOPLINES(LOOPP) = CURLINE
  CALL EXPECT("TO")
  LOOPMAX(LOOPP) = EXPRESSION
  IF ACCEPT("STEP") THEN LOOPSTEP(LOOPP) = EXPRESSION ELSE LOOPSTEP(LOOPP) = 1
ENDÂ SUB
TOK$Â =Â CH$
IF INSTR(",;=+-*/^()", CH$) > 0 THEN CALL GETCH: EXIT SUB
IFÂ CH$Â =Â "<"Â THEN
CALLÂ GETCH
IFÂ CH$Â =Â "="Â ORÂ CH$Â =Â ">"Â THEN
TOK$Â =Â TOK$Â +Â CH$
CALLÂ GETCH
ENDÂ IF
EXITÂ SUB
ENDÂ IF
IFÂ CH$Â =Â ">"Â THEN
CALLÂ GETCH
IFÂ CH$Â =Â "="Â THENÂ TOK$Â =Â TOK$Â +Â CH$:Â CALLÂ GETCH
EXITÂ SUB
ENDÂ IF
IFÂ CH$Â =Â CHR$(34)Â THENÂ CALLÂ READSTR:Â EXITÂ SUB
IFÂ CH$Â =Â CHR$(39)Â THENÂ CALLÂ SKIPTOEOL:Â EXITÂ SUB
CH$Â =Â UCASE$(CH$)
IFÂ CH$Â >=Â "A"Â ANDÂ CH$Â <=Â "Z"Â THENÂ CALLÂ READIDENT:Â EXITÂ SUB
IFÂ CH$Â >=Â "0"Â ANDÂ CH$Â <=Â "9"Â THENÂ CALLÂ READINT:Â EXITÂ SUB
PRINTÂ "WHAT->";Â CH$:Â ERRORSÂ =Â 1
ENDÂ SUB
FUNCTIONÂ GETVARINDEX%
IF LEFT$(TOK$, 1) < "A" OR LEFT$(TOK$, 1) > "Z" THEN
PRINTÂ "NOTÂ AÂ VARIABLE":Â ERRORSÂ =Â 1:Â EXITÂ FUNCTION
ENDÂ IF
GETVARINDEX% = ASC(LEFT$(TOK$, 1)) - ASC("A")
CALLÂ GETSYM
ENDÂ FUNCTION
SUBÂ GOSUBLINE
  CALL VALIDLINENUM
  STACKP = STACKP + 1
  IF STACKP > 255 THEN PRINT "OUT OF STACK SPACE": ERRORS = 1
  STACK(STACKP) = CURLINE
  CALL INITGETSYM(NUM)
ENDÂ SUB
SUBÂ GOSUBSTMT
  IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
  CALL GOSUBLINE
  EXIT SUB
  END IF
  PRINT "LINE NUMBER MUST FOLLOW GOSUB": ERRORS = 1
ENDÂ SUB
SUBÂ GOTOLINE
CALLÂ VALIDLINENUM
CALLÂ INITGETSYM(NUM)
ENDÂ SUB
SUBÂ GOTOSTMT
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
CALLÂ GOTOLINE
EXITÂ SUB
ENDÂ IF
PRINTÂ "LINEÂ NUMBERÂ MUSTÂ FOLLOWÂ GOTO":Â ERRORSÂ =Â 1
ENDÂ SUB
DEFINTÂ A-Z
SUBÂ NEXTSTMT
  IF LOOPP < 0 THEN PRINT "NEXT WITHOUT FOR": EXIT SUB
  VARS(LOOPVARS(LOOPP)) = VARS(LOOPVARS(LOOPP)) + LOOPSTEP(LOOPP)
  IF VARS(LOOPVARS(LOOPP)) <= LOOPMAX(LOOPP) THEN
    CALL INITGETSYM(LOOPLINES(LOOPP))
  ELSE
    LOOPP = LOOPP - 1
  END IF
ENDÂ SUB
SUBÂ READSTR
TOK$Â =Â CHR$(34)
CALLÂ GETCH
WHILEÂ CH$Â <>Â CHR$(34)
IFÂ CH$Â =Â ""Â THEN
PRINTÂ "STRINGÂ NOTÂ TERMINATED":Â ERRORSÂ =Â 1:Â EXITÂ SUB
ENDÂ IF
TOK$Â =Â TOK$Â +Â CH$
CALLÂ GETCH
WEND
CALLÂ GETCH
ENDÂ SUB
SUBÂ RETURNSTMT
  IF STACKP < 0 THEN PRINT "RETURN WITHOUT GOSUB": EXIT SUB
  LIN = STACK(STACKP)
  STACKP = STACKP - 1
  CALL INITGETSYM(LIN + 1)
ENDÂ SUB
DEFINT A-Z
DECLARE SUB NEXTSTMT ()
DECLARE SUB FORSTMT ()
DECLARE SUB WIDTHSTMT ()
DECLARE SUB LOCATESTMT ()
DECLARE SUB COLORSTMT ()
DECLARE SUB GOSUBLINE ()
DECLARE SUB GOSUBSTMT ()
DECLARE SUB RETURNSTMT ()
DECLARE SUB LLISTSTMT ()
DECLARE SUB LPRINTSTMT ()
DECLARE SUB INITGETSYM (N AS INTEGER)
DECLARE SUB VALIDLINENUM ()
DECLARE SUB DOCMD ()
DECLARE SUB CLEARVARS ()
DECLARE SUB LISTSTMT ()
DECLARE SUB GOTOSTMT ()
DECLARE SUB IFSTMT ()
DECLARE SUB INPUTSTMT ()
DECLARE SUB PRINTSTMT ()
DECLARE SUB SKIPTOEOL ()
DECLARE SUB IDSTMT ()
DECLARE SUB GETSYM ()
DECLARE SUB EXPECT (S AS STRING)
DECLARE SUB GOTOLINE ()
DECLARE FUNCTION EXPRESSION% ()
DECLARE FUNCTION ADDEXPR% ()
DECLARE FUNCTION TERM% ()
DECLARE FUNCTION FACTOR% ()
DECLARE FUNCTION GETVARINDEX% ()
DECLARE FUNCTION ACCEPT% (S AS STRING)
DECLARE SUB GETCH ()
DECLARE SUB READSTR ()
DECLARE SUB READIDENT ()
DECLARE SUB READINT ()
CONST STACKSIZE = 500
CONST PGMSIZE = 2000
DIM SHARED CH$, THELIN$, PGM$(PGMSIZE), TOK$, STACK(STACKSIZE) AS INTEGER
DIM SHARED LOOPVARS(26) AS INTEGER, LOOPLINES(26) AS INTEGER
DIM SHARED LOOPMAX(26) AS INTEGER, LOOPSTEP(26) AS INTEGER
DIM SHARED WSTACK(STACKSIZE)
DIM SHARED STACKP AS INTEGER, LOOPP AS INTEGER, WHILEP AS INTEGER
STACKP = -1
LOOPP = -1
WHILEP = -1
DIM SHARED VARS(26) AS INTEGER, CURLINE AS INTEGER, NUM AS INTEGER
DIM SHARED TEXTP AS INTEGER, ERRORS AS INTEGER
DIM SHARED HEIGHT AS INTEGER, CURWIDTH AS INTEGER
WIDTH 80, 25
HEIGHT = 25
CURWIDTH = 80
DO
ERRORS = 0
LINE INPUT "> ", PGM$(0)
IF PGM$(0) <> "" THEN
CALL INITGETSYM(0)
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
CALL VALIDLINENUM
PGM$(NUM) = MID$(PGM$(0), TEXTP, LEN(PGM$(0)) - TEXTP + 1)
ELSE
CALL DOCMD
END IF
END IF
LOOP
DEFSNG A-Z
FUNCTION ACCEPT% (S AS STRING)
ACCEPT% = 0
IF TOK$ = S THEN ACCEPT% = 1: CALL GETSYM
END FUNCTION
FUNCTION ADDEXPR%
DIM N
N = TERM%
ADDEL:
IF TOK$ = "MOD" THEN CALL GETSYM: N = N MOD TERM%: GOTO ADDEL
IF TOK$ = "+" THEN CALL GETSYM: N = N + TERM%: GOTO ADDEL
IF TOK$ = "-" THEN CALL GETSYM: N = N - TERM%: GOTO ADDEL
ADDEXPR% = N
END FUNCTION
SUB CLEARVARS
DIM I AS INTEGER
FOR I = 1 TO 26
VARS(I) = 0
NEXT I
END SUB
SUB COLORSTMT
IF ACCEPT(",") THEN
BACK = EXPRESSION
IF (NOBACK = 0) AND (BACK > 15 OR BACK < 0) THEN PRINT "ILLEGAL FUNCTION CALL": ERRORS = 1: EXIT SUB
COLOR , BACK
END IF
FORE = EXPRESSION
IF FORE < 0 OR FORE > 31 THEN PRINT "ILLEGAL FUNCTION CALL": ERRORS = 1: EXIT SUB
IF ACCEPT(",") THEN BACK = EXPRESSION ELSE NOBACK = -1
IF (NOBACK = 0) AND (BACK > 15 OR BACK < 0) THEN PRINT "ILLEGAL FUNCTION CALL": ERRORS = 1: EXIT SUB
IF NOBACK = 0 THEN COLOR FORE, BACK ELSE COLOR FORE
END SUB
SUB DOCMD
DIM I AS INTEGER
AGAIN:
IF ERRORS <> 0 THEN EXIT SUB
WHILE TOK$ = ""
IF CURLINE = 0 OR CURLINE >= PGMSIZE THEN EXIT SUB
CALL INITGETSYM(CURLINE + 1)
WEND
IF ACCEPT("STOP") OR ACCEPT("END") THEN EXIT SUB
IF ACCEPT("NEW") THEN
CALL CLEARVARS
FOR I = 1 TO PGMSIZE
PGM$(I) = ""
NEXT I
EXIT SUB
END IF
IF ACCEPT("BYE") THEN END
IF ACCEPT("QUIT") THEN END
IF ACCEPT("LIST") THEN CALL LISTSTMT: GOTO AGAIN
IF ACCEPT("LLIST") THEN CALL LLISTSTMT: GOTO AGAIN
IF ACCEPT("RUN") THEN
CALL CLEARVARS
CALL INITGETSYM(1)
GOTO AGAIN
END IF
IF ACCEPT("GOSUB") THEN CALL GOSUBSTMT: GOTO AGAIN
IF ACCEPT("RETURN") THEN CALL RETURNSTMT: GOTO AGAIN
IF ACCEPT("GOTO") THEN CALL GOTOSTMT: GOTO AGAIN
IF ACCEPT("IF") THEN CALL IFSTMT: GOTO AGAIN
IF ACCEPT("INPUT") THEN CALL INPUTSTMT: GOTO AGAIN
IF ACCEPT("PRINT") THEN CALL PRINTSTMT: GOTO AGAIN
IF ACCEPT("LPRINT") THEN CALL LPRINTSTMT: GOTO AGAIN
IF ACCEPT("REM") THEN CALL SKIPTOEOL: GOTO AGAIN
IF ACCEPT("CLS") THEN CLS : GOTO AGAIN
IF ACCEPT("COLOR") THEN CALL COLORSTMT: GOTO AGAIN
IF ACCEPT("COLOUR") THEN CALL COLORSTMT: GOTO AGAIN
IF ACCEPT("LOCATE") THEN CALL LOCATESTMT: GOTO AGAIN
IF ACCEPT("WIDTH") THEN CALL WIDTHSTMT: GOTO AGAIN
IF ACCEPT("FOR") THEN CALL FORSTMT: GOTO AGAIN
IF ACCEPT("NEXT") THEN CALL NEXTSTMT: GOTO AGAIN
IF LEFT$(TOK$, 1) >= "A" AND LEFT$(TOK$, 1) <= "Z" THEN
CALL IDSTMT
GOTO AGAIN
END IF
PRINT "UNKNOWN TOKEN "; TOK$; " AT LINE "; CURLINE
END SUB
SUB EXPECT (S AS STRING)
IF ACCEPT(S) <> 0 THEN EXIT SUB
ERRORS = 1
PRINT "EXPECTING "; S; " BUT FOUND "; TOK$
END SUB
FUNCTION EXPRESSION%
DIM N
N = ADDEXPR%
EXPRL:
IF TOK$ = "=" THEN CALL GETSYM: N = N = ADDEXPR%: GOTO EXPRL
IF TOK$ = "<" THEN CALL GETSYM: N = N < ADDEXPR%: GOTO EXPRL
IF TOK$ = ">" THEN CALL GETSYM: N = N > ADDEXPR%: GOTO EXPRL
IF TOK$ = "<>" THEN CALL GETSYM: N = N <> ADDEXPR%: GOTO EXPRL
IF TOK$ = "<=" THEN CALL GETSYM: N = N <= ADDEXPR%: GOTO EXPRL
IF TOK$ = ">=" THEN CALL GETSYM: N = N >= ADDEXPR%: GOTO EXPRL
IF TOK$ = "NOT" THEN CALL GETSYM: N = NOT ADDEXPR%: GOTO EXPRL
IF TOK$ = "AND" THEN CALL GETSYM: N = N AND ADDEXPR%: GOTO EXPRL
IF TOK$ = "OR" THEN CALL GETSYM: N = N OR ADDEXPR%: GOTO EXPRL
IF TOK$ = "XOR" THEN CALL GETSYM: N = N XOR ADDEXPR%: GOTO EXPRL
IF TOK$ = "EQV" THEN CALL GETSYM: N = N EQV ADDEXPR%: GOTO EXPRL
IF TOK$ = "IMP" THEN CALL GETSYM: N = N IMP ADDEXPR%: GOTO EXPRL
EXPRESSION% = N
END FUNCTION
FUNCTION FACTOR%
IF ACCEPT("-") THEN
FACTOR% = -EXPRESSION
EXIT FUNCTION
END IF
IF ACCEPT("(") THEN
FACTOR% = EXPRESSION
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
FACTOR% = NUM
CALL GETSYM
EXIT FUNCTION
END IF
IF LEFT$(TOK$, 1) >= "A" AND LEFT$(TOK$, 1) <= "Z" THEN
FACTOR% = VARS(GETVARINDEX)
EXIT FUNCTION
END IF
PRINT "UNEXPECTED SYM "; TOK$; " IN FACTOR": ERRORS = 1
END FUNCTION
DEFINT A-Z
SUB FORSTMT
DIM VAR AS INTEGER
VAR = GETVARINDEX
IF LOOPP >= 0 THEN
IF CURLINE = LOOPLINES(LOOPP) THEN CALL SKIPTOEOL: EXIT SUB
FOR I = 0 TO LOOPP
IF LOOPVARS(LOOPP) = VAR THEN PRINT "FOR INDEX VARIABLE ALREADY IN USE": ERRORS = 1: EXIT SUB
NEXT
END IF
CALL EXPECT("=")
VARS(VAR) = EXPRESSION
LOOPP = LOOPP + 1
LOOPVARS(LOOPP) = VAR
LOOPLINES(LOOPP) = CURLINE
CALL EXPECT("TO")
LOOPMAX(LOOPP) = EXPRESSION
IF ACCEPT("STEP") THEN LOOPSTEP(LOOPP) = EXPRESSION ELSE LOOPSTEP(LOOPP) = 1
END SUB
DEFSNG A-Z
SUB GETCH
IF TEXTP > LEN(THELIN$) THEN CH$ = "": EXIT SUB
CH$ = MID$(THELIN$, TEXTP, 1)
TEXTP = TEXTP + 1
END SUB
SUB GETSYM
TOK$ = ""
WHILE CH$ <= " "
IF CH$ = "" THEN EXIT SUB
CALL GETCH
WEND
TOK$ = CH$
IF INSTR(",;=+-*/^()", CH$) > 0 THEN CALL GETCH: EXIT SUB
IF CH$ = "<" THEN
CALL GETCH
IF CH$ = "=" OR CH$ = ">" THEN
TOK$ = TOK$ + CH$
CALL GETCH
END IF
EXIT SUB
END IF
IF CH$ = ">" THEN
CALL GETCH
IF CH$ = "=" THEN TOK$ = TOK$ + CH$: CALL GETCH
EXIT SUB
END IF
IF CH$ = CHR$(34) THEN CALL READSTR: EXIT SUB
IF CH$ = CHR$(39) THEN CALL SKIPTOEOL: EXIT SUB
CH$ = UCASE$(CH$)
IF CH$ >= "A" AND CH$ <= "Z" THEN CALL READIDENT: EXIT SUB
IF CH$ >= "0" AND CH$ <= "9" THEN CALL READINT: EXIT SUB
PRINT "WHAT->"; CH$: ERRORS = 1
END SUB
FUNCTION GETVARINDEX%
IF LEFT$(TOK$, 1) < "A" OR LEFT$(TOK$, 1) > "Z" THEN
PRINT "NOT A VARIABLE": ERRORS = 1: EXIT FUNCTION
END IF
GETVARINDEX% = ASC(LEFT$(TOK$, 1)) - ASC("A")
CALL GETSYM
END FUNCTION
SUB GOSUBLINE
CALL VALIDLINENUM
STACKP = STACKP + 1
IF STACKP > 255 THEN PRINT "OUT OF STACK SPACE": ERRORS = 1
STACK(STACKP) = CURLINE
CALL INITGETSYM(NUM)
END SUB
SUB GOSUBSTMT
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
CALL GOSUBLINE
EXIT SUB
END IF
PRINT "LINE NUMBER MUST FOLLOW GOSUB": ERRORS = 1
END SUB
SUB GOTOLINE
CALL VALIDLINENUM
CALL INITGETSYM(NUM)
END SUB
SUB GOTOSTMT
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
CALL GOTOLINE
EXIT SUB
END IF
PRINT "LINE NUMBER MUST FOLLOW GOTO": ERRORS = 1
END SUB
SUB IDSTMT
DIM VAR AS INTEGER
VAR = GETVARINDEX
CALL EXPECT("=")
VARS(VAR) = EXPRESSION
END SUB
SUB IFSTMT
DIM B AS INTEGER
IF EXPRESSION = 0 THEN CALL SKIPTOEOL: EXIT SUB
B = ACCEPT("THEN")
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
CALL GOTOLINE
END IF
END SUB
SUB INITGETSYM (N AS INTEGER)
CURLINE = N
TEXTP = 1
THELIN$ = PGM$(CURLINE)
CH$ = " "
CALL GETSYM
END SUB
SUB INPUTSTMT
DIM VAR AS INTEGER
IF TOK$ = CHR$(34) THEN
PRINT MID$(TOK$, 2, LEN(TOK$) - 1);
CALL GETSYM
CALL EXPECT(",")
ELSE
PRINT "? ";
END IF
VAR = GETVARINDEX
INPUT VARS(VAR)
END SUB
SUB LISTSTMT
DIM I AS INTEGER
FOR I = 1 TO PGMSIZE
IF PGM$(I) <> "" THEN PRINT I; " "; PGM$(I)
NEXT I
PRINT
END SUB
SUB LLISTSTMT
OPEN "LPT1" FOR OUTPUT AS #1
DIM I AS INTEGER
FOR I = 1 TO 1999
IF PGM$(I) <> "" THEN PRINT #1, I; " "; PGM$(I)
NEXT I
PRINT
CLOSE #1
END SUB
SUB LOCATESTMT
IF ACCEPT(",") THEN COL = EXPRESSION: ROW = CSRLIN: GOTO 2
ROW = EXPRESSION
IF ROW <= 0 OR ROW > HEIGHT THEN PRINT "ILLEGAL FUNCTION CALL": ERRORS = 1: EXIT SUB
IF ACCEPT(",") THEN COL = EXPRESSION ELSE NOCOL = -1
2 IF (NOCOL = 0) AND (COL <= 0 OR COL >= CURWIDTH) THEN PRINT "ILLEGAL FUNCTION CALL": ERRORS = 1: EXIT SUB
IF NOCOL = 0 THEN LOCATE ROW, COL ELSE LOCATE ROW
END SUB
SUB LPRINTSTMT
OPEN "LPT1" FOR OUTPUT AS #1
DIM LPRINTNL AS INTEGER
LPRINTNL = 1
DO WHILE TOK$ <> ""
LPRINTNL = 1
IF LEFT$(TOK$, 1) = CHR$(34) THEN
PRINT #1, MID$(TOK$, 2, LEN(TOK$) - 1);
CALL GETSYM
ELSE
PRINT #1, EXPRESSION;
END IF
IF ACCEPT(",") = 0 AND ACCEPT(";") = 0 THEN EXIT DO
PRINTNL = 0
LOOP
IF PRINTNL <> 0 THEN PRINT #1, ""
CLOSE #1
END SUB
DEFINT A-Z
SUB NEXTSTMT
IF LOOPP < 0 THEN PRINT "NEXT WITHOUT FOR": EXIT SUB
VARS(LOOPVARS(LOOPP)) = VARS(LOOPVARS(LOOPP)) + LOOPSTEP(LOOPP)
IF VARS(LOOPVARS(LOOPP)) <= LOOPMAX(LOOPP) THEN
CALL INITGETSYM(LOOPLINES(LOOPP))
ELSE
LOOPP = LOOPP - 1
END IF
END SUB
DEFSNG A-Z
SUB PRINTSTMT
DIM PRINTNL AS INTEGER
PRINTNL = 1
DO WHILE TOK$ <> ""
PRINTNL = 1
IF LEFT$(TOK$, 1) = CHR$(34) THEN
PRINT MID$(TOK$, 2, LEN(TOK$) - 1);
CALL GETSYM
ELSE
PRINT EXPRESSION;
END IF
IF ACCEPT(",") = 0 AND ACCEPT(";") = 0 THEN EXIT DO
PRINTNL = 0
LOOP
IF PRINTNL <> 0 THEN PRINT
END SUB
SUB READIDENT
TOK$ = ""
WHILE CH$ >= "A" AND CH$ <= "Z"
TOK$ = TOK$ + CH$
CALL GETCH
WEND
END SUB
SUB READINT
TOK$ = ""
WHILE CH$ >= "0" AND CH$ <= "9"
TOK$ = TOK$ + CH$
CALL GETCH
WEND
NUM = VAL(TOK$)
END SUB
SUB READSTR
TOK$ = CHR$(34)
CALL GETCH
WHILE CH$ <> CHR$(34)
IF CH$ = "" THEN
PRINT "STRING NOT TERMINATED": ERRORS = 1: EXIT SUB
END IF
TOK$ = TOK$ + CH$
CALL GETCH
WEND
CALL GETCH
END SUB
SUB RETURNSTMT
IF STACKP < 0 THEN PRINT "RETURN WITHOUT GOSUB": EXIT SUB
LIN = STACK(STACKP)
STACKP = STACKP - 1
CALL INITGETSYM(LIN + 1)
END SUB
SUB SKIPTOEOL
WHILE CH$ <> ""
CALL GETCH
WEND
CALL GETSYM
END SUB
FUNCTION TERM%
DIM N
N = FACTOR%
TERML:
IF TOK$ = "*" THEN CALL GETSYM: N = N * FACTOR%: GOTO TERML
IF TOK$ = "/" THEN CALL GETSYM: N = N / FACTOR%: GOTO TERML
IF TOK$ = "^" THEN CALL GETSYM: N = N ^ FACTOR: GOTO TERML
TERM% = N
END FUNCTION
SUB VALIDLINENUM
IF NUM > 0 AND NUM <= 1999 THEN EXIT SUB
PRINT "LINE NUMBER OUT OF RANGE": ERRORS = 1
END SUB
DEFINT A-Z
SUB WIDTHSTMT
IF ACCEPT(",") THEN CHEIGHT = EXPRESSION: CWIDTH = CURWIDTH: GOTO 1
CWIDTH = EXPRESSION
IF (CWIDTH <> 40) AND (CWIDTH <> 80) THEN PRINT "ILLEGAL FUNCTION CALL": ERRORS = 1: EXIT SUB
IF ACCEPT(",") THEN CHEIGHT = EXPRESSION ELSE NOCHIEGHT = -1
1 IF (NOCHEIGHT = 0) AND (CHEIGHT <> 25 AND CHEIGHT <> 43 AND CHEIGHT <> 50) THEN PRINT "ILLEGAL FUNCTION CALL": ERRORS = 1: EXIT SUB
IF NOCHEIGHT THEN
WIDTH CWIDTH
CURWIDTH = CWIDTH
ELSE
WIDTH CWIDTH, CHEIGHT
CURWIDTH = CWIDTH
HEIGHT = CHEIGHT
END IF
END SUB
' It now supports decimals, trig functions, (more trig functions than QBASIC)
' -- It has SEC, CSC, COT, ASIN, ACOS, ASEC, ACSC, ACOT, and hyperbolic
' trig functions, DEG and RAD for converting to degrees and radians
' It also has logarithms, which also have more functions than QB
' [base10=LOG10, base e = LN or LOG, base n = LOG(x, n)]; random nunbers;
' GOSUB, RETURN, COLOR, LOCATE, WIDTH, FOR, NEXT, TIMER, variable names
' longer than 1 letter, lowercase keywords, correct order of operations,
' the useless unary plus operator, and probably some other stuff that I
' forgot.
DEFSTR A-Z
DECLARE FUNCTION ASECH# (Z AS DOUBLE)
DECLARE FUNCTION ACOTH# (Z AS DOUBLE)
DECLARE FUNCTION ASINH# (Z AS DOUBLE)
DECLARE FUNCTION ATANH# (Z AS DOUBLE)
DECLARE FUNCTION TANH# (Z AS DOUBLE)
DECLARE FUNCTION ACSCH# (Z AS DOUBLE)
DECLARE FUNCTION ACOSH# (Z AS DOUBLE)
DECLARE FUNCTION COSH# (Z AS DOUBLE)
DECLARE FUNCTION ASIN# (I AS DOUBLE)
DECLARE FUNCTION SINH# (Z AS DOUBLE)
DECLARE SUB RANDOMIZER ()
DECLARE FUNCTION EXPT# ()
DECLARE SUB NEXTSTMT ()
DECLARE SUB FORSTMT ()
DECLARE SUB WIDTHSTMT ()
DECLARE SUB LOCATESTMT ()
DECLARE SUB COLORSTMT ()
DECLARE SUB GOSUBLINE ()
DECLARE SUB GOSUBSTMT ()
DECLARE SUB RETURNSTMT ()
DECLARE SUB LLISTSTMT ()
DECLARE SUB LPRINTSTMT ()
DECLARE SUB INITGETSYM (N%)
DECLARE SUB VALIDLINENUM ()
DECLARE SUB DOCMD ()
DECLARE SUB CLEARVARS ()
DECLARE SUB LISTSTMT ()
DECLARE SUB GOTOSTMT ()
DECLARE SUB IFSTMT ()
DECLARE SUB INPUTSTMT ()
DECLARE SUB PRINTSTMT ()
DECLARE SUB SKIPTOEOL ()
DECLARE SUB IDSTMT ()
DECLARE SUB GETSYM ()
DECLARE SUB EXPECT (S AS STRING)
DECLARE SUB GOTOLINE ()
DECLARE FUNCTION EXPRESSION# ()
DECLARE FUNCTION ADDEXPR# ()
DECLARE FUNCTION TERM# ()
DECLARE FUNCTION FACTOR# ()
DECLARE FUNCTION GETVARINDEX% ()
DECLARE FUNCTION ACCEPT% (S AS STRING)
DECLARE SUB GETCH ()
DECLARE SUB READSTR ()
DECLARE SUB READIDENT ()
DECLARE SUB READINT ()
CONST VARSSIZE = 999
CONST STACKSIZE = 999
CONST PGMSIZE = 4000
CONST PI = 3.14159265358979#
CONST HALFPI = 1.5707963267949#
CONST E = 2.71828182845905#
DIM SHARED CH$, THELIN$, PGM$(PGMSIZE), TOK$, GOSUBSTACK(STACKSIZE) AS INTEGER
DIM SHARED LOOPVARS(VARSSIZE) AS INTEGER, LOOPLINES(VARSSIZE) AS INTEGER
DIM SHARED LOOPMAX(VARSSIZE) AS DOUBLE, LOOPSTEP(VARSSIZE) AS DOUBLE
DIM SHARED STACKP AS INTEGER, LOOPP AS INTEGER, NUMVARS AS INTEGER
STACKP = -1
LOOPP = -1
NUMVARS = 0
DIM SHARED VARNAMES(VARSSIZE) AS STRING
DIM SHARED VARS(VARSSIZE) AS DOUBLE, CURLINE AS INTEGER, NUM AS DOUBLE
DIM SHARED TEXTP AS INTEGER, ERRORS AS INTEGER
DIM SHARED HEIGHT AS INTEGER, CURWIDTH AS INTEGER
WIDTH 80, 25
HEIGHT = 25
CURWIDTH = 80
DO
ERRORS = 0
LINE INPUT "> ", PGM$(0)
IF PGM$(0) <> "" THEN
CALL INITGETSYM(0)
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
CALL VALIDLINENUM
PGM$(NUM) = MID$(PGM$(0), TEXTP, LEN(PGM$(0)) - TEXTP + 1)
ELSE
CALL DOCMD
END IF
END IF
LOOP
FUNCTION ACCEPT% (S AS STRING)
ACCEPT = 0
IF TOK$ = S THEN ACCEPT = 1: CALL GETSYM
END FUNCTION
FUNCTION ACOSH# (Z AS DOUBLE)
ACOSH = LOG(Z + SQR(Z + 1) * SQR(Z - 1))
END FUNCTION
FUNCTION ACOTH# (Z AS DOUBLE)
Z = .5 * (LOG(1 + 1 / Z) - LOG(1 - 1 / Z))
END FUNCTION
FUNCTION ACSCH# (Z AS DOUBLE)
ACSCH = LOG(SQR(1 + Z ^ (-2)) + Z ^ (-1))
END FUNCTION
FUNCTION ADDEXPR#
DIM N AS DOUBLE
N = TERM
ADDEL:
IF TOK$ = "MOD" THEN CALL GETSYM: N = N MOD TERM: GOTO ADDEL
IF TOK$ = "+" THEN CALL GETSYM: N = N + TERM: GOTO ADDEL
IF TOK$ = "-" THEN CALL GETSYM: N = N - TERM: GOTO ADDEL
ADDEXPR = N
END FUNCTION
FUNCTION ASECH# (Z AS DOUBLE)
ASECH = LOG(SQR(Z ^ (-1) - 1) * SQR(Z ^ (-1) + 1) + Z ^ (-1))
END FUNCTION
FUNCTION ASIN# (I AS DOUBLE)
IF I = -1 THEN
ASIN = -HALFPI
ELSEIF I = 1 THEN
ASIN = HALFPI
ELSE
ASIN = ATN(I / SQR(1 - I * I))
END IF
END FUNCTION
FUNCTION ASINH# (Z AS DOUBLE)
ASINH = LOG(Z + SQR(1 + Z ^ 2))
END FUNCTION
FUNCTION ATANH# (Z AS DOUBLE)
ATANH = .5 * (LOG(1 + Z) - LOG(1 - Z))
END FUNCTION
SUB CLEARVARS
DIM I AS INTEGER
FOR I = 1 TO VARSSIZE
VARS(I) = 0
NEXT I
END SUB
SUB COLORSTMT
DIM BACK AS INTEGER, FORE AS INTEGER, NOBACK AS INTEGER
IF ACCEPT(",") THEN
BACK = EXPRESSION
IF (NOBACK = 0) AND (BACK > 15 OR BACK < 0) THEN PRINT "ILLEGAL FUNCTION CALL": ERRORS = 1: EXIT SUB
COLOR , BACK
END IF
FORE = EXPRESSION
IF FORE < 0 OR FORE > 31 THEN PRINT "ILLEGAL FUNCTION CALL": ERRORS = 1: EXIT SUB
IF ACCEPT(",") THEN BACK = EXPRESSION ELSE NOBACK = -1
IF (NOBACK = 0) AND (BACK > 15 OR BACK < 0) THEN PRINT "ILLEGAL FUNCTION CALL": ERRORS = 1: EXIT SUB
IF NOBACK = 0 THEN COLOR FORE, BACK ELSE COLOR FORE
END SUB
FUNCTION COSH# (Z AS DOUBLE)
COSH = (E ^ Z + E ^ (-Z)) / 2
END FUNCTION
SUB DOCMD
DIM I AS INTEGER
AGAIN:
IF ERRORS <> 0 THEN EXIT SUB
WHILE TOK$ = ""
IF CURLINE = 0 OR CURLINE >= PGMSIZE THEN EXIT SUB
CALL INITGETSYM(CURLINE + 1)
WEND
IF ACCEPT("STOP") OR ACCEPT("END") THEN EXIT SUB
IF ACCEPT("NEW") THEN
CALL CLEARVARS
FOR I = 1 TO PGMSIZE
PGM$(I) = ""
NEXT I
EXIT SUB
END IF
IF ACCEPT("BYE") THEN END
IF ACCEPT("QUIT") THEN END
IF ACCEPT("LIST") THEN CALL LISTSTMT: GOTO AGAIN
IF ACCEPT("LLIST") THEN CALL LLISTSTMT: GOTO AGAIN
IF ACCEPT("RUN") THEN
CALL CLEARVARS
CALL INITGETSYM(1)
GOTO AGAIN
END IF
IF ACCEPT("RANDOMIZE") THEN CALL RANDOMIZER: GOTO AGAIN
IF ACCEPT("GOSUB") THEN CALL GOSUBSTMT: GOTO AGAIN
IF ACCEPT("RETURN") THEN CALL RETURNSTMT: GOTO AGAIN
IF ACCEPT("GOTO") THEN CALL GOTOSTMT: GOTO AGAIN
IF ACCEPT("GO") THEN
IF ACCEPT("TO") THEN CALL GOTOSTMT: GOTO AGAIN
IF ACCEPT("SUB") THEN CALL GOSUBSTMT: GOTO AGAIN
PRINT "EXPECTED 'GO TO' OR 'GO SUB'": ERRORS = 1: EXIT SUB
END IF
IF ACCEPT("IF") THEN CALL IFSTMT: GOTO AGAIN
IF ACCEPT("INPUT") THEN CALL INPUTSTMT: GOTO AGAIN
IF ACCEPT("PRINT") THEN CALL PRINTSTMT: GOTO AGAIN
IF ACCEPT("LPRINT") THEN CALL LPRINTSTMT: GOTO AGAIN
IF ACCEPT("REM") THEN CALL SKIPTOEOL: GOTO AGAIN
IF ACCEPT("CLS") THEN CLS : GOTO AGAIN
IF ACCEPT("COLOR") OR ACCEPT("COLOUR") THEN CALL COLORSTMT: GOTO AGAIN
IF ACCEPT("LOCATE") THEN CALL LOCATESTMT: GOTO AGAIN
IF ACCEPT("WIDTH") THEN CALL WIDTHSTMT: GOTO AGAIN
IF ACCEPT("FOR") THEN CALL FORSTMT: GOTO AGAIN
IF ACCEPT("NEXT") THEN CALL NEXTSTMT: GOTO AGAIN
IF LEFT$(TOK$, 1) >= "A" AND LEFT$(TOK$, 1) <= "Z" THEN
CALL IDSTMT
GOTO AGAIN
END IF
PRINT "UNKNOWN TOKEN "; TOK$; " AT LINE "; CURLINE
END SUB
SUB EXPECT (S AS STRING)
IF ACCEPT(S) <> 0 THEN EXIT SUB
ERRORS = 1
PRINT "EXPECTING "; S; " BUT FOUND "; TOK$
END SUB
FUNCTION EXPRESSION#
DIM N AS DOUBLE
N = ADDEXPR
EXPRL:
IF TOK$ = "=" THEN CALL GETSYM: N = N = ADDEXPR: GOTO EXPRL
IF TOK$ = "<" THEN CALL GETSYM: N = N < ADDEXPR: GOTO EXPRL
IF TOK$ = ">" THEN CALL GETSYM: N = N > ADDEXPR: GOTO EXPRL
IF TOK$ = "<>" THEN CALL GETSYM: N = N <> ADDEXPR: GOTO EXPRL
IF TOK$ = "<=" THEN CALL GETSYM: N = N <= ADDEXPR: GOTO EXPRL
IF TOK$ = ">=" THEN CALL GETSYM: N = N >= ADDEXPR: GOTO EXPRL
IF TOK$ = "AND" THEN CALL GETSYM: N = N AND ADDEXPR: GOTO EXPRL
IF TOK$ = "OR" THEN CALL GETSYM: N = N OR ADDEXPR: GOTO EXPRL
IF TOK$ = "XOR" THEN CALL GETSYM: N = N XOR ADDEXPR: GOTO EXPRL
IF TOK$ = "EQV" THEN CALL GETSYM: N = N EQV ADDEXPR: GOTO EXPRL
IF TOK$ = "IMP" THEN CALL GETSYM: N = N IMP ADDEXPR: GOTO EXPRL
EXPRESSION = N
END FUNCTION
FUNCTION EXPT#
DIM N AS DOUBLE
N = FACTOR
EXPTL:
IF TOK$ = "^" THEN CALL GETSYM: N = N ^ FACTOR: GOTO EXPTL
EXPT = N
END FUNCTION
FUNCTION FACTOR#
DIM I AS DOUBLE
IF ACCEPT("-") THEN
FACTOR = -EXPT
EXIT FUNCTION
END IF
IF ACCEPT("+") THEN
FACTOR = EXPRESSION
EXIT FUNCTION
END IF
IF ACCEPT("NOT") THEN
FACTOR = NOT EXPRESSION
EXIT FUNCTION
END IF
IF ACCEPT("DEG") THEN
CALL EXPECT("(")
FACTOR = EXPRESSION * 180 / PI
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("RAD") THEN
CALL EXPECT("(")
FACTOR = EXPRESSION * PI / 180
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("SIN") THEN
CALL EXPECT("(")
FACTOR = SIN(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("COS") THEN
CALL EXPECT("(")
FACTOR = COS(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("TAN") THEN
CALL EXPECT("(")
FACTOR = TAN(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ATN") OR ACCEPT("ATAN") THEN
CALL EXPECT("(")
FACTOR = ATN(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ASIN") THEN
CALL EXPECT("(")
FACTOR = ASIN(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ACOS") THEN
CALL EXPECT("(")
FACTOR = HALFPI - ASIN(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ACOT") THEN
CALL EXPECT("(")
FACTOR = HALFPI - ATN(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ASEC") THEN
CALL EXPECT("(")
FACTOR = HALFPI - ASIN(1 / EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ACSC") THEN
CALL EXPECT("(")
FACTOR = ASIN(1 / EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("SEC") THEN
CALL EXPECT("(")
FACTOR = 1 / COS(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("CSC") THEN
CALL EXPECT("(")
FACTOR = 1 / SIN(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("COT") THEN
CALL EXPECT("(")
FACTOR = 1 / TAN(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("SINH") THEN
CALL EXPECT("(")
FACTOR = SINH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("COSH") THEN
CALL EXPECT("(")
FACTOR = COSH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("TANH") THEN
CALL EXPECT("(")
FACTOR = TANH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("SECH") THEN
CALL EXPECT("(")
FACTOR = 1 / COSH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("CSCH") THEN
CALL EXPECT("(")
FACTOR = 1 / SINH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("COTH") THEN
CALL EXPECT("(")
FACTOR = 1 / TANH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ASINH") THEN
CALL EXPECT("(")
FACTOR = ASINH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ACOSH") THEN
CALL EXPECT("(")
FACTOR = ACOSH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ATANH") THEN
CALL EXPECT("(")
FACTOR = ATANH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ACSCH") THEN
CALL EXPECT("(")
FACTOR = ACSCH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ASECH") THEN
CALL EXPECT("(")
FACTOR = ASECH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ACOTH") THEN
CALL EXPECT("(")
FACTOR = ACOTH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("SQR") OR ACCEPT("SQRT") THEN
CALL EXPECT("(")
FACTOR = SQR(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("LN") THEN
CALL EXPECT("(")
FACTOR = LOG(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("LOG10") THEN
CALL EXPECT("(")
FACTOR = LOG(EXPRESSION) / LOG(10)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("LOG") THEN
CALL EXPECT("(")
I = LOG(EXPRESSION)
IF ACCEPT(",") THEN
FACTOR = I / LOG(EXPRESSION)
ELSE
FACTOR = I
END IF
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("EXP") THEN
CALL EXPECT("(")
FACTOR = EXP(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("INT") THEN
CALL EXPECT("(")
FACTOR = INT(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("CINT") THEN
CALL EXPECT("(")
I = EXPRESSION
FACTOR = SGN(I) * INT(ABS(I) + .5)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("CLNG") THEN
CALL EXPECT("(")
I = EXPRESSION
FACTOR = SGN(I) * INT(ABS(I) + .5)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("FIX") THEN
CALL EXPECT("(")
FACTOR = FIX(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("RND") THEN
IF ACCEPT("(") THEN
FACTOR = RND(EXPRESSION)
CALL EXPECT(")")
ELSE
FACTOR = RND
END IF
EXIT FUNCTION
END IF
IF ACCEPT("TIMER") THEN
FACTOR = TIMER
EXIT FUNCTION
END IF
IF ACCEPT("(") THEN
FACTOR = EXPRESSION
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF LEFT$(TOK$, 1) = "." OR (LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9") THEN
FACTOR = NUM
CALL GETSYM
EXIT FUNCTION
END IF
IF LEFT$(TOK$, 1) >= "A" AND LEFT$(TOK$, 1) <= "Z" THEN
FACTOR = VARS(GETVARINDEX)
EXIT FUNCTION
END IF
PRINT "UNEXPECTED SYM "; TOK$; " IN FACTOR": ERRORS = 1
END FUNCTION
SUB FORSTMT
DIM VAR AS INTEGER, I AS INTEGER
VAR = GETVARINDEX
IF LOOPP >= 0 THEN
IF CURLINE = LOOPLINES(LOOPP) THEN CALL SKIPTOEOL: EXIT SUB
FOR I = 0 TO LOOPP
IF LOOPVARS(LOOPP) = VAR THEN PRINT "FOR INDEX VARIABLE ALREADY IN USE": ERRORS = 1: EXIT SUB
NEXT
END IF
CALL EXPECT("=")
VARS(VAR) = EXPRESSION
LOOPP = LOOPP + 1
LOOPVARS(LOOPP) = VAR
LOOPLINES(LOOPP) = CURLINE
CALL EXPECT("TO")
LOOPMAX(LOOPP) = EXPRESSION
IF ACCEPT("STEP") THEN LOOPSTEP(LOOPP) = EXPRESSION ELSE LOOPSTEP(LOOPP) = 1
END SUB
SUB GETCH
IF TEXTP > LEN(THELIN$) THEN CH$ = "": EXIT SUB
CH$ = MID$(THELIN$, TEXTP, 1)
TEXTP = TEXTP + 1
END SUB
SUB GETSYM
TOK$ = ""
WHILE CH$ <= " "
IF CH$ = "" THEN EXIT SUB
CALL GETCH
WEND
TOK$ = CH$
IF INSTR(",;=+-*/\^()", CH$) > 0 THEN CALL GETCH: EXIT SUB
IF CH$ = "<" THEN
CALL GETCH
IF CH$ = "=" OR CH$ = ">" THEN
TOK$ = TOK$ + CH$
CALL GETCH
END IF
EXIT SUB
END IF
IF CH$ = ">" THEN
CALL GETCH
IF CH$ = "=" THEN TOK$ = TOK$ + CH$: CALL GETCH
EXIT SUB
END IF
IF CH$ = CHR$(34) THEN CALL READSTR: EXIT SUB
IF CH$ = CHR$(39) THEN CALL SKIPTOEOL: EXIT SUB
CH$ = UCASE$(CH$)
IF CH$ >= "A" AND CH$ <= "Z" THEN CALL READIDENT: EXIT SUB
IF (CH$ >= "0" AND CH$ <= "9") OR CH$ = "." THEN CALL READINT: EXIT SUB
PRINT "WHAT->"; CH$: ERRORS = 1
END SUB
FUNCTION GETVARINDEX%
DIM I AS INTEGER
IF LEFT$(TOK$, 1) < "A" OR LEFT$(TOK$, 1) > "Z" THEN
PRINT "NOT A VARIABLE": ERRORS = 1: EXIT FUNCTION
END IF
FOR I = 1 TO VARSSIZE
IF VARNAMES(I) = TOK$ THEN
GETVARINDEX = I
CALL GETSYM
EXIT FUNCTION
END IF
NEXT
NUMVARS = NUMVARS + 1
GETVARINDEX = NUMVARS
VARNAMES(NUMVARS) = TOK$
CALL GETSYM
END FUNCTION
SUB GOSUBLINE
CALL VALIDLINENUM
STACKP = STACKP + 1
IF STACKP > 255 THEN PRINT "OUT OF STACK SPACE": ERRORS = 1
GOSUBSTACK(STACKP) = CURLINE
CALL INITGETSYM(INT(NUM))
END SUB
SUB GOSUBSTMT
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
CALL GOSUBLINE
EXIT SUB
END IF
PRINT "LINE NUMBER MUST FOLLOW GOSUB": ERRORS = 1
END SUB
SUB GOTOLINE
CALL VALIDLINENUM
CALL INITGETSYM(INT(NUM))
END SUB
SUB GOTOSTMT
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
CALL GOTOLINE
EXIT SUB
END IF
PRINT "LINE NUMBER MUST FOLLOW GOTO": ERRORS = 1
END SUB
SUB IDSTMT
DIM VAR AS INTEGER
VAR = GETVARINDEX
CALL EXPECT("=")
VARS(VAR) = EXPRESSION
END SUB
SUB IFSTMT
DIM B AS INTEGER
IF EXPRESSION = 0 THEN CALL SKIPTOEOL: EXIT SUB
B = ACCEPT("THEN")
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
CALL GOTOLINE
END IF
END SUB
SUB INITGETSYM (N AS INTEGER)
CURLINE = N
TEXTP = 1
THELIN$ = PGM$(CURLINE)
CH$ = " "
CALL GETSYM
END SUB
SUB INPUTSTMT
DIM VAR AS INTEGER
IF TOK$ = CHR$(34) THEN
PRINT MID$(TOK$, 2, LEN(TOK$) - 1);
CALL GETSYM
CALL EXPECT(",")
ELSE
PRINT "? ";
END IF
VAR = GETVARINDEX
INPUT VARS(VAR)
END SUB
SUB LISTSTMT
DIM I AS INTEGER
FOR I = 1 TO PGMSIZE
IF PGM$(I) <> "" THEN PRINT I; " "; PGM$(I)
NEXT I
PRINT
END SUB
SUB LLISTSTMT
DIM I AS INTEGER
OPEN "LPT1" FOR OUTPUT AS #1
FOR I = 1 TO PGMSIZE
IF PGM$(I) <> "" THEN PRINT #1, I; " "; PGM$(I)
NEXT I
PRINT
CLOSE #1
END SUB
SUB LOCATESTMT
DIM ROW AS INTEGER, COL AS INTEGER, NOCOL AS INTEGER
IF ACCEPT(",") THEN COL = EXPRESSION: ROW = CSRLIN: GOTO 2
ROW = EXPRESSION
IF ROW <= 0 OR ROW > HEIGHT THEN PRINT "ILLEGAL FUNCTION CALL": ERRORS = 1: EXIT SUB
IF ACCEPT(",") THEN COL = EXPRESSION ELSE NOCOL = -1
2 IF (NOCOL = 0) AND (COL <= 0 OR COL >= CURWIDTH) THEN PRINT "ILLEGAL FUNCTION CALL": ERRORS = 1: EXIT SUB
IF NOCOL = 0 THEN LOCATE ROW, COL ELSE LOCATE ROW
END SUB
SUB LPRINTSTMT
DIM LPRINTNL AS INTEGER
OPEN "LPT1" FOR OUTPUT AS #1
LPRINTNL = 1
DO WHILE TOK$ <> ""
LPRINTNL = 1
IF LEFT$(TOK$, 1) = CHR$(34) THEN
PRINT #1, MID$(TOK$, 2, LEN(TOK$) - 1);
CALL GETSYM
ELSE
PRINT #1, EXPRESSION;
END IF
IF ACCEPT(",") = 0 AND ACCEPT(";") = 0 THEN EXIT DO
LPRINTNL = 0
LOOP
IF LPRINTNL <> 0 THEN PRINT #1, ""
CLOSE #1
END SUB
SUB NEXTSTMT
IF LOOPP < 0 THEN PRINT "NEXT WITHOUT FOR": EXIT SUB
VARS(LOOPVARS(LOOPP)) = VARS(LOOPVARS(LOOPP)) + LOOPSTEP(LOOPP)
IF VARS(LOOPVARS(LOOPP)) <= LOOPMAX(LOOPP) THEN
CALL INITGETSYM(LOOPLINES(LOOPP))
ELSE
LOOPP = LOOPP - 1
END IF
END SUB
SUB PRINTSTMT
DIM PRINTNL AS INTEGER
PRINTNL = 1
DO WHILE TOK$ <> ""
PRINTNL = 1
IF LEFT$(TOK$, 1) = CHR$(34) THEN
PRINT MID$(TOK$, 2, LEN(TOK$) - 1);
CALL GETSYM
ELSE
PRINT EXPRESSION;
END IF
IF ACCEPT(",") THEN
PRINT ,
ELSEIF ACCEPT(";") = 0 THEN
EXIT DO
END IF
PRINTNL = 0
LOOP
IF PRINTNL <> 0 THEN PRINT
END SUB
SUB RANDOMIZER
RANDOMIZE EXPRESSION
END SUB
SUB READIDENT
TOK$ = ""
WHILE (UCASE$(CH$) >= "A" AND UCASE$(CH$) <= "Z") OR (CH$ >= "0" AND CH$ <= "9") OR (CH$ = "_")
TOK$ = TOK$ + UCASE$(CH$)
CALL GETCH
WEND
END SUB
SUB READINT
TOK$ = ""
WHILE CH$ >= "0" AND CH$ <= "9"
TOK$ = TOK$ + CH$
CALL GETCH
WEND
IF CH$ = "." THEN
TOK$ = TOK$ + CH$
CALL GETCH
WHILE CH$ >= "0" AND CH$ <= "9"
TOK$ = TOK$ + CH$
CALL GETCH
WEND
END IF
IF CH$ = "E" OR CH$ = "D" THEN
TOK$ = TOK$ + "D"
CALL GETCH
IF CH$ = "+" OR CH$ = "-" THEN TOK$ = TOK$ + CH$: CALL GETCH
WHILE CH$ >= "0" AND CH$ <= "9"
TOK$ = TOK$ + CH$
CALL GETCH
WEND
END IF
NUM = VAL(TOK$)
END SUB
SUB READSTR
TOK$ = CHR$(34)
CALL GETCH
WHILE CH$ <> CHR$(34)
IF CH$ = "" THEN
PRINT "STRING NOT TERMINATED": ERRORS = 1: EXIT SUB
END IF
TOK$ = TOK$ + CH$
CALL GETCH
WEND
CALL GETCH
END SUB
SUB RETURNSTMT
DIM LIN AS INTEGER
IF STACKP < 0 THEN PRINT "RETURN WITHOUT GOSUB": EXIT SUB
LIN = GOSUBSTACK(STACKP)
STACKP = STACKP - 1
CALL INITGETSYM(LIN + 1)
END SUB
FUNCTION SINH# (Z AS DOUBLE)
SINH = (E ^ Z - E ^ (-Z)) / 2
END FUNCTION
SUB SKIPTOEOL
WHILE CH$ <> ""
CALL GETCH
WEND
CALL GETSYM
END SUB
FUNCTION TANH# (Z AS DOUBLE)
TANH = (E ^ (2 * Z) - 1) / (E ^ (2 * Z) + 1)
END FUNCTION
FUNCTION TERM#
DIM N AS DOUBLE, I AS DOUBLE
N = EXPT
TERML:
IF TOK$ = "*" THEN CALL GETSYM: N = N * EXPT: GOTO TERML
IF TOK$ = "/" THEN
CALL GETSYM
I = EXPT
IF I = 0 THEN PRINT "DIVISION BY ZERO": ERRORS = 1: EXIT FUNCTION
N = N / I
GOTO TERML
END IF
IF TOK$ = "\" THEN
CALL GETSYM
I = EXPT
IF I = 0 THEN PRINT "DIVISION BY ZERO": ERRORS = 1: EXIT FUNCTION
N = N \ I
GOTO TERML
END IF
TERM = N
END FUNCTION
SUB VALIDLINENUM
IF NUM > 0 AND NUM <= PGMSIZE THEN EXIT SUB
PRINT "LINE NUMBER OUT OF RANGE": ERRORS = 1
END SUB
SUB WIDTHSTMT
DIM CHEIGHT AS INTEGER, CWIDTH AS INTEGER, NOCHEIGHT AS INTEGER
IF ACCEPT(",") THEN CHEIGHT = EXPRESSION: CWIDTH = CURWIDTH: GOTO 1
CWIDTH = EXPRESSION
IF (CWIDTH <> 40) AND (CWIDTH <> 80) THEN PRINT "ILLEGAL FUNCTION CALL": ERRORS = 1: EXIT SUB
IF ACCEPT(",") THEN CHEIGHT = EXPRESSION ELSE NOCHEIGHT = -1
1 IF (NOCHEIGHT = 0) AND (CHEIGHT <> 25 AND CHEIGHT <> 43 AND CHEIGHT <> 50) THEN PRINT "ILLEGAL FUNCTION CALL": ERRORS = 1: EXIT SUB
IF NOCHEIGHT THEN
WIDTH CWIDTH
CURWIDTH = CWIDTH
ELSE
WIDTH CWIDTH, CHEIGHT
CURWIDTH = CWIDTH
HEIGHT = CHEIGHT
END IF
END SUB
This adds STRING variables, string functions (incl. MID$, LEFT$, RIGHT$, HEX$, OCT$, STR$, CHR$, etc.), some graphics statement.
'$DYNAMIC
DEFSTR A-Z
DECLARE SUB LINEINPUTSTMT ()
DECLARE SUB MIDSTMT ()
DECLARE SUB LINESTMT ()
DECLARE SUB SCREENSTMT ()
DECLARE SUB PSETSTMT ()
DECLARE SUB PRESETSTMT ()
DECLARE FUNCTION STREXPRESSION$ ()
DECLARE SUB STRIDSTMT ()
DECLARE FUNCTION GETSTRINDEX% ()
DECLARE FUNCTION ASECH# (Z AS DOUBLE)
DECLARE FUNCTION ACOTH# (Z AS DOUBLE)
DECLARE FUNCTION ASINH# (Z AS DOUBLE)
DECLARE FUNCTION ATANH# (Z AS DOUBLE)
DECLARE FUNCTION TANH# (Z AS DOUBLE)
DECLARE FUNCTION ACSCH# (Z AS DOUBLE)
DECLARE FUNCTION ACOSH# (Z AS DOUBLE)
DECLARE FUNCTION COSH# (Z AS DOUBLE)
DECLARE FUNCTION ASIN# (I AS DOUBLE)
DECLARE FUNCTION SINH# (Z AS DOUBLE)
DECLARE SUB RANDOMIZER ()
DECLARE FUNCTION EXPT# ()
DECLARE SUB NEXTSTMT ()
DECLARE SUB FORSTMT ()
DECLARE SUB WIDTHSTMT ()
DECLARE SUB LOCATESTMT ()
DECLARE SUB COLORSTMT ()
DECLARE SUB GOSUBLINE ()
DECLARE SUB GOSUBSTMT ()
DECLARE SUB RETURNSTMT ()
DECLARE SUB LLISTSTMT ()
DECLARE SUB LPRINTSTMT ()
DECLARE SUB INITGETSYM (N%)
DECLARE SUB VALIDLINENUM ()
DECLARE SUB DOCMD ()
DECLARE SUB CLEARVARS ()
DECLARE SUB LISTSTMT ()
DECLARE SUB GOTOSTMT ()
DECLARE SUB IFSTMT ()
DECLARE SUB INPUTSTMT ()
DECLARE SUB PRINTSTMT ()
DECLARE SUB SKIPTOEOL ()
DECLARE SUB IDSTMT ()
DECLARE SUB GETSYM ()
DECLARE SUB EXPECT (S AS STRING)
DECLARE SUB GOTOLINE ()
DECLARE FUNCTION EXPRESSION# ()
DECLARE FUNCTION ADDEXPR# ()
DECLARE FUNCTION TERM# ()
DECLARE FUNCTION FACTOR# ()
DECLARE FUNCTION GETVARINDEX% ()
DECLARE FUNCTION ACCEPT% (S AS STRING)
DECLARE SUB GETCH ()
DECLARE SUB READSTR ()
DECLARE SUB READIDENT ()
DECLARE SUB READINT ()
ON ERROR GOTO 1
CONST VARSSIZE = 512
CONST STACKSIZE = 512
CONST PGMSIZE = 4096
CONST PI = 3.14159265358979#
CONST HALFPI = 1.5707963267949#
CONST E = 2.71828182845905#
DIM SHARED CH$, THELIN$, PGM$(PGMSIZE), TOK$, GOSUBSTACK(STACKSIZE) AS INTEGER
DIM SHARED LOOPVARS(VARSSIZE) AS INTEGER, LOOPLINES(VARSSIZE) AS INTEGER
DIM SHARED LOOPMAX(VARSSIZE) AS DOUBLE, LOOPSTEP(VARSSIZE) AS DOUBLE
DIM SHARED STACKP AS INTEGER, LOOPP AS INTEGER, NUMVARS AS INTEGER
DIM SHARED STRS(VARSSIZE) AS STRING, STRNAMES(VARSSIZE) AS STRING, NUMSTRS AS INTEGER
STACKP = -1
LOOPP = -1
NUMVARS = 0
NUMSTRS = 0
DIM SHARED VARNAMES(VARSSIZE) AS STRING
DIM SHARED VARS(VARSSIZE) AS DOUBLE, CURLINE AS INTEGER, NUM AS DOUBLE
DIM SHARED TEXTP AS INTEGER, ERRORS AS INTEGER
WIDTH 80, 25
DO
ERRORS = 0
1 LINE INPUT "> ", PGM$(0)
IF PGM$(0) <> "" THEN
CALL INITGETSYM(0)
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
CALL VALIDLINENUM
PGM$(NUM) = MID$(PGM$(0), TEXTP, LEN(PGM$(0)) - TEXTP + 1)
ELSE
CALL DOCMD
END IF
END IF
LOOP
2
SELECT CASE ERR
CASE 5
PRINT "ILLEGAL FUNCTION CALL"
CASE 6
PRINT "OVERFLOW"
CASE 11
PRINT "DIVISION BY ZERO"
CASE 14
PRINT "OUT OF STRING SPACE"
CASE 25
PRINT "DEVICE FAULT"
CASE 27
PRINT "OUT OF PAPER"
END SELECT
RESUME 1
REM $STATIC
FUNCTION ACCEPT% (S AS STRING)
ACCEPT = 0
IF TOK$ = S THEN ACCEPT = 1: CALL GETSYM
END FUNCTION
FUNCTION ACOSH# (Z AS DOUBLE)
ACOSH = LOG(Z + SQR(Z + 1) * SQR(Z - 1))
END FUNCTION
FUNCTION ACOTH# (Z AS DOUBLE)
Z = .5 * (LOG(1 + 1 / Z) - LOG(1 - 1 / Z))
END FUNCTION
FUNCTION ACSCH# (Z AS DOUBLE)
ACSCH = LOG(SQR(1 + Z ^ (-2)) + Z ^ (-1))
END FUNCTION
FUNCTION ADDEXPR#
DIM N AS DOUBLE
N = TERM
ADDEL:
IF TOK$ = "MOD" THEN CALL GETSYM: N = N MOD TERM: GOTO ADDEL
IF TOK$ = "+" THEN CALL GETSYM: N = N + TERM: GOTO ADDEL
IF TOK$ = "-" THEN CALL GETSYM: N = N - TERM: GOTO ADDEL
ADDEXPR = N
END FUNCTION
FUNCTION ASECH# (Z AS DOUBLE)
ASECH = LOG(SQR(Z ^ (-1) - 1) * SQR(Z ^ (-1) + 1) + Z ^ (-1))
END FUNCTION
FUNCTION ASIN# (I AS DOUBLE)
IF I = -1 THEN
ASIN = -HALFPI
ELSEIF I = 1 THEN
ASIN = HALFPI
ELSE
ASIN = ATN(I / SQR(1 - I * I))
END IF
END FUNCTION
FUNCTION ASINH# (Z AS DOUBLE)
ASINH = LOG(Z + SQR(1 + Z ^ 2))
END FUNCTION
FUNCTION ATANH# (Z AS DOUBLE)
ATANH = .5 * (LOG(1 + Z) - LOG(1 - Z))
END FUNCTION
SUB CLEARVARS
DIM I AS INTEGER
FOR I = 1 TO VARSSIZE
VARS(I) = 0
STRS(I) = ""
STRNAMES(I) = ""
VARNAMES(I) = ""
NEXT
NUMVARS = 0
NUMSTRS = 0
END SUB
SUB COLORSTMT
DIM BACK AS INTEGER, FORE AS INTEGER, NOBACK AS INTEGER
IF ACCEPT(",") THEN
BACK = EXPRESSION
COLOR , BACK
END IF
FORE = EXPRESSION
IF ACCEPT(",") THEN BACK = EXPRESSION ELSE NOBACK = -1
IF NOBACK = 0 THEN COLOR FORE, BACK ELSE COLOR FORE
END SUB
FUNCTION COSH# (Z AS DOUBLE)
COSH = (E ^ Z + E ^ (-Z)) / 2
END FUNCTION
SUB DOCMD
DIM I AS INTEGER
AGAIN:
IF ERRORS <> 0 THEN EXIT SUB
WHILE TOK$ = ""
IF CURLINE = 0 OR CURLINE >= PGMSIZE THEN EXIT SUB
CALL INITGETSYM(CURLINE + 1)
WEND
IF ACCEPT("STOP") OR ACCEPT("END") THEN EXIT SUB
IF ACCEPT("NEW") THEN
CALL CLEARVARS
FOR I = 1 TO PGMSIZE
PGM$(I) = ""
NEXT
EXIT SUB
END IF
IF ACCEPT("BYE") THEN END
IF ACCEPT("QUIT") THEN END
IF ACCEPT("LIST") THEN CALL LISTSTMT: GOTO AGAIN
IF ACCEPT("LLIST") THEN CALL LLISTSTMT: GOTO AGAIN
IF ACCEPT("RUN") THEN
CALL CLEARVARS
CALL INITGETSYM(1)
GOTO AGAIN
END IF
IF ACCEPT("SCREEN") THEN CALL SCREENSTMT: GOTO AGAIN
IF ACCEPT("PSET") THEN CALL PSETSTMT: GOTO AGAIN
IF ACCEPT("PRESET") THEN CALL PRESETSTMT: GOTO AGAIN
IF ACCEPT("LINE") THEN
IF ACCEPT("INPUT") THEN
CALL LINEINPUTSTMT: GOTO AGAIN
ELSE
CALL LINESTMT: GOTO AGAIN
END IF
END IF
IF ACCEPT("RANDOMIZE") THEN CALL RANDOMIZER: GOTO AGAIN
IF ACCEPT("GOSUB") THEN CALL GOSUBSTMT: GOTO AGAIN
IF ACCEPT("RETURN") THEN CALL RETURNSTMT: GOTO AGAIN
IF ACCEPT("GOTO") THEN CALL GOTOSTMT: GOTO AGAIN
IF ACCEPT("GO") THEN
IF ACCEPT("TO") THEN CALL GOTOSTMT: GOTO AGAIN
IF ACCEPT("SUB") THEN CALL GOSUBSTMT: GOTO AGAIN
PRINT "EXPECTED 'GO TO' OR 'GO SUB'"
ERRORS = 1
EXIT SUB
END IF
IF ACCEPT("IF") THEN CALL IFSTMT: GOTO AGAIN
IF ACCEPT("INPUT") THEN CALL INPUTSTMT: GOTO AGAIN
IF ACCEPT("PRINT") THEN CALL PRINTSTMT: GOTO AGAIN
IF ACCEPT("LPRINT") THEN CALL LPRINTSTMT: GOTO AGAIN
IF ACCEPT("REM") THEN CALL SKIPTOEOL: GOTO AGAIN
IF ACCEPT("CLS") THEN CLS : GOTO AGAIN
IF ACCEPT("COLOR") THEN CALL COLORSTMT: GOTO AGAIN
IF ACCEPT("LOCATE") THEN CALL LOCATESTMT: GOTO AGAIN
IF ACCEPT("WIDTH") THEN CALL WIDTHSTMT: GOTO AGAIN
IF ACCEPT("FOR") THEN CALL FORSTMT: GOTO AGAIN
IF ACCEPT("NEXT") THEN CALL NEXTSTMT: GOTO AGAIN
IF ACCEPT("MID$") THEN CALL MIDSTMT: GOTO AGAIN
IF LEFT$(TOK$, 1) >= "A" AND LEFT$(TOK$, 1) <= "Z" AND RIGHT$(TOK$, 1) = "$" THEN
CALL STRIDSTMT
GOTO AGAIN
END IF
IF LEFT$(TOK$, 1) >= "A" AND LEFT$(TOK$, 1) <= "Z" THEN
CALL IDSTMT
GOTO AGAIN
END IF
PRINT "UNKNOWN TOKEN "; TOK$; " AT LINE "; CURLINE
END SUB
SUB EXPECT (S AS STRING)
IF ACCEPT(S) <> 0 THEN EXIT SUB
ERRORS = 1
PRINT "EXPECTING "; S; " BUT FOUND "; TOK$
END SUB
FUNCTION EXPRESSION#
DIM N AS DOUBLE
N = ADDEXPR
EXPRL:
IF TOK$ = "=" THEN CALL GETSYM: N = N = ADDEXPR: GOTO EXPRL
IF TOK$ = "<" THEN CALL GETSYM: N = N < ADDEXPR: GOTO EXPRL
IF TOK$ = ">" THEN CALL GETSYM: N = N > ADDEXPR: GOTO EXPRL
IF TOK$ = "<>" THEN CALL GETSYM: N = N <> ADDEXPR: GOTO EXPRL
IF TOK$ = "<=" THEN CALL GETSYM: N = N <= ADDEXPR: GOTO EXPRL
IF TOK$ = ">=" THEN CALL GETSYM: N = N >= ADDEXPR: GOTO EXPRL
IF TOK$ = "AND" THEN CALL GETSYM: N = N AND ADDEXPR: GOTO EXPRL
IF TOK$ = "OR" THEN CALL GETSYM: N = N OR ADDEXPR: GOTO EXPRL
IF TOK$ = "XOR" THEN CALL GETSYM: N = N XOR ADDEXPR: GOTO EXPRL
IF TOK$ = "EQV" THEN CALL GETSYM: N = N EQV ADDEXPR: GOTO EXPRL
IF TOK$ = "IMP" THEN CALL GETSYM: N = N IMP ADDEXPR: GOTO EXPRL
EXPRESSION = N
END FUNCTION
FUNCTION EXPT#
DIM N AS DOUBLE
N = FACTOR
EXPTL:
IF TOK$ = "^" THEN CALL GETSYM: N = N ^ FACTOR: GOTO EXPTL
EXPT = N
END FUNCTION
FUNCTION FACTOR#
DIM I AS DOUBLE
IF ACCEPT("-") THEN
FACTOR = -EXPT
EXIT FUNCTION
END IF
IF ACCEPT("+") THEN
FACTOR = EXPRESSION
EXIT FUNCTION
END IF
IF ACCEPT("NOT") THEN
FACTOR = NOT EXPRESSION
EXIT FUNCTION
END IF
IF ACCEPT("VAL") THEN
CALL EXPECT("(")
FACTOR = VAL(STREXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("LEN") THEN
CALL EXPECT("(")
FACTOR = LEN(STREXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ABS") THEN
CALL EXPECT("(")
FACTOR = ABS(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("SGN") THEN
CALL EXPECT("(")
FACTOR = SGN(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("DEG") THEN
CALL EXPECT("(")
FACTOR = EXPRESSION * 180 / PI
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("RAD") THEN
CALL EXPECT("(")
FACTOR = EXPRESSION * PI / 180
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("SIN") THEN
CALL EXPECT("(")
FACTOR = SIN(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("COS") THEN
CALL EXPECT("(")
FACTOR = COS(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("TAN") THEN
CALL EXPECT("(")
FACTOR = TAN(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ATN") OR ACCEPT("ATAN") THEN
CALL EXPECT("(")
FACTOR = ATN(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ASIN") THEN
CALL EXPECT("(")
FACTOR = ASIN(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ACOS") THEN
CALL EXPECT("(")
FACTOR = HALFPI - ASIN(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ACOT") THEN
CALL EXPECT("(")
FACTOR = HALFPI - ATN(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ASEC") THEN
CALL EXPECT("(")
FACTOR = HALFPI - ASIN(1 / EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ACSC") THEN
CALL EXPECT("(")
FACTOR = ASIN(1 / EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("SEC") THEN
CALL EXPECT("(")
FACTOR = 1 / COS(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("CSC") THEN
CALL EXPECT("(")
FACTOR = 1 / SIN(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("COT") THEN
CALL EXPECT("(")
FACTOR = 1 / TAN(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("SINH") THEN
CALL EXPECT("(")
FACTOR = SINH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("COSH") THEN
CALL EXPECT("(")
FACTOR = COSH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("TANH") THEN
CALL EXPECT("(")
FACTOR = TANH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("SECH") THEN
CALL EXPECT("(")
FACTOR = 1 / COSH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("CSCH") THEN
CALL EXPECT("(")
FACTOR = 1 / SINH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("COTH") THEN
CALL EXPECT("(")
FACTOR = 1 / TANH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ASINH") THEN
CALL EXPECT("(")
FACTOR = ASINH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ACOSH") THEN
CALL EXPECT("(")
FACTOR = ACOSH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ATANH") THEN
CALL EXPECT("(")
FACTOR = ATANH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ACSCH") THEN
CALL EXPECT("(")
FACTOR = ACSCH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ASECH") THEN
CALL EXPECT("(")
FACTOR = ASECH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ACOTH") THEN
CALL EXPECT("(")
FACTOR = ACOTH(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("SQR") OR ACCEPT("SQRT") THEN
CALL EXPECT("(")
FACTOR = SQR(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("LN") THEN
CALL EXPECT("(")
FACTOR = LOG(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("LOG10") THEN
CALL EXPECT("(")
FACTOR = LOG(EXPRESSION) / LOG(10)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("LOG") THEN
CALL EXPECT("(")
I = LOG(EXPRESSION)
IF ACCEPT(",") THEN
FACTOR = I / LOG(EXPRESSION)
ELSE
FACTOR = I
END IF
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("EXP") THEN
CALL EXPECT("(")
FACTOR = EXP(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("INT") THEN
CALL EXPECT("(")
FACTOR = INT(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("CINT") THEN
CALL EXPECT("(")
I = EXPRESSION
FACTOR = SGN(I) * INT(ABS(I) + .5)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("CLNG") THEN
CALL EXPECT("(")
I = EXPRESSION
FACTOR = SGN(I) * INT(ABS(I) + .5)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("FIX") THEN
CALL EXPECT("(")
FACTOR = FIX(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("ASC") THEN
CALL EXPECT("(")
FACTOR = ASC(STREXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("RND") THEN
IF ACCEPT("(") THEN
FACTOR = RND(EXPRESSION)
CALL EXPECT(")")
ELSE
FACTOR = RND
END IF
EXIT FUNCTION
END IF
IF ACCEPT("INSTR") THEN
CALL EXPECT("(")
IF LEFT$(TOK$, 1) <> CHR$(34) THEN
I = EXPRESSION
CALL EXPECT(",")
ELSE
I = 1
END IF
X$ = STREXPRESSION
CALL EXPECT(",")
Y$ = STREXPRESSION
CALL EXPECT(")")
FACTOR = INSTR(I, X$, Y$)
EXIT FUNCTION
END IF
IF ACCEPT("TIMER") THEN
FACTOR = TIMER
EXIT FUNCTION
END IF
IF ACCEPT("(") THEN
FACTOR = EXPRESSION
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF LEFT$(TOK$, 1) = "." OR (LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9") THEN
FACTOR = NUM
CALL GETSYM
EXIT FUNCTION
END IF
IF LEFT$(TOK$, 1) >= "A" AND LEFT$(TOK$, 1) <= "Z" THEN
FACTOR = VARS(GETVARINDEX)
EXIT FUNCTION
END IF
PRINT "UNEXPECTED SYM "; TOK$; " IN FACTOR"
ERRORS = 1
END FUNCTION
SUB FORSTMT
DIM VAR AS INTEGER, I AS INTEGER, NULL AS INTEGER
VAR = GETVARINDEX
IF LOOPP >= 0 THEN
IF CURLINE = LOOPLINES(LOOPP) THEN
CALL EXPECT("=")
NULL = EXPRESSION
CALL EXPECT("TO")
NULL = EXPRESSION
IF ACCEPT("STEP") THEN NULL = EXPRESSION
'CALL SKIPTOEOL
EXIT SUB
END IF
FOR I = 0 TO LOOPP - 1
IF LOOPVARS(I) = VAR THEN PRINT "FOR INDEX VARIABLE ALREADY IN USE": ERRORS = 1: EXIT SUB
NEXT
END IF
CALL EXPECT("=")
VARS(VAR) = EXPRESSION
LOOPP = LOOPP + 1
LOOPVARS(LOOPP) = VAR
LOOPLINES(LOOPP) = CURLINE
CALL EXPECT("TO")
LOOPMAX(LOOPP) = EXPRESSION
IF ACCEPT("STEP") THEN LOOPSTEP(LOOPP) = EXPRESSION ELSE LOOPSTEP(LOOPP) = 1
END SUB
SUB GETCH
IF TEXTP > LEN(THELIN$) THEN CH$ = "": EXIT SUB
CH$ = MID$(THELIN$, TEXTP, 1)
TEXTP = TEXTP + 1
END SUB
FUNCTION GETSTRINDEX%
DIM I AS INTEGER
IF LEFT$(TOK$, 1) < "A" OR LEFT$(TOK$, 1) > "Z" THEN
PRINT "NOT A VARIABLE"
ERRORS = 1
EXIT FUNCTION
END IF
IF RIGHT$(TOK$, 1) <> "$" THEN
PRINT "TYPE MISMATCH"
ERRORS = 1
EXIT FUNCTION
END IF
FOR I = 1 TO VARSSIZE
IF STRNAMES(I) = TOK$ THEN
GETSTRINDEX = I
CALL GETSYM
EXIT FUNCTION
END IF
NEXT
NUMSTRS = NUMSTRS + 1
GETSTRINDEX = NUMVARS
STRNAMES(NUMVARS) = TOK$
CALL GETSYM
END FUNCTION
SUB GETSYM
TOK$ = ""
WHILE CH$ <= " "
IF CH$ = "" THEN EXIT SUB
CALL GETCH
WEND
TOK$ = CH$
IF INSTR(",;=+-*/\^()", CH$) > 0 THEN CALL GETCH: EXIT SUB
IF CH$ = "<" THEN
CALL GETCH
IF CH$ = "=" OR CH$ = ">" THEN
TOK$ = TOK$ + CH$
CALL GETCH
END IF
EXIT SUB
END IF
IF CH$ = ">" THEN
CALL GETCH
IF CH$ = "=" THEN TOK$ = TOK$ + CH$: CALL GETCH
EXIT SUB
END IF
IF CH$ = CHR$(34) THEN CALL READSTR: EXIT SUB
IF CH$ = CHR$(39) THEN CALL SKIPTOEOL: EXIT SUB
IF CH$ = CHR$(63) THEN TOK$ = "PRINT": CALL GETCH: EXIT SUB
CH$ = UCASE$(CH$)
IF CH$ >= "A" AND CH$ <= "Z" OR CH$ = "$" THEN CALL READIDENT: EXIT SUB
IF (CH$ >= "0" AND CH$ <= "9") OR CH$ = "." THEN CALL READINT: EXIT SUB
PRINT "WHAT->"; CH$
ERRORS = 1
END SUB
FUNCTION GETVARINDEX%
DIM I AS INTEGER
IF LEFT$(TOK$, 1) < "A" OR LEFT$(TOK$, 1) > "Z" THEN
PRINT "NOT A VARIABLE"
ERRORS = 1
EXIT FUNCTION
END IF
IF RIGHT$(TOK$, 1) = "$" THEN
PRINT "TYPE MISMATCH"
ERRORS = 1
EXIT FUNCTION
END IF
FOR I = 1 TO VARSSIZE
IF VARNAMES(I) = TOK$ THEN
GETVARINDEX = I
CALL GETSYM
EXIT FUNCTION
END IF
NEXT
NUMVARS = NUMVARS + 1
GETVARINDEX = NUMVARS
VARNAMES(NUMVARS) = TOK$
CALL GETSYM
END FUNCTION
SUB GOSUBLINE
CALL VALIDLINENUM
STACKP = STACKP + 1
IF STACKP > 255 THEN PRINT "OUT OF STACK SPACE": ERRORS = 1
GOSUBSTACK(STACKP) = CURLINE
CALL INITGETSYM(INT(NUM))
END SUB
SUB GOSUBSTMT
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
CALL GOSUBLINE
EXIT SUB
END IF
PRINT "LINE NUMBER MUST FOLLOW GOSUB"
ERRORS = 1
END SUB
SUB GOTOLINE
CALL VALIDLINENUM
CALL INITGETSYM(INT(NUM))
END SUB
SUB GOTOSTMT
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
CALL GOTOLINE
EXIT SUB
END IF
PRINT "LINE NUMBER MUST FOLLOW GOTO"
ERRORS = 1
END SUB
SUB IDSTMT
DIM VAR AS INTEGER
VAR = GETVARINDEX
CALL EXPECT("=")
VARS(VAR) = EXPRESSION
END SUB
SUB IFSTMT
DIM B AS INTEGER
IF EXPRESSION = 0 THEN CALL SKIPTOEOL: EXIT SUB
B = ACCEPT("THEN")
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
CALL GOTOLINE
END IF
END SUB
SUB INITGETSYM (N AS INTEGER)
CURLINE = N
TEXTP = 1
THELIN$ = PGM$(CURLINE)
CH$ = " "
CALL GETSYM
END SUB
SUB INPUTSTMT
DIM VAR AS INTEGER
IF LEFT$(TOK$, 1) = CHR$(34) THEN
PRINT MID$(TOK$, 2, LEN(TOK$) - 1);
CALL GETSYM
IF ACCEPT(";") THEN
PRINT "? ";
ELSE
CALL EXPECT(",")
END IF
END IF
IF INSTR(TOK$, "$") THEN
VAR = GETSTRINDEX
INPUT STRS(VAR)
ELSE
VAR = GETVARINDEX
INPUT VARS(VAR)
END IF
END SUB
SUB LINEINPUTSTMT
DIM VAR AS INTEGER
IF LEFT$(TOK$, 1) = CHR$(34) THEN
PRINT MID$(TOK$, 2, LEN(TOK$) - 1);
CALL GETSYM
IF NOT ACCEPT(";") THEN CALL EXPECT(",")
END IF
VAR = GETSTRINDEX
LINE INPUT STRS(VAR)
END SUB
SUB LINESTMT
DIM STEP1 AS INTEGER, STEP2 AS INTEGER
DIM X1 AS DOUBLE, Y1 AS DOUBLE, X2 AS DOUBLE, Y2 AS DOUBLE
DIM COLOUR AS INTEGER, STYLE AS INTEGER, BLOCK AS INTEGER, FILL AS INTEGER
IF ACCEPT("STEP") THEN STEP1 = -1
CALL EXPECT("(")
X1 = EXPRESSION
CALL EXPECT(",")
Y1 = EXPRESSION
CALL EXPECT(")")
CALL EXPECT("-")
IF ACCEPT("STEP") THEN STEP2 = -1
CALL EXPECT("(")
X2 = EXPRESSION
CALL EXPECT(",")
Y2 = EXPRESSION
CALL EXPECT(")")
IF ACCEPT(",") THEN
IF ACCEPT(",") THEN
IF ACCEPT(",") THEN
STYLE = EXPRESSION
IF STEP1 AND STEP2 THEN
LINE STEP(X1, Y1)-STEP(X2, Y2), , , STYLE
ELSEIF STEP1 THEN
LINE STEP(X1, Y1)-(X2, Y2), , , STYLE
ELSEIF STEP2 THEN
LINE (X1, Y1)-STEP(X2, Y2), , , STYLE
ELSE
LINE (X1, Y1)-(X2, Y2), , , STYLE
END IF
ELSE
IF ACCEPT("B") THEN BLOCK = -1
IF ACCEPT("BF") THEN FILL = -1
IF NOT (BLOCK OR FILL) THEN PRINT "EXPECTED: B OR BF BUT FOUND "; TOK$: ERRORS = 1: EXIT SUB
IF ACCEPT(",") THEN
STYLE = EXPRESSION
IF STEP1 AND STEP2 THEN
IF FILL THEN
LINE STEP(X1, Y1)-STEP(X2, Y2), , BF, STYLE
ELSE
LINE STEP(X1, Y1)-STEP(X2, Y2), , B, STYLE
END IF
ELSEIF STEP1 THEN
IF FILL THEN
LINE STEP(X1, Y1)-(X2, Y2), , BF, STYLE
ELSE
LINE STEP(X1, Y1)-(X2, Y2), , B, STYLE
END IF
ELSEIF STEP2 THEN
IF FILL THEN
LINE (X1, Y1)-STEP(X2, Y2), , BF, STYLE
ELSE
LINE (X1, Y1)-STEP(X2, Y2), , B, STYLE
END IF
ELSE
IF FILL THEN
LINE (X1, Y1)-(X2, Y2), , BF, STYLE
ELSE
LINE (X1, Y1)-(X2, Y2), , B, STYLE
END IF
END IF
ELSE
IF STEP1 AND STEP2 THEN
IF FILL THEN
LINE STEP(X1, Y1)-STEP(X2, Y2), , BF
ELSE
LINE STEP(X1, Y1)-STEP(X2, Y2), , B
END IF
ELSEIF STEP1 THEN
IF FILL THEN
LINE STEP(X1, Y1)-(X2, Y2), , BF
ELSE
LINE STEP(X1, Y1)-(X2, Y2), , B
END IF
ELSEIF STEP2 THEN
IF FILL THEN
LINE (X1, Y1)-STEP(X2, Y2), , BF
ELSE
LINE (X1, Y1)-STEP(X2, Y2), , B
END IF
ELSE
IF FILL THEN
LINE (X1, Y1)-(X2, Y2), , BF
ELSE
LINE (X1, Y1)-(X2, Y2), , B
END IF
END IF
END IF
END IF
ELSE
COLOUR = EXPRESSION
IF ACCEPT(",") THEN
IF ACCEPT(",") THEN
STYLE = EXPRESSION
IF STEP1 AND STEP2 THEN
LINE STEP(X1, Y1)-STEP(X2, Y2), COLOUR, , STYLE
ELSEIF STEP1 THEN
LINE STEP(X1, Y1)-(X2, Y2), COLOUR, , STYLE
ELSEIF STEP2 THEN
LINE (X1, Y1)-STEP(X2, Y2), COLOUR, , STYLE
ELSE
LINE (X1, Y1)-(X2, Y2), COLOUR, , STYLE
END IF
ELSE
IF ACCEPT("B") THEN BLOCK = -1
IF ACCEPT("BF") THEN FILL = -1
IF NOT (BLOCK OR FILL) THEN PRINT "EXPECTED B OR BF BUT FOUND "; TOK$: ERRORS = 1: EXIT SUB
IF ACCEPT(",") THEN
STYLE = EXPRESSION
IF STEP1 AND STEP2 THEN
IF FILL THEN
LINE STEP(X1, Y1)-STEP(X2, Y2), COLOUR, BF, STYLE
ELSE
LINE STEP(X1, Y1)-STEP(X2, Y2), COLOUR, B, STYLE
END IF
ELSEIF STEP1 THEN
IF FILL THEN
LINE STEP(X1, Y1)-(X2, Y2), COLOUR, BF, STYLE
ELSE
LINE STEP(X1, Y1)-(X2, Y2), COLOUR, B, STYLE
END IF
ELSEIF STEP2 THEN
IF FILL THEN
LINE (X1, Y1)-STEP(X2, Y2), COLOUR, BF, STYLE
ELSE
LINE (X1, Y1)-STEP(X2, Y2), COLOUR, B, STYLE
END IF
ELSE
IF FILL THEN
LINE (X1, Y1)-(X2, Y2), COLOUR, BF
ELSE
LINE (X1, Y1)-(X2, Y2), COLOUR, B
END IF
END IF
ELSE
IF STEP1 AND STEP2 THEN
IF FILL THEN
LINE STEP(X1, Y1)-STEP(X2, Y2), COLOUR, BF
ELSE
LINE STEP(X1, Y1)-STEP(X2, Y2), COLOUR, B
END IF
ELSEIF STEP1 THEN
IF FILL THEN
LINE STEP(X1, Y1)-(X2, Y2), COLOUR, BF
ELSE
LINE STEP(X1, Y1)-(X2, Y2), COLOUR, B
END IF
ELSEIF STEP2 THEN
IF FILL THEN
LINE (X1, Y1)-STEP(X2, Y2), COLOUR, BF
ELSE
LINE (X1, Y1)-STEP(X2, Y2), COLOUR, B
END IF
ELSE
IF FILL THEN
LINE (X1, Y1)-(X2, Y2), COLOUR, BF
ELSE
LINE (X1, Y1)-(X2, Y2), COLOUR, B
END IF
END IF
END IF
END IF
ELSE
IF STEP1 AND STEP2 THEN
LINE STEP(X1, Y1)-STEP(X2, Y2), COLOUR
ELSEIF STEP1 THEN
LINE STEP(X1, Y1)-(X2, Y2), COLOUR
ELSEIF STEP2 THEN
LINE (X1, Y1)-STEP(X2, Y2), COLOUR
ELSE
LINE (X1, Y1)-(X2, Y2), COLOUR
END IF
END IF
END IF
ELSE
IF STEP1 AND STEP2 THEN
LINE STEP(X1, Y1)-STEP(X2, Y2)
ELSEIF STEP1 THEN
LINE STEP(X1, Y1)-(X2, Y2)
ELSEIF STEP2 THEN
LINE (X1, Y1)-STEP(X2, Y2)
ELSE
LINE (X1, Y1)-(X2, Y2)
END IF
END IF
END SUB
SUB LISTSTMT
DIM I AS INTEGER
FOR I = 1 TO PGMSIZE
IF PGM$(I) <> "" THEN PRINT I; " "; PGM$(I)
NEXT
PRINT
END SUB
SUB LLISTSTMT
DIM I AS INTEGER
OPEN "LPT1" FOR OUTPUT AS #1
FOR I = 1 TO PGMSIZE
IF PGM$(I) <> "" THEN PRINT #1, I; " "; PGM$(I)
NEXT
PRINT
CLOSE #1
END SUB
SUB LOCATESTMT
DIM ROW AS INTEGER, COL AS INTEGER, NOCOL AS INTEGER
IF ACCEPT(",") THEN
COL = EXPRESSION
LOCATE , COL
EXIT SUB
ELSE
ROW = EXPRESSION
END IF
IF ACCEPT(",") THEN COL = EXPRESSION ELSE NOCOL = -1
IF NOCOL = 0 THEN LOCATE ROW, COL ELSE LOCATE ROW
END SUB
SUB LPRINTSTMT
DIM LPRINTNL AS INTEGER
OPEN "LPT1" FOR OUTPUT AS #1
LPRINTNL = 1
DO WHILE TOK$ <> ""
LPRINTNL = 1
IF LEFT$(TOK$, 1) = CHR$(34) THEN
PRINT #1, MID$(TOK$, 2, LEN(TOK$) - 1);
CALL GETSYM
ELSEIF INSTR(TOK$, "$") THEN
PRINT #1, STREXPRESSION;
ELSE
PRINT #1, EXPRESSION;
END IF
IF ACCEPT(",") = 0 AND ACCEPT(";") = 0 THEN EXIT DO
LPRINTNL = 0
LOOP
IF LPRINTNL <> 0 THEN PRINT #1, ""
CLOSE #1
END SUB
SUB MIDSTMT
DIM VAR AS INTEGER, START AS INTEGER, LENGTH AS INTEGER, NOLENGTH AS INTEGER
CALL EXPECT("(")
VAR = GETSTRINDEX
CALL EXPECT(",")
START = EXPRESSION
IF ACCEPT(",") THEN LENGTH = EXPRESSION ELSE NOLENGTH = -1
CALL EXPECT(")")
CALL EXPECT("=")
IF NOLENGTH THEN
MID$(STRS(VAR), START) = STREXPRESSION
ELSE
MID$(STRS(VAR), START, LENGTH) = STREXPRESSION
END IF
END SUB
SUB NEXTSTMT
IF LOOPP < 0 THEN PRINT "NEXT WITHOUT FOR": EXIT SUB
VARS(LOOPVARS(LOOPP)) = VARS(LOOPVARS(LOOPP)) + LOOPSTEP(LOOPP)
IF VARS(LOOPVARS(LOOPP)) <= LOOPMAX(LOOPP) THEN
CALL INITGETSYM(LOOPLINES(LOOPP))
ELSE
LOOPP = LOOPP - 1
END IF
END SUB
SUB PRESETSTMT
DIM PSETSTEP AS INTEGER, X AS DOUBLE, Y AS DOUBLE, COLOUR AS INTEGER, NOCOLOUR AS INTEGER
IF ACCEPT("STEP") THEN
PSETSTEP = -1
END IF
CALL EXPECT("(")
X = EXPRESSION
CALL EXPECT(",")
Y = EXPRESSION
CALL EXPECT(")")
IF ACCEPT(",") THEN
COLOUR = EXPRESSION
ELSE
NOCOLOUR = -1
END IF
IF PSETSTEP THEN
IF NOCOLOUR THEN
PRESET STEP(X, Y)
ELSE
PRESET STEP(X, Y), COLOUR
END IF
ELSE
IF NOCOLOUR THEN
PRESET (X, Y)
ELSE
PRESET (X, Y), COLOUR
END IF
END IF
END SUB
SUB PRINTSTMT
DIM PRINTNL AS INTEGER
PRINTNL = 1
DO WHILE TOK$ <> ""
PRINTNL = 1
IF LEFT$(TOK$, 1) = CHR$(34) THEN
PRINT MID$(TOK$, 2, LEN(TOK$) - 1);
CALL GETSYM
ELSEIF INSTR(TOK$, "$") THEN
PRINT STREXPRESSION;
ELSE
PRINT EXPRESSION;
END IF
IF ACCEPT(",") THEN
PRINT ,
ELSEIF ACCEPT(";") = 0 THEN
EXIT DO
END IF
PRINTNL = 0
LOOP
IF PRINTNL <> 0 THEN PRINT
END SUB
SUB PSETSTMT
DIM PSETSTEP AS INTEGER, X AS DOUBLE, Y AS DOUBLE, COLOUR AS INTEGER, NOCOLOR AS INTEGER
IF ACCEPT("STEP") THEN
PSETSTEP = -1
END IF
CALL EXPECT("(")
X = EXPRESSION
CALL EXPECT(",")
Y = EXPRESSION
CALL EXPECT(")")
IF ACCEPT(",") THEN
COLOUR = EXPRESSION
ELSE
NOCOLOR = -1
END IF
IF PSETSTEP THEN
IF NOCOLOR THEN
PSET STEP(X, Y)
ELSE
PSET STEP(X, Y), COLOUR
END IF
ELSE
IF NOCOLOR THEN
PSET (X, Y)
ELSE
PSET (X, Y), COLOUR
END IF
END IF
END SUB
SUB RANDOMIZER
RANDOMIZE EXPRESSION
END SUB
SUB READIDENT
TOK$ = ""
WHILE (UCASE$(CH$) >= "A" AND UCASE$(CH$) <= "Z") OR (CH$ >= "0" AND CH$ <= "9") OR (CH$ = "_")
TOK$ = TOK$ + UCASE$(CH$)
CALL GETCH
WEND
IF CH$ = "$" THEN TOK$ = TOK$ + CH$: CALL GETCH
END SUB
SUB READINT
TOK$ = ""
WHILE CH$ >= "0" AND CH$ <= "9"
TOK$ = TOK$ + CH$
CALL GETCH
WEND
IF CH$ = "." THEN
TOK$ = TOK$ + CH$
CALL GETCH
WHILE CH$ >= "0" AND CH$ <= "9"
TOK$ = TOK$ + CH$
CALL GETCH
WEND
END IF
IF CH$ = "E" OR CH$ = "D" THEN
TOK$ = TOK$ + "D"
CALL GETCH
IF CH$ = "+" OR CH$ = "-" THEN TOK$ = TOK$ + CH$: CALL GETCH
WHILE CH$ >= "0" AND CH$ <= "9"
TOK$ = TOK$ + CH$
CALL GETCH
WEND
END IF
NUM = VAL(TOK$)
END SUB
SUB READSTR
TOK$ = CHR$(34)
CALL GETCH
WHILE CH$ <> CHR$(34)
IF CH$ = "" THEN
PRINT "STRING NOT TERMINATED"
ERRORS = 1
EXIT SUB
END IF
TOK$ = TOK$ + CH$
CALL GETCH
WEND
CALL GETCH
END SUB
SUB RETURNSTMT
DIM LIN AS INTEGER
IF STACKP < 0 THEN PRINT "RETURN WITHOUT GOSUB": EXIT SUB
LIN = GOSUBSTACK(STACKP)
STACKP = STACKP - 1
CALL INITGETSYM(LIN + 1)
END SUB
SUB SCREENSTMT
DIM MODE AS INTEGER, USECOLOR AS INTEGER, APAGE AS INTEGER, VPAGE AS INTEGER
MODE = EXPRESSION
IF ACCEPT(",") THEN
IF ACCEPT(",") THEN
IF ACCEPT(",") THEN
VPAGE = EXPRESSION
SCREEN MODE, , , VPAGE
ELSE
APAGE = EXPRESSION
IF ACCEPT(",") THEN
VPAGE = EXPRESSION
SCREEN MODE, , APAGE, VPAGE
ELSE
SCREEN MODE, , APAGE
END IF
END IF
ELSE
USECOLOR = EXPRESSION
IF ACCEPT(",") THEN
IF ACCEPT(",") THEN
VPAGE = EXPRESSION
SCREEN MODE, USECOLOR, , VPAGE
ELSE
APAGE = EXPRESSION
IF ACCEPT(",") THEN
VPAGE = EXPRESSION
SCREEN MODE, USECOLOR, APAGE, VPAGE
ELSE
SCREEN MODE, USECOLOR, APAGE
END IF
END IF
ELSE
SCREEN MODE, USECOLOR
END IF
END IF
ELSE
SCREEN MODE
END IF
END SUB
FUNCTION SINH# (Z AS DOUBLE)
SINH = (E ^ Z - E ^ (-Z)) / 2
END FUNCTION
SUB SKIPTOEOL
WHILE CH$ <> ""
CALL GETCH
WEND
CALL GETSYM
END SUB
FUNCTION STREXPRESSION$
DIM X AS INTEGER, Y AS INTEGER
IF LEFT$(TOK$, 1) = CHR$(34) THEN STREXPRESSION = MID$(TOK$, 2, LEN(TOK$) - 1): CALL GETSYM: EXIT FUNCTION
IF ACCEPT("HEX$") THEN
CALL EXPECT("(")
STREXPRESSION = HEX$(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("OCT$") THEN
CALL EXPECT("(")
STREXPRESSION = OCT$(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("STR$") THEN
CALL EXPECT("(")
STREXPRESSION = STR$(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("MID$") THEN
CALL EXPECT("(")
I$ = STREXPRESSION
CALL EXPECT(",")
X = EXPRESSION
IF ACCEPT(",") THEN
Y = EXPRESSION
STREXPRESSION = MID$(I$, X, Y)
ELSE
STREXPRESSION = MID$(I$, X)
END IF
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("LEFT$") THEN
CALL EXPECT("(")
I$ = STREXPRESSION
CALL EXPECT(",")
X = EXPRESSION
STREXPRESSION = LEFT$(I$, X)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("RIGHT$") THEN
CALL EXPECT("(")
I$ = STREXPRESSION
CALL EXPECT(",")
X = EXPRESSION
STREXPRESSION = RIGHT$(I$, X)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("UCASE$") THEN
CALL EXPECT("(")
STREXPRESSION = UCASE$(STREXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("LCASE$") THEN
CALL EXPECT("(")
STREXPRESSION = LCASE$(STREXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("LTRIM$") THEN
CALL EXPECT("(")
STREXPRESSION = LTRIM$(STREXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("RTRIM$") THEN
CALL EXPECT("(")
STREXPRESSION = RTRIM$(STREXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("CHR$") THEN
CALL EXPECT("(")
STREXPRESSION = CHR$(EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF ACCEPT("STRING$") THEN
CALL EXPECT("(")
X = EXPRESSION
IF LEFT$(TOK$, 1) = CHR$(34) THEN STREXPRESSION = STRING$(X, STREXPRESSION) ELSE STREXPRESSION = STRING$(X, EXPRESSION)
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF LEFT$(TOK$, 1) >= "A" AND LEFT$(TOK$, 1) <= "Z" AND RIGHT$(TOK$, 1) = "$" THEN
X = GETSTRINDEX
STREXPRESSION = STRS(X)
EXIT FUNCTION
END IF
END FUNCTION
SUB STRIDSTMT
DIM VAR AS INTEGER
VAR = GETSTRINDEX
CALL EXPECT("=")
STRS(VAR) = STREXPRESSION
END SUB
FUNCTION TANH# (Z AS DOUBLE)
TANH = (E ^ (2 * Z) - 1) / (E ^ (2 * Z) + 1)
END FUNCTION
FUNCTION TERM#
DIM N AS DOUBLE, I AS DOUBLE
N = EXPT
TERML:
IF TOK$ = "*" THEN CALL GETSYM: N = N * EXPT: GOTO TERML
IF TOK$ = "/" THEN
CALL GETSYM
I = EXPT
IF I = 0 THEN PRINT "DIVISION BY ZERO": ERRORS = 1: EXIT FUNCTION
N = N / I
GOTO TERML
END IF
IF TOK$ = "\" THEN
CALL GETSYM
I = EXPT
IF I = 0 THEN PRINT "DIVISION BY ZERO": ERRORS = 1: EXIT FUNCTION
N = N \ I
GOTO TERML
END IF
TERM = N
END FUNCTION
SUB VALIDLINENUM
IF NUM > 0 AND NUM <= PGMSIZE THEN EXIT SUB
PRINT "LINE NUMBER OUT OF RANGE"
ERRORS = 1
END SUB
SUB WIDTHSTMT
DIM CHEIGHT AS INTEGER, CWIDTH AS INTEGER, NOCHEIGHT AS INTEGER
IF ACCEPT(",") THEN
CHEIGHT = EXPRESSION
WIDTH , CHEIGHT
EXIT SUB
ELSE
CWIDTH = EXPRESSION
IF ACCEPT(",") THEN CHEIGHT = EXPRESSION ELSE NOCHEIGHT = -1
END IF
IF NOCHEIGHT THEN
WIDTH CWIDTH
ELSE
WIDTH CWIDTH, CHEIGHT
END IF
END SUB
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
DIM fingers(0 TO 9) AS STRING * 1
FOR I = 0 TO 9
fingers(I) = "-"
NEXT
PRINT "COUNTING ON FINGERS PROGRAM IN QBASIC"
DO
CLS
FOR I = 0 TO 4
PRINT fingers(I);
NEXT
PRINT " ";
FOR I = 5 TO 9
PRINT fingers(I);
NEXT
PRINT
X$ = UCASE$(INPUT$(1))
SELECT CASE X$
CASE "A"
IF fingers(0) = "-" THEN fingers(0) = "o" ELSE fingers(0) = "-"
CASE "S"
IF fingers(1) = "-" THEN fingers(1) = "o" ELSE fingers(1) = "-"
CASE "D"
IF fingers(2) = "-" THEN fingers(2) = "o" ELSE fingers(2) = "-"
CASE "F"
IF fingers(3) = "-" THEN fingers(3) = "o" ELSE fingers(3) = "-"
CASE "G"
IF fingers(4) = "-" THEN fingers(4) = "o" ELSE fingers(4) = "-"
CASE "H"
IF fingers(5) = "-" THEN fingers(5) = "o" ELSE fingers(5) = "-"
CASE "J"
IF fingers(6) = "-" THEN fingers(6) = "o" ELSE fingers(6) = "-"
CASE "K"
IF fingers(7) = "-" THEN fingers(7) = "o" ELSE fingers(7) = "-"
CASE "L"
IF fingers(8) = "-" THEN fingers(8) = "o" ELSE fingers(8) = "-"
CASE ";"
IF fingers(9) = "-" THEN fingers(9) = "o" ELSE fingers(9) = "-"
END SELECT
'uncomment for Dvorak
'SELECT CASE X$
' CASE "A"
' IF fingers(0) = "-" THEN fingers(0) = "o" ELSE fingers(0) = "-"
' CASE "O"
' IF fingers(1) = "-" THEN fingers(1) = "o" ELSE fingers(1) = "-"
' CASE "E"
' IF fingers(2) = "-" THEN fingers(2) = "o" ELSE fingers(2) = "-"
' CASE "U"
' IF fingers(3) = "-" THEN fingers(3) = "o" ELSE fingers(3) = "-"
' CASE "I"
' IF fingers(4) = "-" THEN fingers(4) = "o" ELSE fingers(4) = "-"
' CASE "D"
' IF fingers(5) = "-" THEN fingers(5) = "o" ELSE fingers(5) = "-"
' CASE "H"
' IF fingers(6) = "-" THEN fingers(6) = "o" ELSE fingers(6) = "-"
' CASE "T"
' IF fingers(7) = "-" THEN fingers(7) = "o" ELSE fingers(7) = "-"
' CASE "N"
' IF fingers(8) = "-" THEN fingers(8) = "o" ELSE fingers(8) = "-"
' CASE "S"
' IF fingers(9) = "-" THEN fingers(9) = "o" ELSE fingers(9) = "-"
'END SELECT
DECLARE SUB OBFUSCATESUB ()
DECLARE FUNCTION ROT13$ (X$)
DECLARE SUB HELPSUB ()
DECLARE SUB WRITESUB ()
DECLARE SUB LISTSUB ()
DECLARE SUB PRINTSUB ()
DECLARE SUB DELETESUB ()
DECLARE SUB INSERTSUB ()
DECLARE SUB EDITSUB ()
DECLARE SUB SEARCHSUB ()
DECLARE SUB REPLACESUB ()
DECLARE SUB QUITSUB ()
DEFINT A-Z
DIM SHARED FILE$, TEMP1$, TEMP2$
IF COMAND$ = "" THEN
INPUT "FILE? ", FILE$
ELSE
FILE$ = COMMAND$
END IF
SHELL "if not exist " + FILE$ + " echo Reading input from CON into new file. ^Z to end"
' Uncomment for Win98
' SHELL "cmd /c if not exist " + FILE$ + " copy con " + FILE$
SHELL "cmd /c if not exist " + FILE$ + " copy con " + FILE$
I = LEN(FILE$) - 1
TEMP1$ = LEFT$(FILE$, I) + "~"
TEMP2$ = LEFT$(FILE$, I) + "!"
SHELL "COPY " + FILE$ + CHR$(32) + TEMP1$
DO
INPUT "*", CMD$
CMD$ = LEFT$(UCASE$(LTRIM$(RTRIM$(CMD$))), 1)
SELECT CASE CMD$
CASE "L"
CALL LISTSUB
CASE "P"
CALL PRINTSUB
CASE "D"
CALL DELETESUB
CASE "I"
CALL INSERTSUB
CASE "E"
CALL EDITSUB
CASE "S"
CALL SEARCHSUB
CASE "R"
CALL REPLACESUB
CASE "W"
CALL WRITESUB
CASE "Q"
CALL QUITSUB
CASE "?", "H"
CALL HELPSUB
CASE "O"
CALL OBFUSCATESUB
END SELECT
LOOP
SUB DELETESUB
INPUT "ENTER RANGE OR ENTER TO CANCE;", RANGE$
IF LTRIM$(RANGE$) = "" THEN
EXIT SUB
ELSE
STARTLINE = VAL(RANGE$)
ENDLINE = VAL(MID$(RANGE$, INSTR(RANGE$, "-") + 1))
END IF
OPEN TEMP1$ FOR INPUT AS #1
OPEN TEMP2$ FOR OUTPUT AS #2
FOR I = 1 TO STARTLINE - 1
IF EOF(1) THEN EXIT FOR
LINE INPUT #1, LINE$
PRINT #2, LINE$
NEXT
FOR I = STARTLINE TO ENDLINE
IF EOF(1) THEN EXIT FOR
LINE INPUT #1, LINE$
NEXT
WHILE NOT EOF(1)
LINE INPUT #1, LINE$
PRINT #2, LINE$
WEND
CLOSE #1
CLOSE #2
SHELL "COPY " + TEMP2$ + CHR$(32) + TEMP1$
KILL TEMP2$
END SUB
SUB EDITSUB
INPUT "ENTER RANGE OR ENTER TO CANCEL", RANGE$
IF LTRIM$(RANGE$) = "" THEN
EXIT SUB
ELSE
STARTLINE = VAL(RANGE$)
ENDLINE = VAL(MID$(RANGE$, INSTR(RANGE$, "-") + 1))
END IF
OPEN TEMP1$ FOR INPUT AS #1
OPEN TEMP2$ FOR OUTPUT AS #2
FOR I = 1 TO STARTLINE - 1
IF EOF(1) THEN EXIT FOR
LINE INPUT #1, LINE$
PRINT #2, LINE$
NEXT
FOR I = STARTLINE TO ENDLINE
LINE INPUT LINE$
PRINT #2, LINE$
NEXT
WHILE NOT EOF(1)
LINE INPUT #1, LINE$
PRINT #2, LINE$
WEND
CLOSE #1
CLOSE #2
SHELL "COPY " + TEMP2$ + CHR$(32) + TEMP1$
KILL TEMP2$
END SUB
SUB HELPSUB
PRINT "List -- Display lines from file"
PRINT "Print -- Print file"
PRINT "Write -- Save changes"
PRINT "Quit -- Exit"
PRINT "Help -- Display this message"
PRINT "Insert -- Insert lines"
PRINT "Delete -- Delete lines"
PRINT "Search -- Search for text"
PRINT "Replace -- Search for text and replace"
PRINT "Edit -- Replace lines"
PRINT "Obfuscate -- ROT13 text"
END SUB
SUB INSERTSUB
INPUT "INSERT AFTER WHICH LINE? ", RANGE$
PRINT "CTRL-Z ON ITS OWN LINE TO STOP INSERTING"
IF LTRIM$(RANGE$) = "" THEN
EXIT SUB
ELSE
STARTLINE = VAL(RANGE$)
END IF
OPEN TEMP1$ FOR INPUT AS #1
OPEN TEMP2$ FOR OUTPUT AS #2
FOR I = 1 TO STARTLINE
IF EOF(1) THEN EXIT FOR
LINE INPUT #1, LINE$
PRINT #2, LINE$
NEXT
DO
LINE INPUT LINE$
IF LTRIM$(RTRIM$(LINE$)) = CHR$(26) THEN EXIT DO
PRINT #2, LINE$
LOOP
WHILE NOT EOF(1)
LINE INPUT #1, LINE$
PRINT #2, LINE$
WEND
CLOSE #1
CLOSE #2
SHELL "COPY " + TEMP2$ + CHR$(32) + TEMP1$
KILL TEMP2$
END SUB
SUB LISTSUB
INPUT "ENTER RANGE OR ENTER TO LIST ALL", RANGE$
IF LTRIM$(RANGE$) = "" THEN
STARTLINE = 1
ENDLINE = 32767
ELSE
STARTLINE = VAL(RANGE$)
ENDLINE = VAL(MID$(RANGE$, INSTR(RANGE$, "-") + 1))
END IF
OPEN TEMP1$ FOR INPUT AS #1
FOR I = STARTLINE TO ENDLINE
IF EOF(1) THEN EXIT FOR
LINE INPUT #1, LINE$
I$ = RIGHT$(SPACE$(8) + LTRIM$(STR$(I)), 8)
PRINT I$; ":"; LINE$
NEXT
CLOSE #1
END SUB
SUB OBFUSCATESUB
INPUT "INPUT RANGE OR ENTER TO ROT13 WHOLE FILE: ", RANGE$
IF LTRIM$(RANGE$) = "" THEN
STARTLINE = 1
ENDLINE = 32767
ELSE
STARTLINE = VAL(RANGE$)
ENDLINE = VAL(MID$(RANGE$, INSTR(RANGE$, "-") + 1))
END IF
OPEN TEMP1$ FOR INPUT AS #1
OPEN TEMP2$ FOR OUTPUT AS #2
FOR I = 1 TO STARTLINE - 1
IF EOF(1) THEN EXIT FOR
LINE INPUT #1, LINE$
PRINT #2, LINE$
NEXT
FOR I = STARTLINE TO ENDLINE
IF EOF(1) THEN EXIT FOR
LINE INPUT #1, LINE$
LINE$ = ROT13$(LINE$)
PRINT #2, LINE$
NEXT
WHILE NOT EOF(1)
LINE INPUT #1, LINE$
PRINT #2, LINE$
WEND
CLOSE #1
CLOSE #2
SHELL "COPY " + TEMP2$ + CHR$(32) + TEMP1$
KILL TEMP2$
END SUB
SUB PRINTSUB
OPEN TEMP1$ FOR INPUT AS #1
WIDTH LPRINT 255
WHILE NOT EOF(1)
INPUT #1, n$
LPRINT n$
WEND
CLOSE
END SUB
SUB QUITSUB
INPUT "REALLY QUIT? ", n$
n$ = UCASE$(LTRIM$(RTRIM$(n$)))
IF n$ = "YES" OR n$ = "Y" THEN END
KILL TEMP1$
KILL TEMP2$
END SUB
SUB REPLACESUB
LINE INPUT "SEARCH FOR? ", X$
LINE INPUT "REPLACE WITH? ", Y$
OPEN TEMP1$ FOR INPUT AS #1
OPEN TEMP2$ FOR OUTPUT AS #2
WHILE NOT EOF(1)
LINE INPUT #1, J$
I = INSTR(J$, X$)
IF I = 0 THEN
PRINT #2, J$
ELSE
PRINT #2, LEFT$(J$, I - 1) + Y$ + MID$(J$, I + LEN(X$))
END IF
WEND
CLOSE #1
CLOSE #2
SHELL "COPY " + TEMP2$ + CHR$(32) + TEMP1$
KILL TEMP2$
END SUB
FUNCTION ROT13$ (X$)
FOR I = 1 TO LEN(X$)
A = ASC(MID$(X$, I))
B = 64 XOR A AND 223
IF B AND B < 27 THEN
Z$ = Z$ + CHR$((A AND 96) OR (B + 12) MOD 26 + 1)
ELSE
Z$ = Z$ + CHR$(A)
END IF
NEXT
ROT13$ = Z$
END FUNCTION
SUB SEARCHSUB
LINE INPUT "STRING TO SEARCH? ", n$
I = 1
OPEN TEMP1$ FOR INPUT AS #1
WHILE NOT EOF(1)
I$ = RIGHT$(SPACE$(8) + LTRIM$(STR$(I)), 8)
LINE INPUT #1, J$
IF INSTR(J$, n$) THEN PRINT I$; ":"; J$
I = I + 1
WEND
CLOSE #1
END SUB
SUB WRITESUB
SHELL "COPY " + TEMP1$ + CHR$(32) + FILE$
END SUB
Fixed REPLACESUB bug where did not replace if more than one instance on a line
January 2 2008, 9:31 AM
DECLARE SUB OBFUSCATESUB ()
DECLARE FUNCTION ROT13$ (X$)
DECLARE SUB HELPSUB ()
DECLARE SUB WRITESUB ()
DECLARE SUB LISTSUB ()
DECLARE SUB PRINTSUB ()
DECLARE SUB DELETESUB ()
DECLARE SUB INSERTSUB ()
DECLARE SUB EDITSUB ()
DECLARE SUB SEARCHSUB ()
DECLARE SUB REPLACESUB ()
DECLARE SUB QUITSUB ()
DEFINT A-Z
DIM SHARED FILE$, TEMP1$, TEMP2$
IF COMAND$ = "" THEN
INPUT "FILE? ", FILE$
ELSE
FILE$ = COMMAND$
END IF
SHELL "if not exist " + FILE$ + " echo Reading input from CON into new file. ^Z to end"
' Uncomment for Win98
' SHELL "cmd /c if not exist " + FILE$ + " copy con " + FILE$
SHELL "cmd /c if not exist " + FILE$ + " copy con " + FILE$
I = LEN(FILE$) - 1
TEMP1$ = LEFT$(FILE$, I) + "~"
TEMP2$ = LEFT$(FILE$, I) + "!"
SHELL "COPY " + FILE$ + CHR$(32) + TEMP1$
DO
INPUT "*", CMD$
CMD$ = LEFT$(UCASE$(LTRIM$(RTRIM$(CMD$))), 1)
SELECT CASE CMD$
CASE "L"
CALL LISTSUB
CASE "P"
CALL PRINTSUB
CASE "D"
CALL DELETESUB
CASE "I"
CALL INSERTSUB
CASE "E"
CALL EDITSUB
CASE "S"
CALL SEARCHSUB
CASE "R"
CALL REPLACESUB
CASE "W"
CALL WRITESUB
CASE "Q"
CALL QUITSUB
CASE "?", "H"
CALL HELPSUB
CASE "O"
CALL OBFUSCATESUB
END SELECT
LOOP
SUB DELETESUB
INPUT "ENTER RANGE OR ENTER TO CANCE;", RANGE$
IF LTRIM$(RANGE$) = "" THEN
EXIT SUB
ELSE
STARTLINE = VAL(RANGE$)
ENDLINE = VAL(MID$(RANGE$, INSTR(RANGE$, "-") + 1))
END IF
OPEN TEMP1$ FOR INPUT AS #1
OPEN TEMP2$ FOR OUTPUT AS #2
FOR I = 1 TO STARTLINE - 1
IF EOF(1) THEN EXIT FOR
LINE INPUT #1, LINE$
PRINT #2, LINE$
NEXT
FOR I = STARTLINE TO ENDLINE
IF EOF(1) THEN EXIT FOR
LINE INPUT #1, LINE$
NEXT
WHILE NOT EOF(1)
LINE INPUT #1, LINE$
PRINT #2, LINE$
WEND
CLOSE #1
CLOSE #2
SHELL "COPY " + TEMP2$ + CHR$(32) + TEMP1$
KILL TEMP2$
END SUB
SUB EDITSUB
INPUT "ENTER RANGE OR ENTER TO CANCEL", RANGE$
IF LTRIM$(RANGE$) = "" THEN
EXIT SUB
ELSE
STARTLINE = VAL(RANGE$)
ENDLINE = VAL(MID$(RANGE$, INSTR(RANGE$, "-") + 1))
END IF
OPEN TEMP1$ FOR INPUT AS #1
OPEN TEMP2$ FOR OUTPUT AS #2
FOR I = 1 TO STARTLINE - 1
IF EOF(1) THEN EXIT FOR
LINE INPUT #1, LINE$
PRINT #2, LINE$
NEXT
FOR I = STARTLINE TO ENDLINE
LINE INPUT LINE$
PRINT #2, LINE$
NEXT
WHILE NOT EOF(1)
LINE INPUT #1, LINE$
PRINT #2, LINE$
WEND
CLOSE #1
CLOSE #2
SHELL "COPY " + TEMP2$ + CHR$(32) + TEMP1$
KILL TEMP2$
END SUB
SUB HELPSUB
PRINT "List -- Display lines from file"
PRINT "Print -- Print file"
PRINT "Write -- Save changes"
PRINT "Quit -- Exit"
PRINT "Help -- Display this message"
PRINT "Insert -- Insert lines"
PRINT "Delete -- Delete lines"
PRINT "Search -- Search for text"
PRINT "Replace -- Search for text and replace"
PRINT "Edit -- Replace lines"
PRINT "Obfuscate -- ROT13 text"
END SUB
SUB INSERTSUB
INPUT "INSERT AFTER WHICH LINE? ", RANGE$
PRINT "CTRL-Z ON ITS OWN LINE TO STOP INSERTING"
IF LTRIM$(RANGE$) = "" THEN
EXIT SUB
ELSE
STARTLINE = VAL(RANGE$)
END IF
OPEN TEMP1$ FOR INPUT AS #1
OPEN TEMP2$ FOR OUTPUT AS #2
FOR I = 1 TO STARTLINE
IF EOF(1) THEN EXIT FOR
LINE INPUT #1, LINE$
PRINT #2, LINE$
NEXT
DO
LINE INPUT LINE$
IF LTRIM$(RTRIM$(LINE$)) = CHR$(26) THEN EXIT DO
PRINT #2, LINE$
LOOP
WHILE NOT EOF(1)
LINE INPUT #1, LINE$
PRINT #2, LINE$
WEND
CLOSE #1
CLOSE #2
SHELL "COPY " + TEMP2$ + CHR$(32) + TEMP1$
KILL TEMP2$
END SUB
SUB LISTSUB
INPUT "ENTER RANGE OR ENTER TO LIST ALL", RANGE$
IF LTRIM$(RANGE$) = "" THEN
STARTLINE = 1
ENDLINE = 32767
ELSE
STARTLINE = VAL(RANGE$)
ENDLINE = VAL(MID$(RANGE$, INSTR(RANGE$, "-") + 1))
END IF
OPEN TEMP1$ FOR INPUT AS #1
FOR I = STARTLINE TO ENDLINE
IF EOF(1) THEN EXIT FOR
LINE INPUT #1, LINE$
I$ = RIGHT$(SPACE$(8) + LTRIM$(STR$(I)), 8)
PRINT I$; ":"; LINE$
NEXT
CLOSE #1
END SUB
SUB OBFUSCATESUB
INPUT "INPUT RANGE OR ENTER TO ROT13 WHOLE FILE: ", RANGE$
IF LTRIM$(RANGE$) = "" THEN
STARTLINE = 1
ENDLINE = 32767
ELSE
STARTLINE = VAL(RANGE$)
ENDLINE = VAL(MID$(RANGE$, INSTR(RANGE$, "-") + 1))
END IF
OPEN TEMP1$ FOR INPUT AS #1
OPEN TEMP2$ FOR OUTPUT AS #2
FOR I = 1 TO STARTLINE - 1
IF EOF(1) THEN EXIT FOR
LINE INPUT #1, LINE$
PRINT #2, LINE$
NEXT
FOR I = STARTLINE TO ENDLINE
IF EOF(1) THEN EXIT FOR
LINE INPUT #1, LINE$
LINE$ = ROT13$(LINE$)
PRINT #2, LINE$
NEXT
WHILE NOT EOF(1)
LINE INPUT #1, LINE$
PRINT #2, LINE$
WEND
CLOSE #1
CLOSE #2
SHELL "COPY " + TEMP2$ + CHR$(32) + TEMP1$
KILL TEMP2$
END SUB
SUB PRINTSUB
OPEN TEMP1$ FOR INPUT AS #1
WIDTH LPRINT 255
WHILE NOT EOF(1)
INPUT #1, n$
LPRINT n$
WEND
CLOSE
END SUB
SUB QUITSUB
INPUT "REALLY QUIT? ", n$
n$ = UCASE$(LTRIM$(RTRIM$(n$)))
IF n$ = "YES" OR n$ = "Y" THEN END
KILL TEMP1$
KILL TEMP2$
END SUB
SUB REPLACESUB
LINE INPUT "SEARCH FOR? ", X$
LINE INPUT "REPLACE WITH? ", Y$
OPEN TEMP1$ FOR INPUT AS #1
OPEN TEMP2$ FOR OUTPUT AS #2
WHILE NOT EOF(1)
LINE INPUT #1, J$
DO
I = INSTR(J$, X$)
IF I THEN J$ = LEFT$(J$, I - 1) + Y$ + MID$(J$, I + LEN(X$)) ELSE EXIT DO
LOOP
PRINT #2, J$
WEND
CLOSE #1
CLOSE #2
SHELL "COPY " + TEMP2$ + CHR$(32) + TEMP1$
KILL TEMP2$
END SUB
FUNCTION ROT13$ (X$)
FOR I = 1 TO LEN(X$)
A = ASC(MID$(X$, I))
B = 64 XOR A AND 223
IF B AND B < 27 THEN
Z$ = Z$ + CHR$((A AND 96) OR (B + 12) MOD 26 + 1)
ELSE
Z$ = Z$ + CHR$(A)
END IF
NEXT
ROT13$ = Z$
END FUNCTION
SUB SEARCHSUB
LINE INPUT "STRING TO SEARCH? ", n$
I = 1
OPEN TEMP1$ FOR INPUT AS #1
WHILE NOT EOF(1)
I$ = RIGHT$(SPACE$(8) + LTRIM$(STR$(I)), 8)
LINE INPUT #1, J$
IF INSTR(J$, n$) THEN PRINT I$; ":"; J$
I = I + 1
WEND
CLOSE #1
END SUB
SUB WRITESUB
SHELL "COPY " + TEMP1$ + CHR$(32) + FILE$
END SUB
DECLARE SUB BASICSUB ()
DECLARE SUB LOADSTMT ()
DECLARE SUB SAVESTMT ()
DECLARE SUB INITGETSYM (N AS INTEGER)
DECLARE SUB VALIDLINENUM ()
DECLARE SUB DOCMD ()
DECLARE FUNCTION ACCEPT% (S AS STRING)
DECLARE SUB GETSYM ()
DECLARE FUNCTION ADDEXPR% ()
DECLARE SUB CLEARVARS ()
DECLARE SUB LISTSTMT ()
DECLARE SUB LLISTSTMT ()
DECLARE SUB GOTOSTMT ()
DECLARE SUB IFSTMT ()
DECLARE SUB INPUTSTMT ()
DECLARE SUB PRINTSTMT ()
DECLARE SUB LPRINTSTMT ()
DECLARE SUB SKIPTOEOL ()
DECLARE SUB IDSTMT ()
DECLARE SUB EXPECT (S AS STRING)
DECLARE FUNCTION EXPRESSION% ()
DECLARE FUNCTION FACTOR% ()
DECLARE SUB GETCH ()
DECLARE SUB READSTR ()
DECLARE SUB READIDENT ()
DECLARE SUB READINT ()
DECLARE FUNCTION GETVARINDEX% ()
DECLARE SUB GOTOLINE ()
DECLARE FUNCTION TERM% ()
DECLARE SUB OBFUSCATESUB ()
DECLARE FUNCTION ROT13$ (X$)
DECLARE SUB HELPSUB ()
DECLARE SUB WRITESUB ()
DECLARE SUB LISTSUB ()
DECLARE SUB PRINTSUB ()
DECLARE SUB DELETESUB ()
DECLARE SUB INSERTSUB ()
DECLARE SUB EDITSUB ()
DECLARE SUB SEARCHSUB ()
DECLARE SUB REPLACESUB ()
DECLARE SUB QUITSUB ()
DEFINT A-Z
DIM SHARED CH$, THELIN$, PGM$(2000), TOK$
DIM SHARED VARS(26) AS INTEGER, CURLINE AS INTEGER, NUM AS INTEGER
DIM SHARED TEXTP AS INTEGER, ERRORS AS INTEGER
DIM SHARED FILE$, TEMP1$, TEMP2$
IF COMAND$ = "" THEN
INPUT "FILE? ", FILE$
ELSE
FILE$ = COMMAND$
END IF
SHELL "if not exist " + FILE$ + " echo Reading input from CON into new file. ^Z to end"
' Uncomment for Win98
' SHELL "cmd /c if not exist " + FILE$ + " copy con " + FILE$
SHELL "cmd /c if not exist " + FILE$ + " copy con " + FILE$
I = LEN(FILE$) - 1
TEMP1$ = LEFT$(FILE$, I) + "~"
TEMP2$ = LEFT$(FILE$, I) + "!"
SHELL "COPY " + FILE$ + CHR$(32) + TEMP1$
DO
INPUT "*", CMD$
CMD$ = LEFT$(UCASE$(LTRIM$(RTRIM$(CMD$))), 1)
SELECT CASE CMD$
CASE "L"
CALL LISTSUB
CASE "P"
CALL PRINTSUB
CASE "D"
CALL DELETESUB
CASE "I"
CALL INSERTSUB
CASE "E"
CALL EDITSUB
CASE "S"
CALL SEARCHSUB
CASE "R"
CALL REPLACESUB
CASE "W"
CALL WRITESUB
CASE "Q"
CALL QUITSUB
CASE "?", "H"
CALL HELPSUB
CASE "O"
CALL OBFUSCATESUB
CASE "B"
CALL BASICSUB
CASE "C"
LINE INPUT I$
' Uncomment for Win98
' SHELL i$
SHELL "cmd /c " + I$
CASE "K"
'Uncomment for Win98
'SHELL
SHELL "cmd"
END SELECT
LOOP
FUNCTION ACCEPT (S AS STRING)
ACCEPT = 0
IF TOK$ = S THEN ACCEPT = 1: CALL GETSYM
END FUNCTION
FUNCTION ADDEXPR
DIM N
N = TERM
ADDEL:
IF TOK$ = "+" THEN CALL GETSYM: N = N + TERM: GOTO ADDEL
IF TOK$ = "-" THEN CALL GETSYM: N = N - TERM: GOTO ADDEL
ADDEXPR = N
END FUNCTION
SUB BASICSUB
DO
ERRORS = 0
LINE INPUT "> ", PGM$(0)
IF PGM$(0) = "BYE" THEN EXIT SUB
IF PGM$(0) <> "" THEN
CALL INITGETSYM(0)
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
CALL VALIDLINENUM
PGM$(NUM) = MID$(PGM$(0), TEXTP, LEN(PGM$(0)) - TEXTP + 1)
ELSE
CALL DOCMD
END IF
END IF
LOOP
END SUB
SUB CLEARVARS
DIM I AS INTEGER
FOR I = 1 TO 26
VARS(I) = 0
NEXT I
END SUB
SUB DELETESUB
INPUT "ENTER RANGE OR ENTER TO CANCE;", RANGE$
IF LTRIM$(RANGE$) = "" THEN
EXIT SUB
ELSE
STARTLINE = VAL(RANGE$)
ENDLINE = VAL(MID$(RANGE$, INSTR(RANGE$, "-") + 1))
END IF
OPEN TEMP1$ FOR INPUT AS #1
OPEN TEMP2$ FOR OUTPUT AS #2
FOR I = 1 TO STARTLINE - 1
IF EOF(1) THEN EXIT FOR
LINE INPUT #1, LINE$
PRINT #2, LINE$
NEXT
FOR I = STARTLINE TO ENDLINE
IF EOF(1) THEN EXIT FOR
LINE INPUT #1, LINE$
NEXT
WHILE NOT EOF(1)
LINE INPUT #1, LINE$
PRINT #2, LINE$
WEND
CLOSE #1
CLOSE #2
SHELL "COPY " + TEMP2$ + CHR$(32) + TEMP1$
KILL TEMP2$
END SUB
SUB DOCMD
DIM I AS INTEGER
AGAIN:
IF ERRORS <> 0 THEN EXIT SUB
WHILE TOK$ = ""
IF CURLINE = 0 OR CURLINE >= 1999 THEN EXIT SUB
CALL INITGETSYM(CURLINE + 1)
WEND
IF ACCEPT("CLS") THEN CLS
IF ACCEPT("STOP") OR ACCEPT("END") THEN EXIT SUB
IF ACCEPT("NEW") THEN
CALL CLEARVARS
FOR I = 1 TO 1999
PGM$(I) = ""
NEXT I
EXIT SUB
END IF
IF ACCEPT("LIST") THEN CALL LISTSTMT: GOTO AGAIN
IF ACCEPT("LLIST") THEN CALL LLISTSTMT: GOTO AGAIN
IF ACCEPT("RUN") THEN
CALL CLEARVARS
CALL INITGETSYM(1)
GOTO AGAIN
END IF
IF ACCEPT("LOAD") THEN CALL LOADSTMT: GOTO AGAIN
IF ACCEPT("SAVE") THEN CALL SAVESTMT: GOTO AGAIN
IF ACCEPT("GOTO") THEN CALL GOTOSTMT: GOTO AGAIN
IF ACCEPT("IF") THEN CALL IFSTMT: GOTO AGAIN
IF ACCEPT("INPUT") THEN CALL INPUTSTMT: GOTO AGAIN
IF ACCEPT("PRINT") THEN CALL PRINTSTMT: GOTO AGAIN
IF ACCEPT("LPRINT") THEN CALL LPRINTSTMT: GOTO AGAIN
IF ACCEPT("REM") THEN CALL SKIPTOEOL: GOTO AGAIN
IF LEFT$(TOK$, 1) >= "A" AND LEFT$(TOK$, 1) <= "Z" THEN
CALL IDSTMT
GOTO AGAIN
END IF
PRINT "UNKNOWN TOKEN "; TOK$; " AT LINE "; CURLINE
END SUB
SUB EDITSUB
INPUT "ENTER RANGE OR ENTER TO CANCEL", RANGE$
IF LTRIM$(RANGE$) = "" THEN
EXIT SUB
ELSE
STARTLINE = VAL(RANGE$)
ENDLINE = VAL(MID$(RANGE$, INSTR(RANGE$, "-") + 1))
END IF
OPEN TEMP1$ FOR INPUT AS #1
OPEN TEMP2$ FOR OUTPUT AS #2
FOR I = 1 TO STARTLINE - 1
IF EOF(1) THEN EXIT FOR
LINE INPUT #1, LINE$
PRINT #2, LINE$
NEXT
FOR I = STARTLINE TO ENDLINE
LINE INPUT LINE$
PRINT #2, LINE$
NEXT
WHILE NOT EOF(1)
LINE INPUT #1, LINE$
PRINT #2, LINE$
WEND
CLOSE #1
CLOSE #2
SHELL "COPY " + TEMP2$ + CHR$(32) + TEMP1$
KILL TEMP2$
END SUB
SUB EXPECT (S AS STRING)
IF ACCEPT(S) <> 0 THEN EXIT SUB
ERRORS = 1
PRINT "EXPECTING "; S; " BUT FOUND "; TOK$
END SUB
FUNCTION EXPRESSION
DIM N
N = ADDEXPR
EXPRL:
IF TOK$ = "=" THEN CALL GETSYM: N = N = ADDEXPR: GOTO EXPRL
IF TOK$ = "<" THEN CALL GETSYM: N = N < ADDEXPR: GOTO EXPRL
IF TOK$ = ">" THEN CALL GETSYM: N = N > ADDEXPR: GOTO EXPRL
IF TOK$ = "<>" THEN CALL GETSYM: N = N <> ADDEXPR: GOTO EXPRL
IF TOK$ = "<=" THEN CALL GETSYM: N = N <= ADDEXPR: GOTO EXPRL
IF TOK$ = ">=" THEN CALL GETSYM: N = N >= ADDEXPR: GOTO EXPRL
EXPRESSION = N
END FUNCTION
FUNCTION FACTOR
IF ACCEPT("-") THEN
FACTOR = -FACTOR
EXIT FUNCTION
END IF
IF ACCEPT("(") THEN
FACTOR = EXPRESSION
CALL EXPECT(")")
EXIT FUNCTION
END IF
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
FACTOR = NUM
CALL GETSYM
EXIT FUNCTION
END IF
IF LEFT$(TOK$, 1) >= "A" AND LEFT$(TOK$, 1) <= "Z" THEN
FACTOR = VARS(GETVARINDEX)
EXIT FUNCTION
END IF
PRINT "UNEXPECTED SYM "; TOK$; " IN FACTOR": ERRORS = 1
END FUNCTION
SUB GETCH
IF TEXTP > LEN(THELIN$) THEN CH$ = "": EXIT SUB
CH$ = MID$(THELIN$, TEXTP, 1)
TEXTP = TEXTP + 1
END SUB
SUB GETSYM
TOK$ = ""
WHILE CH$ <= " "
IF CH$ = "" THEN EXIT SUB
CALL GETCH
WEND
TOK$ = CH$
IF INSTR(",;=+-*/()", CH$) > 0 THEN CALL GETCH: EXIT SUB
IF CH$ = "<" THEN
CALL GETCH
IF CH$ = "=" OR CH$ = ">" THEN
TOK$ = TOK$ + CH$
CALL GETCH
END IF
EXIT SUB
END IF
IF CH$ = ">" THEN
CALL GETCH
IF CH$ = "=" THEN TOK$ = TOK$ + CH$: CALL GETCH
EXIT SUB
END IF
IF CH$ = CHR$(34) THEN CALL READSTR: EXIT SUB
IF CH$ >= "A" AND CH$ <= "Z" THEN CALL READIDENT: EXIT SUB
IF CH$ >= "0" AND CH$ <= "9" THEN CALL READINT: EXIT SUB
PRINT "WHAT->"; CH$: ERRORS = 1
END SUB
FUNCTION GETVARINDEX
IF LEFT$(TOK$, 1) < "A" OR LEFT$(TOK$, 1) > "Z" THEN
PRINT "NOT A VARIABLE": ERRORS = 1: EXIT FUNCTION
END IF
GETVARINDEX = ASC(LEFT$(TOK$, 1)) - ASC("A")
CALL GETSYM
END FUNCTION
SUB GOTOLINE
CALL VALIDLINENUM
CALL INITGETSYM(NUM)
END SUB
SUB GOTOSTMT
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
CALL GOTOLINE
EXIT SUB
END IF
PRINT "LINE NUMBER MUST FOLLOW GOTO": ERRORS = 1
END SUB
SUB HELPSUB
PRINT "List -- Display lines from file"
PRINT "Print -- Print file"
PRINT "Write -- Save changes"
PRINT "Quit -- Exit"
PRINT "Help -- Display this message"
PRINT "Insert -- Insert lines"
PRINT "Delete -- Delete lines"
PRINT "Search -- Search for text"
PRINT "Replace -- Search for text and replace"
PRINT "Edit -- Replace lines"
PRINT "Obfuscate -- ROT13 text"
PRINT "Basic -- BASIC interpreter"
PRINT TAB(4); "PRINT -- print text/expressions/variables to screen"
PRINT TAB(4); "GOTO -- go to a line in execution"
PRINT TAB(4); "IF -- execute if expression is true"
PRINT TAB(4); "NEW -- clear program from memory"
PRINT TAB(4); "SAVE -- save code to file"
PRINT TAB(4); "LOAD -- save code stored in file"
PRINT TAB(4); "LPRINT -- print to printer"
PRINT TAB(4); "LLIST -- send program listing to printer"
PRINT TAB(4); "LIST -- show program listing"
PRINT TAB(4); "CLS -- clear screen"
PRINT "Compile -- Execute single DOS command"
PRINT "Konsole -- Start DOS shell"
END SUB
SUB IDSTMT
DIM VAR AS INTEGER
VAR = GETVARINDEX
CALL EXPECT("=")
VARS(VAR) = EXPRESSION
END SUB
SUB IFSTMT
DIM B AS INTEGER
IF EXPRESSION = 0 THEN CALL SKIPTOEOL: EXIT SUB
B = ACCEPT("THEN")
IF LEFT$(TOK$, 1) >= "0" AND LEFT$(TOK$, 1) <= "9" THEN
CALL GOTOLINE
END IF
END SUB
SUB INITGETSYM (N AS INTEGER)
CURLINE = N
TEXTP = 1
THELIN$ = PGM$(CURLINE)
CH$ = " "
CALL GETSYM
END SUB
SUB INPUTSTMT
DIM VAR AS INTEGER
IF TOK$ = CHR$(34) THEN
PRINT MID$(TOK$, 2, LEN(TOK$) - 1);
CALL GETSYM
CALL EXPECT(",")
ELSE
PRINT "? ";
END IF
VAR = GETVARINDEX
INPUT VARS(VAR)
END SUB
SUB INSERTSUB
INPUT "INSERT AFTER WHICH LINE? ", RANGE$
PRINT "CTRL-Z ON ITS OWN LINE TO STOP INSERTING"
IF LTRIM$(RANGE$) = "" THEN
EXIT SUB
ELSE
STARTLINE = VAL(RANGE$)
END IF
OPEN TEMP1$ FOR INPUT AS #1
OPEN TEMP2$ FOR OUTPUT AS #2
FOR I = 1 TO STARTLINE
IF EOF(1) THEN EXIT FOR
LINE INPUT #1, LINE$
PRINT #2, LINE$
NEXT
DO
LINE INPUT LINE$
IF LTRIM$(RTRIM$(LINE$)) = CHR$(26) THEN EXIT DO
PRINT #2, LINE$
LOOP
WHILE NOT EOF(1)
LINE INPUT #1, LINE$
PRINT #2, LINE$
WEND
CLOSE #1
CLOSE #2
SHELL "COPY " + TEMP2$ + CHR$(32) + TEMP1$
KILL TEMP2$
END SUB
SUB LISTSTMT
DIM I AS INTEGER
FOR I = 1 TO 1999
IF PGM$(I) <> "" THEN PRINT I; " "; PGM$(I)
NEXT I
PRINT
END SUB
SUB LISTSUB
INPUT "ENTER RANGE OR ENTER TO LIST ALL", RANGE$
IF LTRIM$(RANGE$) = "" THEN
STARTLINE = 1
ENDLINE = 32767
ELSE
STARTLINE = VAL(RANGE$)
ENDLINE = VAL(MID$(RANGE$, INSTR(RANGE$, "-") + 1))
END IF
OPEN TEMP1$ FOR INPUT AS #1
FOR I = STARTLINE TO ENDLINE
IF EOF(1) THEN EXIT FOR
LINE INPUT #1, LINE$
I$ = RIGHT$(SPACE$(8) + LTRIM$(STR$(I)), 8)
PRINT I$; ":"; LINE$
NEXT
CLOSE #1
END SUB
SUB LLISTSTMT
DIM I AS INTEGER
FOR I = 1 TO 1999
IF PGM$(I) <> "" THEN LPRINT I; " "; PGM$(I)
NEXT I
PRINT
END SUB
SUB LOADSTMT
INPUT "FILE? "; LOAD$
OPEN LOAD$ FOR INPUT AS #1
FOR I = 1 TO 1999
IF EOF(1) THEN EXIT FOR
LINE INPUT #1, PGM$(I)
NEXT
END SUB
SUB LPRINTSTMT
DIM LPRINTNL AS INTEGER
LPRINTNL = 1
DO WHILE TOK$ <> ""
LPRINTNL = 1
IF LEFT$(TOK$, 1) = CHR$(34) THEN
LPRINT MID$(TOK$, 2, LEN(TOK$) - 1);
CALL GETSYM
ELSE
LPRINT EXPRESSION;
END IF
IF ACCEPT(",") = 0 AND ACCEPT(";") = 0 THEN EXIT DO
PRINTNL = 0
LOOP
IF PRINTNL <> 0 THEN LPRINT
END SUB
SUB OBFUSCATESUB
INPUT "INPUT RANGE OR ENTER TO ROT13 WHOLE FILE: ", RANGE$
IF LTRIM$(RANGE$) = "" THEN
STARTLINE = 1
ENDLINE = 32767
ELSE
STARTLINE = VAL(RANGE$)
ENDLINE = VAL(MID$(RANGE$, INSTR(RANGE$, "-") + 1))
END IF
OPEN TEMP1$ FOR INPUT AS #1
OPEN TEMP2$ FOR OUTPUT AS #2
FOR I = 1 TO STARTLINE - 1
IF EOF(1) THEN EXIT FOR
LINE INPUT #1, LINE$
PRINT #2, LINE$
NEXT
FOR I = STARTLINE TO ENDLINE
IF EOF(1) THEN EXIT FOR
LINE INPUT #1, LINE$
LINE$ = ROT13$(LINE$)
PRINT #2, LINE$
NEXT
WHILE NOT EOF(1)
LINE INPUT #1, LINE$
PRINT #2, LINE$
WEND
CLOSE #1
CLOSE #2
SHELL "COPY " + TEMP2$ + CHR$(32) + TEMP1$
KILL TEMP2$
END SUB
SUB PRINTSTMT
DIM PRINTNL AS INTEGER
PRINTNL = 1
DO WHILE TOK$ <> ""
PRINTNL = 1
IF LEFT$(TOK$, 1) = CHR$(34) THEN
PRINT MID$(TOK$, 2, LEN(TOK$) - 1);
CALL GETSYM
ELSE
PRINT EXPRESSION;
END IF
IF ACCEPT(",") = 0 AND ACCEPT(";") = 0 THEN EXIT DO
PRINTNL = 0
LOOP
IF PRINTNL <> 0 THEN PRINT
END SUB
SUB PRINTSUB
OPEN TEMP1$ FOR INPUT AS #1
WIDTH LPRINT 255
WHILE NOT EOF(1)
INPUT #1, N$
LPRINT N$
WEND
CLOSE
END SUB
SUB QUITSUB
INPUT "REALLY QUIT? ", N$
N$ = UCASE$(LTRIM$(RTRIM$(N$)))
IF N$ = "YES" OR N$ = "Y" THEN END
KILL TEMP1$
KILL TEMP2$
END SUB
SUB READIDENT
TOK$ = ""
WHILE CH$ >= "A" AND CH$ <= "Z"
TOK$ = TOK$ + CH$
CALL GETCH
WEND
END SUB
SUB READINT
TOK$ = ""
WHILE CH$ >= "0" AND CH$ <= "9"
TOK$ = TOK$ + CH$
CALL GETCH
WEND
NUM = VAL(TOK$)
END SUB
SUB READSTR
TOK$ = CHR$(34)
CALL GETCH
WHILE CH$ <> CHR$(34)
IF CH$ = "" THEN
PRINT "STRING NOT TERMINATED": ERRORS = 1: EXIT SUB
END IF
TOK$ = TOK$ + CH$
CALL GETCH
WEND
CALL GETCH
END SUB
SUB REPLACESUB
LINE INPUT "SEARCH FOR? ", X$
LINE INPUT "REPLACE WITH? ", Y$
IF X$ = "" THEN EXIT SUB
IF X$ = Y$ THEN EXIT SUB
OPEN TEMP1$ FOR INPUT AS #1
OPEN TEMP2$ FOR OUTPUT AS #2
WHILE NOT EOF(1)
LINE INPUT #1, J$
J = 1
DO
I = INSTR(J, J$, X$)
J = I
IF I THEN J$ = LEFT$(J$, I - 1) + Y$ + MID$(J$, I + LEN(X$)) ELSE EXIT DO
LOOP
PRINT #2, J$
WEND
CLOSE #1
CLOSE #2
SHELL "COPY " + TEMP2$ + CHR$(32) + TEMP1$
KILL TEMP2$
END SUB
FUNCTION ROT13$ (X$)
FOR I = 1 TO LEN(X$)
A = ASC(MID$(X$, I))
B = 64 XOR A AND 223
IF B AND B < 27 THEN
Z$ = Z$ + CHR$((A AND 96) OR (B + 12) MOD 26 + 1)
ELSE
Z$ = Z$ + CHR$(A)
END IF
NEXT
ROT13$ = Z$
END FUNCTION
SUB SAVESTMT
INPUT "FILE? "; SAVEAS$
OPEN SAVEAS$ FOR OUTPUT AS #1
FOR I = 1 TO 1999
PRINT #1, PGM$(I)
NEXT
CLOSE #1
END SUB
SUB SEARCHSUB
LINE INPUT "STRING TO SEARCH? ", N$
I = 1
OPEN TEMP1$ FOR INPUT AS #1
WHILE NOT EOF(1)
I$ = RIGHT$(SPACE$(8) + LTRIM$(STR$(I)), 8)
LINE INPUT #1, J$
IF INSTR(J$, N$) THEN PRINT I$; ":"; J$
I = I + 1
WEND
CLOSE #1
END SUB
SUB SKIPTOEOL
WHILE CH$ <> ""
CALL GETCH
WEND
CALL GETSYM
END SUB
FUNCTION TERM
DIM N
N = FACTOR
TERML:
IF TOK$ = "*" THEN CALL GETSYM: N = N * FACTOR: GOTO TERML
IF TOK$ = "/" THEN CALL GETSYM: N = N / FACTOR: GOTO TERML
TERM = N
END FUNCTION
SUB VALIDLINENUM
IF NUM > 0 AND NUM <= 1999 THEN EXIT SUB
PRINT "LINE NUMBER OUT OF RANGE": ERRORS = 1
END SUB
SUB WRITESUB
SHELL "COPY " + TEMP1$ + CHR$(32) + FILE$
END SUB
TYPE REGTYPE
AX AS INTEGER
BX AS INTEGER
CX AS INTEGER
DX AS INTEGER
BP AS INTEGER
SI AS INTEGER
DI AS INTEGER
FLAGS AS INTEGER
END TYPE
DIM REGS AS REGTYPE
X = 0
Y = 0
WIDTH 80, 50
REGS.AX = 0
CALL INTERRUPT(&H33, REGS, REGS)
REGS.AX = 1
CALL INTERRUPT(&H33, REGS, REGS)
DO
KEY$ = INKEY$
IF KEY$ = CHR$(27) THEN END
IF KEY$ <> "" THEN COLOR ASC(KEY$) MOD 16
REGS.AX = 3
CALL INTERRUPT(&H33, REGS, REGS)
LOCATE 1, 1
Y = REGS.DX
X = REGS.CX
Y = Y \ 8 + 1
X = X \ 8 + 1
Z = REGS.BX
IF X <> OLDX OR Y <> OLDY THEN
REGS.AX = 1
CALL INTERRUPT(&H33, REGS, REGS)
END IF
IF Z = 1 THEN
REGS.AX = 2
LOCATE Y, X: PRINT "*";
ELSEIF Z AND 2 THEN
CLS
END IF
OLDX = X
OLDY = Y
LOOP
DECLARE SUB INTERRUPTQB (intnum AS INTEGER, InReg AS ANY, OutReg AS ANY)
TYPE RegType
AX AS INTEGER
BX AS INTEGER
CX AS INTEGER
DX AS INTEGER
BP AS INTEGER
SI AS INTEGER
DI AS INTEGER
FLAGS AS INTEGER
END TYPE
DIM REGS AS RegType
X = 0
Y = 0
WIDTH 80, 50
REGS.AX = 0
CALL INTERRUPTQB(&H33, REGS, REGS)
REGS.AX = 1
CALL INTERRUPTQB(&H33, REGS, REGS)
DO
KEY$ = INKEY$
IF KEY$ = CHR$(27) THEN END
IF KEY$ <> "" THEN COLOR ASC(KEY$) MOD 16
REGS.AX = 3
CALL INTERRUPTQB(&H33, REGS, REGS)
LOCATE 1, 1
Y = REGS.DX
X = REGS.CX
Y = Y \ 8 + 1
X = X \ 8 + 1
Z = REGS.BX
IF X <> OLDX OR Y <> OLDY THEN
REGS.AX = 1
CALL INTERRUPTQB(&H33, REGS, REGS)
END IF
IF Z = 1 THEN
REGS.AX = 2
LOCATE Y, X: PRINT "*";
ELSEIF Z AND 2 THEN
CLS
END IF
OLDX = X
OLDY = Y
LOOP
SUB INTERRUPTQB (intnum AS INTEGER, InReg AS RegType, OutReg AS RegType)
'standard INTERRUPTQB call compatibility with QBasic
'some static variables
STATIC a() AS LONG, bReady AS INTEGER
'If assembler array not created, create it
IF NOT bReady THEN
'don't change anything
I = 50: DIM a(1 TO I) AS LONG
a(1) = &H53EC8B55: a(2) = &H1E575651: a(3) = &H5E8B9C06: a(4) = &HA078B0E
a(5) = &HC70774E4: a(6) = &HE9FFFF07: a(7) = &HEC8300A1: a(8) = &HB3F88A0A
a(9) = &HE85E89CD: a(10) = &HCBEA46C7: a(11) = &H74253C90: a(12) = &H75263C04
a(13) = &HEA46C714: a(14) = &H46C701E8: a(15) = &HC7CB00EC: a(16) = &H2C2EE46
a(17) = &HF046C7: a(18) = &H85E8B90: a(19) = &H5E8B37FF: a(20) = &HE37FF06
a(21) = &H50008FB8: a(22) = &HE85E8D16: a(23) = &H8BDA8C53: a(24) = &H378B0A5E
a(25) = &H8E0C5E8B: a(26) = &H10448B1F: a(27) = &H75FFFF3D: a(28) = &H50C28B02
a(29) = &H3D12448B: a(30) = &H275FFFF: a(31) = &HC08EC28B: a(32) = &H5C8B048B
a(33) = &H44C8B02: a(34) = &H8B06548B: a(35) = &H748B0C7C: a(36) = &H9CCB1F0A
a(37) = &H83EC8B55: a(38) = &H1E5620C5: a(39) = &H89E476C5: a(40) = &H25C8904
a(41) = &H89044C89: a(42) = &H7C890654: a(43) = &H12448C0C: a(44) = &H8F10448F
a(45) = &H448F0A44: a(46) = &HE448F08: a(47) = &H9D0EC483: a(48) = &H5E5F1F07
a(49) = &HCA5D5B59: a(50) = &H9165000A
'Checksum, can be ommited
S1 = 0: S2 = 0: p = VARPTR(a(1)): DEF SEG = VARSEG(a(1))
FOR I = 0 TO 199
S1 = (S1 + PEEK(p + I)) MOD 255: S2 = (S2 + S1) MOD 255
NEXT I
IF S1 OR S2 THEN ERROR 2: intnum = -1: EXIT SUB ' Checksum Error
'End of the checksum
bReady = -1
END IF
'This is where we call our assembler INTERRUPTQB calling function
DEF SEG = VARSEG(a(1))
CALL ABSOLUTE(intnum, VARSEG(InReg), VARPTR(InReg), VARSEG(OutReg), VARPTR(OutReg), 0)
END SUB
Re: SCREEN 0 DRAWING PROGRAM (CALL ABSOLUTE VERSION)
January 6 2008, 7:06 PM
made a couple changes to it:
1.
IF key$ = CHR$(27) THEN END
IF key$ <> "" THEN COLOR ASC(key$) MOD 16
to:
IF key$ = CHR$(27) THEN END
IF csr$ = "" THEN csr$ = "*"
IF key$ <> "" THEN COLOR ASC(key$) MOD 16
IF key$ = "'" THEN csr$ = CHR$(VAL(INPUT$(3)))
IF key$ = "/" THEN csr$ = INPUT$(1)
Saw the same thing done using Absolute with Peek and Poke
January 6 2008, 7:19 PM
But I could only use Mouse Functions 1 to 3 as I could not figure out how to send values to the routine. Funny how you can get grahics coordinates, but can't use them to do any graphics in 0.
CONST pi = 3.141592653589793#
SCREEN 12
WINDOW (0, 0)-(1, 1)
ANGLE = 0
y = 0
delta = .0100001667#
DO
LOCATE 1, 60
PRINT USING "Factor 1: #.####"; SIN(ANGLE)
LOCATE 2, 60
PRINT USING "Factor 2: #.####"; y
LOCATE 3, 60
PRINT USING "Product: #.####"; y * SIN(ANGLE)
IF (ANGLE <> oldangle) OR (y <> oldy) THEN CLS
LINE (0, 0)-(1, 0)
LINE (0, 0)-(COS(ANGLE), SIN(ANGLE))
LINE (COS(ANGLE), SIN(ANGLE))-(COS(ANGLE), 0), 14
LINE (y * COS(ANGLE), y * SIN(ANGLE))-(y * COS(ANGLE), 0), 12
oldangle = ANGLE
oldy = y
key$ = INKEY$
FOR I = 0 TO 1 STEP .1
LINE (I, 0)-(I, .01)
LINE (I * COS(ANGLE), I * SIN(ANGLE))-(I * COS(ANGLE), I * SIN(ANGLE) - .01)
NEXT
SELECT CASE key$
CASE CHR$(0) + CHR$(72)
ANGLE = ANGLE + delta
CASE CHR$(0) + CHR$(80)
ANGLE = ANGLE - delta
CASE CHR$(0) + CHR$(75)
y = y - delta
CASE CHR$(0) + CHR$(77)
y = y + delta
CASE "F", "f"
delta = delta * 10
CASE "S", "s"
delta = delta * .1
END SELECT
IF (ANGLE > pi / 2) THEN ANGLE = 0
IF (ANGLE < 0) THEN ANGLE = pi / 2
IF (y < 0) THEN y = 0
IF (y > 1) THEN y = 1
LOOP
CONST pi = 3.141592653589793#
SCREEN 12
WINDOW (0, 0)-(1, 1)
ANGLE = 0
y = 0
delta = .0100001667#
DO
LOCATE 1, 60
PRINT USING "Factor 1: #.####"; COS(ANGLE)
LOCATE 2, 60
PRINT USING "Factor 2: #.####"; y
LOCATE 3, 60
PRINT USING "Product: #.####"; y * COS(ANGLE)
IF (ANGLE <> oldangle) OR (y <> oldy) THEN CLS
LINE (0, 0)-(1, 0)
LINE (0, 0)-(COS(ANGLE), SIN(ANGLE))
LINE (COS(ANGLE), SIN(ANGLE))-(COS(ANGLE), 0), 14
LINE (y * COS(ANGLE), y * SIN(ANGLE))-(y * COS(ANGLE), 0), 12
oldangle = ANGLE
oldy = y
key$ = INKEY$
FOR I = 0 TO 1 STEP .1
LINE (I, 0)-(I, .01)
LINE (I * COS(ANGLE), I * SIN(ANGLE))-(I * COS(ANGLE), I * SIN(ANGLE) - .01)
NEXT
SELECT CASE key$
CASE CHR$(0) + CHR$(72)
ANGLE = ANGLE + delta
CASE CHR$(0) + CHR$(80)
ANGLE = ANGLE - delta
CASE CHR$(0) + CHR$(75)
y = y - delta
CASE CHR$(0) + CHR$(77)
y = y + delta
CASE "F", "f"
delta = delta * 10
CASE "S", "s"
delta = delta * .1
END SELECT
IF (ANGLE > pi / 2) THEN ANGLE = 0
IF (ANGLE < 0) THEN ANGLE = pi / 2
IF (y < 0) THEN y = 0
IF (y > 1) THEN y = 1
LOOP
CONST pi = 3.141592653589793#
SCREEN 12
WINDOW (0, 0)-(1, 1)
ANGLE = 0
y = 0
delta = .0100001667#
DO
LOCATE 1, 60
PRINT USING "Factor 1: #.####"; COS(ANGLE)
LOCATE 2, 60
PRINT USING "Factor 2: #.####"; y
LOCATE 3, 60
PRINT USING "Product: #.####"; y * COS(ANGLE)
IF (ANGLE <> oldangle) OR (y <> oldy) THEN CLS
LINE (0, 0)-(1, 0)
LINE (0, 0)-(COS(ANGLE), SIN(ANGLE))
LINE (COS(ANGLE), SIN(ANGLE))-(COS(ANGLE), 0), 14
LINE (y * COS(ANGLE), y * SIN(ANGLE))-(y * COS(ANGLE), 0), 12
oldangle = ANGLE
oldy = y
key$ = INKEY$
FOR I = 0 TO 100
IF (I MOD 10) = 0 THEN
SIZE = .02
ELSEIF (I MOD 5) = 0 THEN
SIZE = .015
ELSE
SIZE = .01
END IF
LINE ((I / 100), 0)-((I / 100), SIZE)
LINE ((I / 100) * COS(ANGLE), (I / 100) * SIN(ANGLE))-((I / 100) * COS(ANGLE) + SIZE * SIN(ANGLE), (I / 100) * SIN(ANGLE) - SIZE * COS(ANGLE))
NEXT
SELECT CASE key$
CASE CHR$(0) + CHR$(72)
ANGLE = ANGLE + delta
CASE CHR$(0) + CHR$(80)
ANGLE = ANGLE - delta
CASE CHR$(0) + CHR$(75)
y = y - delta
CASE CHR$(0) + CHR$(77)
y = y + delta
CASE "F", "f"
delta = delta * 10
CASE "S", "s"
delta = delta * .1
END SELECT
IF (ANGLE > pi / 2) THEN ANGLE = 0
IF (ANGLE < 0) THEN ANGLE = pi / 2
IF (y < 0) THEN y = 0
IF (y > 1) THEN y = 1
LOOP
I think it is HIGH time that you joined R Group so that you can edit stuff!
February 24 2008, 4:58 PM
Really, what do you accomplish by constantly posting fixes and updates? I took a look at your Proud of list today. You have made some great stuff, but as you are finding out I hope, a program is never truely done. You have been coming here for quite a while now so why not join?
Version With Continuous Second Hand if anyone prefers this
February 29 2008, 2:41 PM
SCREEN 12
CONST PI = 3.14159265358979#
WINDOW (-1.6, 1.2)-(1.6, -1.2)
DO
i = TIMER
hrs = (i / 8640)
mins = 100 * ((i / 8640) - INT(i / 8640))
secs = 10000 * ((i / 8640) - INT(i / 8640))
a1 = 2 * PI - ((hrs - 2.5) / 10) * 2 * PI
a2 = 2 * PI - ((mins - 25) / 100) * 2 * PI
a3 = 2 * PI - ((secs - 25) / 100) * 2 * PI
WIDTH , 60
FOR J = 0 TO 100
JJ = PI / 2 - (J / 100) * 2 * PI
SIZE = .9
IF (J MOD 5) = 0 THEN SIZE = .85
IF (J MOD 10) = 0 THEN SIZE = .8
LINE (COS(JJ), SIN(JJ))-(SIZE * COS(JJ), SIZE * SIN(JJ)), 15
NEXT
FOR J = 0 TO 9
JJ = PI / 2 - (J / 10) * 2 * PI
X = PMAP(1.1 * COS(JJ), 0) \ 8 + 1
Y = PMAP(1.1 * SIN(JJ), 1) \ 8 + 1
LOCATE Y, X
PRINT J
NEXT
WINDOW (-1.6, 1.2)-(1.6, -1.2)
LINE (0, 0)-(.8 * COS(olda1), .8 * SIN(olda1)), 0
LINE (0, 0)-(.9 * COS(olda2), .9 * SIN(olda2)), 0
LINE (0, 0)-(COS(olda3), SIN(olda3)), 0
LINE (0, 0)-(.8 * COS(a1), .8 * SIN(a1)), 14
LINE (0, 0)-(.9 * COS(a2), .9 * SIN(a2)), 10
LINE (0, 0)-(COS(a3), SIN(a3)), 12
olda1 = a1
olda2 = a2
olda3 = a3
LOOP UNTIL INKEY$ = CHR$(27)
This message has been edited by dean.menezes on Mar 21, 2008 6:54 PM This message has been edited by dean.menezes on Mar 21, 2008 6:53 PM This message has been edited by dean.menezes on Mar 21, 2008 6:52 PM This message has been edited by dean.menezes on Feb 29, 2008 3:20 PM
Beautiful clock, but I first had to correct the code to get it to work:
March 21 2008, 6:31 PM
a1 = 2 * PI - ((hrs - 2.5) / 10) 2 PI
a2 = 2 * PI - ((mins - 25) / 100) 2 PI
a3 = 2 * PI - ((secs - 25) / 100) 2 PI
JJ = PI / 2 - (J / 100) 2 PI
JJ = PI / 2 - (J / 10) 2 PI
======================================
These 5 lines should all be:
whatever) x 2 x PI
For some strange reason, the asterisk doesn't show up in the post. I put an x there instead but it should be corrected. Maybe you can figure it out and edit it yourself.
This message has been edited by Solitaire1 on Mar 21, 2008 6:38 PM This message has been edited by Solitaire1 on Mar 21, 2008 6:34 PM
RANDOMIZE TIMER
DIM syms(&O157) AS STRING
DO
PRINT "QBASIC MIND READER"
FOR I = 0 TO &O157
syms(I) = CHR$(&O344 + INT(RND(1) * 16))
NEXT
a$ = CHR$(&O344 + INT(RND(1) * 16))
FOR I = 0 TO &O157 STEP &O11
syms(I) = a$
NEXT
CLS
FOR I = 0 TO &O157
PRINT USING "### & "; I; syms(I);
NEXT
PRINT : PRINT
PRINT "Choose any two digit number, add together both digits"
PRINT "and then subtract the total from your original number"
PRINT
PRINT "When you have the final number look it up on the chart"
PRINT "and find the relevant symbol. Concentrate on the glyph"
PRINT "and when you have it memorized the glyph, press Return"
PRINT "and I will show you the symbol you are thinking of."
DO: I$ = INPUT$(1): IF I$ = CHR$(27) THEN SYSTEM
LOOP UNTIL I$ = CHR$(13)
CLS
PRINT "Your symbol was: "; a$
PRINT
PRINT "Can't believe it? Press Return to try again"
DO: I$ = INPUT$(1): IF I$ = CHR$(27) THEN SYSTEM
LOOP UNTIL I$ = CHR$(13)
LOOP
This message has been edited by dean.menezes on Mar 1, 2008 1:39 PM
PRINT "Choose any two digit number, add together both digits"
Let's say my number is 42. I add together both digits to get 6.
Subtract the total from your original number
PRINT "and then subtract the total from your original number"
42 - 6 = 36
PRINT "When you have the final number look it up on the chart"
I look up 36 in the chart and the symbol next to it is ß. I press Enter and the program does indeed say ß. Of course, you guessed the trick. The formatting in the chart may have been messed up because the forum trims spaces, but oh well.
You pick a number in your head. Not from the screen!
March 2 2008, 8:44 PM
Then you do the math. Once you have your answer look at the symbol to the right of the answer.
Press enter and the same symbol is shown. All answers that are multiples of 9 have that symbol next to them no matter if the symbol changes next try or not.
This trick can be done with any number of digits. My program arranges the numbers and symbols more neatly by using MOD and a PRINT "". It also uses number answers from 99 to 198 for a range between 100 and 200.
1 means it visited the square first, 2 means it visited it second, etc.
DECLARE SUB KNIGHT (A%, B%, XX%(), YY%(), NDX%)
DECLARE SUB RECALC ()
DEFINT A-Z
RANDOMIZE TIMER
CLS
DIM SHARED XX(27), YY(27), BOARD(8, 8)
A = 0: B = 0
FOR I = -1 TO -64 STEP -1
BOARD(B, A) = I
CALL RECALC
NDX = 0
CALL KNIGHT(A, B, XX(), YY(), NDX)
MIN = 32767
FOR J = 1 TO NDX
IF (BOARD(YY(J), XX(J)) < MIN) OR (BOARD(YY(J), XX(J)) = MIN AND RND(1) < .5) THEN
MIN = BOARD(YY(J), XX(J))
X = XX(J)
Y = YY(J)
END IF
NEXT
A = X
B = Y
NEXT
FOR Y = 0 TO 7
FOR X = 0 TO 7
PRINT USING " ## "; ABS(BOARD(Y, X));
NEXT
PRINT
NEXT
SUB KNIGHT (A, B, XX(), YY(), NDX)
X = A - 1
Y = B - 2
GOSUB 5
X = A - 2
Y = B - 1
GOSUB 5
X = A + 1
Y = B - 2
GOSUB 5
X = A + 2
Y = B - 1
GOSUB 5
X = A - 1
Y = B + 2
GOSUB 5
X = A - 2
Y = B + 1
GOSUB 5
X = A + 1
Y = B + 2
GOSUB 5
X = A + 2
Y = B + 1
GOSUB 5
EXIT SUB
5 REM
IF X < 0 OR X > 7 OR Y < 0 OR Y > 7 THEN RETURN
IF BOARD(Y, X) >= 0 THEN NDX = NDX + 1: XX(NDX) = X: YY(NDX) = Y
RETURN
END SUB
SUB RECALC
FOR A = 0 TO 7
FOR B = 0 TO 7
NDX = 0
IF BOARD(B, A) >= 0 THEN
CALL KNIGHT(A, B, XX(), YY(), NDX)
BOARD(B, A) = NDX
END IF
NEXT
NEXT
END SUB
This is the CALL INTERRUPT VERSION. It will not work in QBASIC 1.1 -- only in QBASIC 4.5. Use the mouse to set up the initial position. Right click when you are done. The program will then iterate through 100 generations, pausing 0.2 seconds between generations. You can have it skip to the next generation without pausing by pressing a key or clicking or you can have it exit by pressing escape.
DECLARE FUNCTION NUMOFNEIGHBORS% (A%(), I%, J%)
DECLARE SUB ASSIGNLOGARRAY (A%(), B%())
DECLARE SUB DISPLAYARRAY (B%(), GEN%, DONEXTGEN%)
DECLARE SUB DETBIRTHORDEATH (AIJ%, N%, B%(), I%, J%)
DEFINT A-Z
DECLARE SUB GETINITCONFIG (A())
TYPE REGTYPE
AX AS INTEGER
BX AS INTEGER
CX AS INTEGER
DX AS INTEGER
BP AS INTEGER
SI AS INTEGER
DI AS INTEGER
FLAGS AS INTEGER
DS AS INTEGER
ES AS INTEGER
END TYPE
DIM SHARED REGS AS REGTYPE
CONST ROWS = 50
CONST COLS = 80
CONST CELLS = ROWS * COLS
CONST GENS = 100
DIM A(ROWS, COLS), B(ROWS, COLS)
WIDTH 80, 50
CALL GETINITCONFIG(A())
CALL ASSIGNLOGARRAY(A(), B())
CALL DISPLAYARRAY(A(), GEN, DONEXTGEN)
GEN = GEN + 1
DO WHILE GEN <= GENS AND DONEXTGEN
FOR J = 2 TO COLS - 1
FOR I = 2 TO ROWS - 1
N = NUMOFNEIGHBORS(A(), I, J)
CALL DETBIRTHORDEATH(A(I, J), N, B(), I, J)
NEXT
NEXT
CALL DISPLAYARRAY(B(), GEN, DONEXTGEN)
CALL ASSIGNLOGARRAY(B(), A())
GEN = GEN + 1
LOOP
' Given two arrays, assign all cells of a to b
SUB ASSIGNLOGARRAY (A(), B())
FOR J = 1 TO COLS
FOR I = 1 TO ROWS
B(I, J) = A(I, J)
NEXT
NEXT
END SUB
SUB DETBIRTHORDEATH (AIJ, N, B(), I, J)
IF NOT AIJ AND N = 3 THEN
B(I, J) = -1
ELSEIF AIJ AND (N < 2 OR N > 3) THEN
B(I, J) = 0
END IF
END SUB
' Display all cells in array
SUB DISPLAYARRAY (B(), GEN, DONEXTGEN)
DIM T AS SINGLE
CLS
FOR I = 1 TO ROWS
FOR J = 1 TO COLS
IF B(I, J) THEN PRINT "*"; ELSE PRINT " ";
NEXT
NEXT
T = TIMER
DO WHILE T > TIMER - .2
KEY$ = INKEY$
REGS.AX = 3
CALL INTERRUPT(&H33, REGS, REGS)
IF REGS.BX <> 0 OR KEY$ <> "" THEN EXIT DO
LOOP
IF KEY$ = CHR$(27) THEN END
DONEXTGEN = -1
END SUB
' Get initial configuration
SUB GETINITCONFIG (A())
DIM T AS SINGLE
REGS.AX = 0
CLS
CALL INTERRUPT(&H33, REGS, REGS) 'Initialize mouse driver
REGS.AX = 1
CALL INTERRUPT(&H33, REGS, REGS) 'Show cursor
DO
REGS.AX = 3
CALL INTERRUPT(&H33, REGS, REGS)
IF REGS.BX = 1 THEN
ROW = REGS.DX \ 8 + 1
COL = REGS.CX \ 8 + 1
A(ROW, COL) = NOT A(ROW, COL)
REGS.AX = 2
CALL INTERRUPT(&H33, REGS, REGS)
LOCATE ROW, COL
IF A(ROW, COL) THEN PRINT "*"; ELSE PRINT " ";
REGS.AX = 1
CALL INTERRUPT(&H33, REGS, REGS)
T = TIMER: WHILE T > TIMER - .2: WEND
END IF
LOOP UNTIL REGS.BX = 2
END SUB
FUNCTION NUMOFNEIGHBORS (A(), I, J)
N = 0
FOR C = J - 1 TO J + 1
FOR R = I - 1 TO I + 1
IF A(R, C) THEN N = N + 1
NEXT
NEXT
IF A(I, J) THEN N = N - 1
NUMOFNEIGHBORS = N
END FUNCTION
This is the CALL ABSOLUTE VERSION. It will work in QB 1.1 but you may have problems compiling it with QB 4.5 or QB 7.1.
Use the mouse to set up the initial position. Right click when you are done. The program will then iterate through 100 generations, pausing 0.2 seconds between generations. You can have it skip to the next generation without pausing by pressing a key or clicking or you can have it exit by pressing escape.
DECLARE SUB INTERRUPTQB (intnum AS INTEGER, InReg AS ANY, OutReg AS ANY)
DECLARE FUNCTION NUMOFNEIGHBORS% (a%(), I%, J%)
DECLARE SUB ASSIGNLOGARRAY (a%(), B%())
DECLARE SUB DISPLAYARRAY (B%(), GEN%, DONEXTGEN%)
DECLARE SUB DETBIRTHORDEATH (AIJ%, N%, B%(), I%, J%)
DEFINT A-Z
DECLARE SUB GETINITCONFIG (a())
TYPE RegType
AX AS INTEGER
BX AS INTEGER
CX AS INTEGER
DX AS INTEGER
BP AS INTEGER
SI AS INTEGER
DI AS INTEGER
FLAGS AS INTEGER
DS AS INTEGER
ES AS INTEGER
END TYPE
DIM SHARED REGS AS RegType
CONST ROWS = 50
CONST COLS = 80
CONST CELLS = ROWS * COLS
CONST GENS = 100
DIM a(ROWS, COLS), B(ROWS, COLS)
WIDTH 80, 50
CALL GETINITCONFIG(a())
CALL ASSIGNLOGARRAY(a(), B())
CALL DISPLAYARRAY(a(), GEN, DONEXTGEN)
GEN = GEN + 1
DO WHILE GEN <= GENS AND DONEXTGEN
FOR J = 2 TO COLS - 1
FOR I = 2 TO ROWS - 1
N = NUMOFNEIGHBORS(a(), I, J)
CALL DETBIRTHORDEATH(a(I, J), N, B(), I, J)
NEXT
NEXT
CALL DISPLAYARRAY(B(), GEN, DONEXTGEN)
CALL ASSIGNLOGARRAY(B(), a())
GEN = GEN + 1
LOOP
' Given two arrays, assign all cells of a to b
SUB ASSIGNLOGARRAY (a(), B())
FOR J = 1 TO COLS
FOR I = 1 TO ROWS
B(I, J) = a(I, J)
NEXT
NEXT
END SUB
SUB DETBIRTHORDEATH (AIJ, N, B(), I, J)
IF NOT AIJ AND N = 3 THEN
B(I, J) = -1
ELSEIF AIJ AND (N < 2 OR N > 3) THEN
B(I, J) = 0
END IF
END SUB
' Display all cells in array
SUB DISPLAYARRAY (B(), GEN, DONEXTGEN)
DIM T AS SINGLE
CLS
FOR I = 1 TO ROWS
FOR J = 1 TO COLS
IF B(I, J) THEN PRINT "*"; ELSE PRINT " ";
NEXT
NEXT
T = TIMER
DO WHILE T > TIMER - .2
KEY$ = INKEY$
REGS.AX = 3
CALL INTERRUPTQB(&H33, REGS, REGS)
IF REGS.BX <> 0 OR KEY$ <> "" THEN EXIT DO
LOOP
IF KEY$ = CHR$(27) THEN END
DONEXTGEN = -1
END SUB
' Get initial configuration
SUB GETINITCONFIG (a())
DIM T AS SINGLE
REGS.AX = 0
CLS
CALL INTERRUPTQB(&H33, REGS, REGS) 'Initialize mouse driver
REGS.AX = 1
CALL INTERRUPTQB(&H33, REGS, REGS) 'Show cursor
DO
REGS.AX = 3
CALL INTERRUPTQB(&H33, REGS, REGS)
IF REGS.BX = 1 THEN
ROW = REGS.DX \ 8 + 1
COL = REGS.CX \ 8 + 1
a(ROW, COL) = NOT a(ROW, COL)
REGS.AX = 2
CALL INTERRUPTQB(&H33, REGS, REGS)
LOCATE ROW, COL
IF a(ROW, COL) THEN PRINT "*"; ELSE PRINT " ";
REGS.AX = 1
CALL INTERRUPTQB(&H33, REGS, REGS)
T = TIMER: WHILE T > TIMER - .5: WEND
END IF
LOOP UNTIL REGS.BX = 2
END SUB
SUB INTERRUPTQB (intnum AS INTEGER, InReg AS RegType, OutReg AS RegType)
'standard INTERRUPTQB call compatibility with QBasic
'some static variables
STATIC a() AS LONG, bReady AS INTEGER
'If assembler array not created, create it
IF NOT bReady THEN
'don't change anything
I = 50: DIM a(1 TO I) AS LONG
a(1) = &H53EC8B55: a(2) = &H1E575651: a(3) = &H5E8B9C06: a(4) = &HA078B0E
a(5) = &HC70774E4: a(6) = &HE9FFFF07: a(7) = &HEC8300A1: a(8) = &HB3F88A0A
a(9) = &HE85E89CD: a(10) = &HCBEA46C7: a(11) = &H74253C90: a(12) = &H75263C04
a(13) = &HEA46C714: a(14) = &H46C701E8: a(15) = &HC7CB00EC: a(16) = &H2C2EE46
a(17) = &HF046C7: a(18) = &H85E8B90: a(19) = &H5E8B37FF: a(20) = &HE37FF06
a(21) = &H50008FB8: a(22) = &HE85E8D16: a(23) = &H8BDA8C53: a(24) = &H378B0A5E
a(25) = &H8E0C5E8B: a(26) = &H10448B1F: a(27) = &H75FFFF3D: a(28) = &H50C28B02
a(29) = &H3D12448B: a(30) = &H275FFFF: a(31) = &HC08EC28B: a(32) = &H5C8B048B
a(33) = &H44C8B02: a(34) = &H8B06548B: a(35) = &H748B0C7C: a(36) = &H9CCB1F0A
a(37) = &H83EC8B55: a(38) = &H1E5620C5: a(39) = &H89E476C5: a(40) = &H25C8904
a(41) = &H89044C89: a(42) = &H7C890654: a(43) = &H12448C0C: a(44) = &H8F10448F
a(45) = &H448F0A44: a(46) = &HE448F08: a(47) = &H9D0EC483: a(48) = &H5E5F1F07
a(49) = &HCA5D5B59: a(50) = &H9165000A
'Checksum, can be ommited
S1 = 0: S2 = 0: p = VARPTR(a(1)): DEF SEG = VARSEG(a(1))
FOR I = 0 TO 199
S1 = (S1 + PEEK(p + I)) MOD 255: S2 = (S2 + S1) MOD 255
NEXT I
IF S1 OR S2 THEN ERROR 2: intnum = -1: EXIT SUB ' Checksum Error
'End of the checksum
bReady = -1
END IF
'This is where we call our assembler INTERRUPTQB calling function
DEF SEG = VARSEG(a(1))
CALL ABSOLUTE(intnum, VARSEG(InReg), VARPTR(InReg), VARSEG(OutReg), VARPTR(OutReg), 0)
END SUB
FUNCTION NUMOFNEIGHBORS (a(), I, J)
N = 0
FOR C = J - 1 TO J + 1
FOR R = I - 1 TO I + 1
IF a(R, C) THEN N = N + 1
NEXT
NEXT
IF a(I, J) THEN N = N - 1
NUMOFNEIGHBORS = N
END FUNCTION
I remember playing an old windows game that had the same principles, except that you could change the squares even after you had started. (Also, I think it had a mode where you could play two sides against each other, red and blue, and the two would interact.)
Experimenting a few times, I accidentally came up with something that eventually generated, among other things, the pattern I had wanted to see...
here is the pattern upon termination:
--*
*-*
-**
this pattern will cause the appearance of traveling across the screen...
I'm sure more information can be gained by doing google or wikipedia searches on the title of his game.
Conway's Game of Life (call absolute) w/ instructions
March 23 2008, 7:14 AM
DECLARE SUB INTERRUPTQB (intnum AS INTEGER, InReg AS ANY, OutReg AS ANY)
DECLARE FUNCTION NUMOFNEIGHBORS% (a%(), I%, J%)
DECLARE SUB ASSIGNLOGARRAY (a%(), B%())
DECLARE SUB DISPLAYARRAY (B%(), GEN%, DONEXTGEN%)
DECLARE SUB DETBIRTHORDEATH (AIJ%, N%, B%(), I%, J%)
DEFINT A-Z
DECLARE SUB GETINITCONFIG (a())
TYPE RegType
AX AS INTEGER
BX AS INTEGER
CX AS INTEGER
DX AS INTEGER
BP AS INTEGER
SI AS INTEGER
DI AS INTEGER
FLAGS AS INTEGER
DS AS INTEGER
ES AS INTEGER
END TYPE
DIM SHARED REGS AS RegType
CONST ROWS = 50
CONST COLS = 80
CONST CELLS = ROWS * COLS
CONST GENS = 999
DIM a(ROWS, COLS), B(ROWS, COLS)
WIDTH 80, 50
PRINT "***********"
PRINT "Instructions"
PRINT "============"
PRINT "1) Start program. Click to replace letters with asterisks"
PRINT "2) On the last letter, use right-click"
PRINT "3) Wait. You should see an animation with `gliders' being created"
PRINT SPACE$(4); "which appear to travel accross the screen"
PRINT "4) If you are tired of watching it, press escape to quit. To"
PRINT SPACE$(4); "make the animation go faster, press a key or click"
PRINT SPACE$(4); "the mouse"
PRINT "5) When satisfied with the demo, go to SUB GETINITCONFIG and"
PRINT SPACE$(4); "remove block of code that looks like this:"
PRINT SPACE$(10); "LOCATE 17, 40"
PRINT SPACE$(10); "PRINT " + CHR$(34) + "N" + CHR$(34)
PRINT SPACE$(10); "LOCATE 18, 38"
PRINT SPACE$(10); "PRINT " + CHR$(34) + "P" + CHR$(34)
PRINT SPACE$(10); "LOCATE 18, 40"
PRINT SPACE$(10); "PRINT " + CHR$(34) + "H" + CHR$(34)
PRINT SPACE$(10); "...etc"
PRINT SPACE$(4); "you can now make your own patterns and see how they evolve."
LINE INPUT "Press Enter to get started"; e$: CLS
CALL GETINITCONFIG(a())
CALL ASSIGNLOGARRAY(a(), B())
CALL DISPLAYARRAY(a(), GEN, DONEXTGEN)
GEN = GEN + 1
DO WHILE GEN <= GENS AND DONEXTGEN
FOR J = 2 TO COLS - 1
FOR I = 2 TO ROWS - 1
N = NUMOFNEIGHBORS(a(), I, J)
CALL DETBIRTHORDEATH(a(I, J), N, B(), I, J)
NEXT
NEXT
CALL DISPLAYARRAY(B(), GEN, DONEXTGEN)
CALL ASSIGNLOGARRAY(B(), a())
GEN = GEN + 1
LOOP
' Given two arrays, assign all cells of a to b
SUB ASSIGNLOGARRAY (a(), B())
FOR J = 1 TO COLS
FOR I = 1 TO ROWS
B(I, J) = a(I, J)
NEXT
NEXT
END SUB
SUB DETBIRTHORDEATH (AIJ, N, B(), I, J)
IF NOT AIJ AND N = 3 THEN
B(I, J) = -1
ELSEIF AIJ AND (N < 2 OR N > 3) THEN
B(I, J) = 0
END IF
END SUB
' Display all cells in array
SUB DISPLAYARRAY (B(), GEN, DONEXTGEN)
DIM T AS SINGLE
CLS
FOR I = 1 TO ROWS
FOR J = 1 TO COLS
IF B(I, J) THEN PRINT "*"; ELSE PRINT " ";
NEXT
NEXT
T = TIMER
DO WHILE T > TIMER - .2
KEY$ = INKEY$
REGS.AX = 3
CALL INTERRUPTQB(&H33, REGS, REGS)
IF REGS.BX <> 0 OR KEY$ <> "" THEN EXIT DO
LOOP
IF KEY$ = CHR$(27) THEN END
DONEXTGEN = -1
END SUB
CALL INTERRUPTQB(&H33, REGS, REGS) 'Initialize mouse driver
REGS.AX = 1
CALL INTERRUPTQB(&H33, REGS, REGS) 'Show cursor
DO
REGS.AX = 3
CALL INTERRUPTQB(&H33, REGS, REGS)
IF REGS.BX = 1 THEN
ROW = REGS.DX \ 8 + 1
COL = REGS.CX \ 8 + 1
a(ROW, COL) = NOT a(ROW, COL)
REGS.AX = 2
CALL INTERRUPTQB(&H33, REGS, REGS)
LOCATE ROW, COL
IF a(ROW, COL) THEN PRINT "*"; ELSE PRINT " ";
REGS.AX = 1
CALL INTERRUPTQB(&H33, REGS, REGS)
T = TIMER: WHILE T > TIMER - .5: WEND
END IF
LOOP UNTIL REGS.BX = 2
END SUB
SUB INTERRUPTQB (intnum AS INTEGER, InReg AS RegType, OutReg AS RegType)
'standard INTERRUPTQB call compatibility with QBasic
'some static variables
STATIC a() AS LONG, bReady AS INTEGER
'If assembler array not created, create it
IF NOT bReady THEN
'don't change anything
I = 50: DIM a(1 TO I) AS LONG
a(1) = &H53EC8B55: a(2) = &H1E575651: a(3) = &H5E8B9C06: a(4) = &HA078B0E
a(5) = &HC70774E4: a(6) = &HE9FFFF07: a(7) = &HEC8300A1: a(8) = &HB3F88A0A
a(9) = &HE85E89CD: a(10) = &HCBEA46C7: a(11) = &H74253C90: a(12) = &H75263C04
a(13) = &HEA46C714: a(14) = &H46C701E8: a(15) = &HC7CB00EC: a(16) = &H2C2EE46
a(17) = &HF046C7: a(18) = &H85E8B90: a(19) = &H5E8B37FF: a(20) = &HE37FF06
a(21) = &H50008FB8: a(22) = &HE85E8D16: a(23) = &H8BDA8C53: a(24) = &H378B0A5E
a(25) = &H8E0C5E8B: a(26) = &H10448B1F: a(27) = &H75FFFF3D: a(28) = &H50C28B02
a(29) = &H3D12448B: a(30) = &H275FFFF: a(31) = &HC08EC28B: a(32) = &H5C8B048B
a(33) = &H44C8B02: a(34) = &H8B06548B: a(35) = &H748B0C7C: a(36) = &H9CCB1F0A
a(37) = &H83EC8B55: a(38) = &H1E5620C5: a(39) = &H89E476C5: a(40) = &H25C8904
a(41) = &H89044C89: a(42) = &H7C890654: a(43) = &H12448C0C: a(44) = &H8F10448F
a(45) = &H448F0A44: a(46) = &HE448F08: a(47) = &H9D0EC483: a(48) = &H5E5F1F07
a(49) = &HCA5D5B59: a(50) = &H9165000A
'Checksum, can be ommited
S1 = 0: S2 = 0: p = VARPTR(a(1)): DEF SEG = VARSEG(a(1))
FOR I = 0 TO 199
S1 = (S1 + PEEK(p + I)) MOD 255: S2 = (S2 + S1) MOD 255
NEXT I
IF S1 OR S2 THEN ERROR 2: intnum = -1: EXIT SUB ' Checksum Error
'End of the checksum
bReady = -1
END IF
'This is where we call our assembler INTERRUPTQB calling function
DEF SEG = VARSEG(a(1))
CALL ABSOLUTE(intnum, VARSEG(InReg), VARPTR(InReg), VARSEG(OutReg), VARPTR(OutReg), 0)
END SUB
FUNCTION NUMOFNEIGHBORS (a(), I, J)
N = 0
FOR C = J - 1 TO J + 1
FOR R = I - 1 TO I + 1
IF a(R, C) THEN N = N + 1
NEXT
NEXT
IF a(I, J) THEN N = N - 1
NUMOFNEIGHBORS = N
END FUNCTION
Conway's game of life w/ instructions (call interrupt version)
March 23 2008, 7:16 AM
DECLARE FUNCTION NUMOFNEIGHBORS% (a%(), I%, J%)
DECLARE SUB ASSIGNLOGARRAY (a%(), B%())
DECLARE SUB DISPLAYARRAY (B%(), GEN%, DONEXTGEN%)
DECLARE SUB DETBIRTHORDEATH (AIJ%, N%, B%(), I%, J%)
DEFINT A-Z
DECLARE SUB GETINITCONFIG (a())
TYPE RegType
AX AS INTEGER
BX AS INTEGER
CX AS INTEGER
DX AS INTEGER
BP AS INTEGER
SI AS INTEGER
DI AS INTEGER
FLAGS AS INTEGER
DS AS INTEGER
ES AS INTEGER
END TYPE
DIM SHARED REGS AS RegType
CONST ROWS = 50
CONST COLS = 80
CONST CELLS = ROWS * COLS
CONST GENS = 999
DIM a(ROWS, COLS), B(ROWS, COLS)
WIDTH 80, 50
PRINT "***********"
PRINT "Instructions"
PRINT "============"
PRINT "1) Start program. Click to replace letters with asterisks"
PRINT "2) On the last letter, use right-click"
PRINT "3) Wait. You should see an animation with `gliders' being created"
PRINT SPACE$(4); "which appear to travel accross the screen"
PRINT "4) If you are tired of watching it, press escape to quit. To"
PRINT SPACE$(4); "make the animation go faster, press a key or click"
PRINT SPACE$(4); "the mouse"
PRINT "5) When satisfied with the demo, go to SUB GETINITCONFIG and"
PRINT SPACE$(4); "remove block of code that looks like this:"
PRINT SPACE$(10); "LOCATE 17, 40"
PRINT SPACE$(10); "PRINT " + CHR$(34) + "N" + CHR$(34)
PRINT SPACE$(10); "LOCATE 18, 38"
PRINT SPACE$(10); "PRINT " + CHR$(34) + "P" + CHR$(34)
PRINT SPACE$(10); "LOCATE 18, 40"
PRINT SPACE$(10); "PRINT " + CHR$(34) + "H" + CHR$(34)
PRINT SPACE$(10); "...etc"
PRINT SPACE$(4); "you can now make your own patterns and see how they evolve."
LINE INPUT "Press Enter to get started"; e$: CLS
CALL GETINITCONFIG(a())
CALL ASSIGNLOGARRAY(a(), B())
CALL DISPLAYARRAY(a(), GEN, DONEXTGEN)
GEN = GEN + 1
DO WHILE GEN <= GENS AND DONEXTGEN
FOR J = 2 TO COLS - 1
FOR I = 2 TO ROWS - 1
N = NUMOFNEIGHBORS(a(), I, J)
CALL DETBIRTHORDEATH(a(I, J), N, B(), I, J)
NEXT
NEXT
CALL DISPLAYARRAY(B(), GEN, DONEXTGEN)
CALL ASSIGNLOGARRAY(B(), a())
GEN = GEN + 1
LOOP
' Given two arrays, assign all cells of a to b
SUB ASSIGNLOGARRAY (a(), B())
FOR J = 1 TO COLS
FOR I = 1 TO ROWS
B(I, J) = a(I, J)
NEXT
NEXT
END SUB
SUB DETBIRTHORDEATH (AIJ, N, B(), I, J)
IF NOT AIJ AND N = 3 THEN
B(I, J) = -1
ELSEIF AIJ AND (N < 2 OR N > 3) THEN
B(I, J) = 0
END IF
END SUB
' Display all cells in array
SUB DISPLAYARRAY (B(), GEN, DONEXTGEN)
DIM T AS SINGLE
CLS
FOR I = 1 TO ROWS
FOR J = 1 TO COLS
IF B(I, J) THEN PRINT "*"; ELSE PRINT " ";
NEXT
NEXT
T = TIMER
DO WHILE T > TIMER - .2
KEY$ = INKEY$
REGS.AX = 3
CALL interrupt(&H33, REGS, REGS)
IF REGS.BX <> 0 OR KEY$ <> "" THEN EXIT DO
LOOP
IF KEY$ = CHR$(27) THEN END
DONEXTGEN = -1
END SUB
CALL interrupt(&H33, REGS, REGS) 'Initialize mouse driver
REGS.AX = 1
CALL interrupt(&H33, REGS, REGS) 'Show cursor
DO
REGS.AX = 3
CALL interrupt(&H33, REGS, REGS)
IF REGS.BX = 1 THEN
ROW = REGS.DX \ 8 + 1
COL = REGS.CX \ 8 + 1
a(ROW, COL) = NOT a(ROW, COL)
REGS.AX = 2
CALL interrupt(&H33, REGS, REGS)
LOCATE ROW, COL
IF a(ROW, COL) THEN PRINT "*"; ELSE PRINT " ";
REGS.AX = 1
CALL interrupt(&H33, REGS, REGS)
T = TIMER: WHILE T > TIMER - .5: WEND
END IF
LOOP UNTIL REGS.BX = 2
END SUB
FUNCTION NUMOFNEIGHBORS (a(), I, J)
N = 0
FOR C = J - 1 TO J + 1
FOR R = I - 1 TO I + 1
IF a(R, C) THEN N = N + 1
NEXT
NEXT
IF a(I, J) THEN N = N - 1
NUMOFNEIGHBORS = N
END FUNCTION
DIM XX(1 TO 3) AS DOUBLE, YY(1 TO 3) AS DOUBLE, X AS DOUBLE, Y AS DOUBLE
DIM I AS INTEGER
SCREEN 12
WINDOW (0, 0)-(1.6, 1.2)
XX(1) = 0
YY(1) = 0
XX(2) = 2.4 / SQR(3)
YY(2) = 0
XX(3) = 1.2 / SQR(3)
YY(3) = 1.2
DO
I = INT(RND(1) * 3) + 1
X = .5 * (X + XX(I))
Y = .5 * (Y + YY(I))
PSET (X, Y)
LOOP UNTIL INKEY$ = CHR$(27)
CLS
SCREEN 8
s1 = 225
f1 = 1.4
s2 = 225
f2 = .35
x = .4
y = .1
FOR i = 1 TO 2000
x1 = y + 1 - 1.4 * x * x
y = .3 * x
IF s1 * (x1 + f1) < 640 AND x1 + f1 > 0 THEN
IF s2 * (y + f2) < 350 AND y + f2 > 0 THEN
PSET (s1 * (x1 + f1), s2 * (y + f2))
END IF
END IF
x = x1
NEXT
SCREEN 12
WINDOW (-5, 0)-(5, 10)
RANDOMIZE TIMER
COLOR 10
DO
SELECT CASE RND
CASE IS < .01
X = 0
Y = .16 * Y
CASE .01 TO .08
X = .2 * X - .26 * Y
Y = .23