Skip to content

Instantly share code, notes, and snippets.

@eevee
Last active Sep 27, 2020
Embed
What would you like to do?
chip's challenge in qbasic — compiled for dos at https://c.eev.ee/CHIPS.EXE
DECLARE FUNCTION WaitKey$ ()
' Add support for stepping off of force floors - DONE
' Add support for nonwaiting so monsters and things can move - SORTA DONE
' Add support for blocks moving on ice
' Add support for dying when the player steps in unprotected water, fire,
' or gets hit by a monster - DONE
' Level editor!
DECLARE SUB KillPlayer (S AS STRING, C AS INTEGER)
DECLARE FUNCTION ChipCount! ()
DECLARE SUB SetDir (K AS STRING)
DECLARE SUB CenterPrint (msg AS STRING, linenum AS INTEGER)
DECLARE SUB DrawBoard ()
DECLARE SUB LoadBoard (Level AS INTEGER)
DECLARE SUB NextLevel ()
DECLARE SUB ReverseScan (find AS STRING)
DECLARE SUB LinearScan (find AS STRING)
DECLARE SUB Quit (msg AS STRING)
DECLARE SUB SwapTiles (char1 AS STRING, char2 AS STRING)
DECLARE SUB Inventory ()
DECLARE SUB DrawPlayer ()
DECLARE SUB CheckCode ()
DECLARE SUB DrawPoint (R AS INTEGER, C AS INTEGER)
CONST ENTER = 13, ESCAPE = 27
CONST DOWNARROW = 80, UPARROW = 72, LEFTARROW = 75, RIGHTARROW = 77
DIM SHARED Row AS INTEGER, Column AS INTEGER, totalchips AS INTEGER, code AS STRING
DIM SHARED Board(1 TO 25) AS STRING, chipleft AS INTEGER, flippers AS INTEGER
DIM SHARED iceboots AS INTEGER, fireboots AS INTEGER, suckerboots AS INTEGER
DIM SHARED keyy AS INTEGER, keyg AS INTEGER, keyr AS INTEGER, keyb AS INTEGER
DIM SHARED move AS INTEGER, poof AS STRING, PlayerChar AS STRING, keyt AS INTEGER
DIM SHARED ROffset AS INTEGER, COffset AS INTEGER, LevelName AS STRING, LevelNum AS INTEGER
DIM SHARED movement AS INTEGER, killNow AS INTEGER
'ON ERROR GOTO Handler
PlayerChar$ = CHR$(2)
CLS
LoadBoard 1
DO
DO
K$ = INKEY$
IF K$ = CHR$(27) THEN END
IF LCASE$(K$) = "r" THEN LoadBoard LevelNum: EXIT DO
IF movement = 0 THEN
COffset = 0: ROffset = 0
IF K$ <> CHR$(0) AND LEN(K$) <> 0 THEN
IF ASC(K$) > 96 AND ASC(K$) < 123 THEN code$ = code$ + K$
CheckCode
SetDir K$
END IF
ELSEIF movement = 2 THEN
IF K$ <> "" AND movestyle = 0 THEN
SetDir K$
movestyle = 1
ELSE
ROffset = NROffset
COffset = NCOffset
movestyle = 0
END IF
ELSE
K$ = INKEY$
END IF
MoveTo$ = MID$(Board(Row + ROffset), Column + COffset, 1)
move = 0: poof$ = MoveTo$
IF ABS(COffset) + ABS(ROffset) = 0 THEN EXIT DO
IF tspace THEN
SELECT CASE MoveTo$
CASE "t": move = 1: tspace = 0: PlayerChar$ = CHR$(2)
CASE "f":
CASE ELSE: move = 1
END SELECT
ELSE
killNow = 0
SELECT CASE MoveTo$
CASE " ": move = 1
CASE "x":
CASE "c": move = 1: poof$ = " ": IF chipleft > 0 THEN chipleft = chipleft - 1
CASE "S": IF chipleft = 0 THEN move = 1: poof$ = " "
CASE "E": move = 1: NextLevel: EXIT DO
CASE "F": move = 1: poof$ = " ": flippers = 1
CASE "W": move = 1: IF flippers = 0 THEN KillPlayer "You drowned.", 9: EXIT DO
CASE "G":
CASE "g": move = 1
CASE "b": move = 1: SwapTiles "G", "g": SwapTiles "q", "Q"
CASE "P":
CASE "p": move = 1
CASE "B": move = 1: SwapTiles "P", "p"
CASE "i":
CASE "I": poof$ = "R"
CASE "R":
CASE "/": move = 1: poof$ = " "
CASE "?": poof$ = "x"
CASE "1": keyy = keyy + 1: move = 1: poof$ = " "
CASE "2": keyg = keyg + 1: move = 1: poof$ = " "
CASE "3": keyb = keyb + 1: move = 1: poof$ = " "
CASE "4": keyr = keyr + 1: move = 1: poof$ = " "
CASE "!": IF keyy THEN keyy = keyy - 1: move = 1: poof$ = " "
CASE "@": IF keyg THEN move = 1: poof$ = " "
CASE "#": IF keyb THEN keyb = keyb - 1: move = 1: poof$ = " "
CASE "$": IF keyr THEN keyr = keyr - 1: move = 1: poof$ = " "
CASE "o": move = 1: poof$ = "x"
CASE "t": tspace = 1: move = 1: PlayerChar$ = CHR$(1)
CASE "T": DrawPoint Row, Column: ReverseScan "T": move = 1
CASE "y": IF keyt THEN DrawPoint Row, Column: ReverseScan "y": move = 1
CASE "k": keyt = 1: move = 1: poof$ = " "
CASE "Y": LinearScan "Y": move = 1
CASE "C": tempspot$ = MID$(Board(Row + 2 * ROffset), Column + 2 * COffset, 1)
IF tempspot$ = " " THEN
MID$(Board(Row + 2 * ROffset), Column + 2 * COffset, 1) = "C"
DrawPoint Row + 2 * ROffset, Column + 2 * COffset
move = 1: poof$ = " "
ELSEIF tempspot$ = "W" THEN
MID$(Board(Row + 2 * ROffset), Column + 2 * COffset, 1) = "d"
DrawPoint Row + 2 * ROffset, Column + 2 * COffset
move = 1: poof$ = " "
ELSEIF tempspot$ = "*" OR tempspot$ = "q" THEN
MID$(Board(Row + 2 * ROffset), Column + 2 * COffset, 1) = "a"
DrawPoint Row + 2 * ROffset, Column + 2 * COffset
move = 1: poof$ = " "
ELSEIF tempspot$ = "a" THEN
MID$(Board(Row + 2 * ROffset), Column + 2 * COffset, 1) = "C"
DrawPoint Row + 2 * ROffset, Column + 2 * COffset
move = 1: poof$ = " "
END IF
CASE "d": move = 1: poof$ = " "
CASE "w": move = 1
CASE "D": SwapTiles "W", "w": move = 1
CASE "~": move = 1: IF iceboots <> 1 THEN movement = 1
CASE "v": move = 1: IF suckerboots = 0 THEN movement = 2: movecycle = 1: NROffset = 1: NCOffset = 0
CASE "^": move = 1: IF suckerboots = 0 THEN movement = 2: movecycle = 1: NROffset = -1: NCOffset = 0
CASE "<": move = 1: IF suckerboots = 0 THEN movement = 2: movecycle = 1: NROffset = 0: NCOffset = -1
CASE ">": move = 1: IF suckerboots = 0 THEN movement = 2: movecycle = 1: NROffset = 0: NCOffset = 1
CASE "f": move = 1
CASE "*":
CASE "a": move = 1
CASE "q":
CASE "Q": move = 1: IF chipleft > 0 THEN chipleft = chipleft - 1: poof$ = " "
CASE "`": move = 1: poof$ = " ": iceboots = 1
CASE "&": move = 1: IF fireboots = 0 THEN KillPlayer "You were roasted.", 8: EXIT DO
CASE "7": move = 1: poof$ = " ": fireboots = 1
CASE ",": move = 1: poof$ = " ": suckerboots = 1
CASE ELSE:
END SELECT
END IF
IF movement = 1 OR movement = 2 THEN
FOR I = 1 TO 50000: NEXT I
IF INSTR("~v^<>", MoveTo$) <> 0 THEN
DrawPoint Row + ROffset, Column + COffset
DrawPoint Row, Column: Row = Row + ROffset: Column = Column + COffset: DrawPoint Row, Column: DrawPlayer
ELSEIF move = 0 AND MoveTo$ = MoveTo$ THEN '"~" THEN
COffset = -1 * COffset
ROffset = -1 * ROffset
DrawPoint Row + ROffset, Column + COffset
DrawPoint Row, Column: Row = Row + ROffset: Column = Column + COffset: DrawPoint Row, Column: DrawPlayer
ELSE
movement = 0
END IF
END IF
IF movement = 0 THEN
MID$(Board(Row + ROffset), Column + COffset, 1) = poof$
DrawPoint Row + ROffset, Column + COffset
IF move THEN DrawPoint Row, Column: Row = Row + ROffset: Column = Column + COffset: DrawPoint Row, Column: DrawPlayer
Inventory
END IF
LOOP
LOOP
Handler:
IF ERR = 62 THEN END ELSE CLS : Quit "Error" + STR$(ERR)
RESUME
SUB CenterPrint (msg AS STRING, linenum AS INTEGER)
LOCATE linenum, INT((80 - LEN(msg)) / 2)
PRINT msg;
END SUB
SUB CheckCode
IF RIGHT$(code$, 5) = "stuff" THEN keyg = 1: keyb = 9: keyy = 9: keyr = 9: keyt = 1: flippers = 1: code$ = ""
IF RIGHT$(code$, 8) = "lays" THEN chipleft = 0: code$ = "": Inventory
IF RIGHT$(code$, 6) = "whoosh" THEN code$ = "": MID$(Board(Row), Column, 1) = "E"
END SUB
FUNCTION ChipCount
chips = 0
FOR I = 1 TO 24
FOR J = 1 TO 80
IF MID$(Board(I), J, 1) = "c" OR MID$(Board(I), J, 1) = "Q" THEN chips = chips + 1
NEXT J
NEXT I
ChipCount = chips
END FUNCTION
SUB DrawBoard
DIM I AS INTEGER, J AS INTEGER
CLS
FOR I = 1 TO 24
FOR J = 1 TO 80
DrawPoint I, J
NEXT J
NEXT I
END SUB
SUB DrawPlayer
LOCATE Row, Column
COLOR 15
PRINT PlayerChar$;
END SUB
SUB DrawPoint (R AS INTEGER, C AS INTEGER)
LOCATE R, C
SELECT CASE MID$(Board(R), C, 1)
CASE " ": COLOR 7, 0: PRINT " ";
CASE "x": COLOR 7, 7: PRINT "Û";
CASE "c": COLOR 8, 0: PRINT "#";
CASE "S": COLOR 10, 0: PRINT "ð";
CASE "E": COLOR 9, 5: PRINT "±";
CASE "F": COLOR 9, 0: PRINT "ê";
CASE "W": COLOR 9, 1: PRINT "°";
CASE "G": COLOR 10, 0: PRINT "Û";
CASE "g": COLOR 2, 0: PRINT "°";
CASE "b": COLOR 10, 0: PRINT "*";
CASE "P": COLOR 13, 0: PRINT "Û";
CASE "p": COLOR 5, 0: PRINT "°";
CASE "B": COLOR 13, 0: PRINT "*";
CASE "i": COLOR 7, 0: PRINT " ";
CASE "I": COLOR 7, 0: PRINT " ";
CASE "R": COLOR 7, 0: PRINT "±";
CASE "/": COLOR 3, 0: PRINT "Û";
CASE "?": COLOR 3, 0: PRINT "Û";
CASE "1": COLOR 14, 0: PRINT "¾";
CASE "!": COLOR 14, 0: PRINT "è";
CASE "2": COLOR 10, 0: PRINT "¾";
CASE "@": COLOR 10, 0: PRINT "è";
CASE "3": COLOR 11, 0: PRINT "¾";
CASE "#": COLOR 11, 0: PRINT "è";
CASE "4": COLOR 12, 0: PRINT "¾";
CASE "$": COLOR 12, 0: PRINT "è";
CASE "o": COLOR 7, 0: PRINT "é";
CASE "t": COLOR 11, 3: PRINT CHR$(15);
CASE "T": COLOR 10, 2: PRINT CHR$(15);
CASE "y": COLOR 14, 6: PRINT CHR$(15);
CASE "Y": COLOR 12, 4: PRINT CHR$(15);
CASE "k": COLOR 15, 0: PRINT "ž";
CASE "C": COLOR 6, 0: PRINT "þ";
CASE "d": COLOR 6, 0: PRINT "°";
CASE "w": COLOR 9, 0: PRINT "°";
CASE "D": COLOR 9, 0: PRINT "o";
CASE "~": COLOR 11, 3: PRINT "ð";
CASE "v": COLOR 10, 2: PRINT "v";
CASE "^": COLOR 10, 2: PRINT "^";
CASE "<": COLOR 10, 2: PRINT "<";
CASE ">": COLOR 10, 2: PRINT ">";
CASE "f": COLOR 11, 0: PRINT "ù";
CASE "*": COLOR 8, 0: PRINT "ë";
CASE "a": COLOR 8, 0: PRINT "°";
CASE "q": COLOR 2, 0: PRINT "ë";
CASE "Q": COLOR 2, 0: PRINT "#";
CASE "`": COLOR 11, 0: PRINT CHR$(20);
CASE "&": COLOR 14, 6: PRINT "°";
CASE "7": COLOR 12, 0: PRINT CHR$(20);
CASE ",": COLOR 10, 0: PRINT CHR$(20);
CASE ELSE: COLOR 15, 0: PRINT "!";
END SELECT
END SUB
SUB Inventory
LOCATE 25, 1
IF chipleft THEN
chip$ = LTRIM$(STR$(chipleft)) + "/" + LTRIM$(STR$(totalchips))
COLOR 15, 0: PRINT SPACE$(9 - LEN(chip$)); chip$; " ";
COLOR 14, 0: PRINT "chips left";
ELSE
COLOR 6, 0: PRINT " No chips left ";
END IF
COLOR 15, 0: PRINT " | ";
IF flippers THEN COLOR 9, 0: PRINT "ê"; ELSE PRINT " ";
IF iceboots THEN COLOR 11, 0: PRINT CHR$(20); ELSE PRINT " ";
IF fireboots THEN COLOR 12, 0: PRINT CHR$(20); ELSE PRINT " ";
IF suckerboots THEN COLOR 10, 0: PRINT CHR$(20); ELSE PRINT " ";
IF keyt > 0 THEN COLOR 15, 0: PRINT "ž"; ELSE PRINT " ";
COLOR 7, 0
PRINT " ";
IF keyy = 0 THEN COLOR 6, 0 ELSE COLOR 14, 0
PRINT "¾"; LTRIM$(STR$(keyy));
IF keyb = 0 THEN COLOR 3, 0 ELSE COLOR 11, 0
PRINT " ¾"; LTRIM$(STR$(keyb));
IF keyr = 0 THEN COLOR 4, 0 ELSE COLOR 12, 0
PRINT " ¾"; LTRIM$(STR$(keyr));
IF keyg = 0 THEN COLOR 2, 0 ELSE COLOR 10, 0
PRINT " ¾";
LOCATE 25, 81 - (LEN(LevelName$) + LOG(LevelNum) + 4)
COLOR 10, 0: PRINT "L"; : PRINT LTRIM$(STR$(LevelNum));
IF LevelName$ <> "" THEN COLOR 15, 0: PRINT ": "; : PRINT LevelName$;
COLOR 7, 0
END SUB
SUB KillPlayer (S AS STRING, C AS INTEGER)
MID$(Board(Row + ROffset), Column + COffset, 1) = poof$
DrawPoint Row + ROffset, Column + COffset
IF move THEN DrawPoint Row, Column: Row = Row + ROffset: Column = Column + COffset: DrawPoint Row, Column: DrawPlayer
LOCATE Row, Column
COLOR C
PRINT PlayerChar$;
COLOR C, 0
LOCATE 25, 1
PRINT SPACE$(80);
CenterPrint S + " [ Press any key to restart level ]", 25
SLEEP
K$ = INKEY$
LoadBoard LevelNum
END SUB
SUB LinearScan (find AS STRING)
R = Row + 2 * ROffset: C = Column + 2 * COffset
WHILE R > 0 AND R < 25 AND C > 0 AND C < 81
IF MID$(Board(R), C, 1) = find$ THEN ROffset = R - Row: COffset = C - Column: EXIT SUB
R = R + ROffset: C = C + COffset
WEND
END SUB
SUB LoadBoard (Level AS INTEGER)
OPEN "levels.txt" FOR INPUT AS #1
FOR I = 1 TO (Level - 1) * 25
LINE INPUT #1, line$
NEXT I
LINE INPUT #1, data$
totalchips = VAL(MID$(data$, 1, 4))
LevelName$ = MID$(data$, 5)
Row = 2: Column = 2
FOR I = 1 TO 24
LINE INPUT #1, Board(I)
IF LEN(Board(I)) <> 80 THEN Quit "Error: Level " + LTRIM$(STR$(LevelNum)) + " row " + LTRIM$(STR$(I)) + " is invalid."
J = INSTR(Board(I), ".")
IF J <> 0 THEN Row = I: Column = J: MID$(Board(I), J, 1) = " "
NEXT I
CLOSE #1
LevelNum = Level
DrawBoard
flippers = 0: movement = 0
iceboots = 0: fireboots = 0: suckerboots = 0
keyy = 0: keyg = 0: keyb = 0: keyr = 0: keyt = 0
tspace = 0: code$ = "": poof$ = " ": K$ = INKEY$
COLOR 7, 0
DrawPlayer
IF totalchips = 9999 THEN totalchips = ChipCount
chipleft = totalchips
Inventory
END SUB
SUB NextLevel
CLS
COLOR 15
CenterPrint "You win!", 13
SLEEP
LoadBoard LevelNum + 1
END SUB
SUB Quit (msg AS STRING)
CLS
COLOR 12, 0
CenterPrint msg, 13
END
END SUB
SUB ReverseScan (find AS STRING)
I = 0: SR = Row + ROffset: SC = Column + COffset
R = SR: C = SC
WHILE I < 24 * 80
I = I + 1
C = C - 1: IF C = 0 THEN C = 80
IF C = SC THEN R = R - 1
IF R = 0 THEN R = 24
IF MID$(Board(R), C, 1) = find$ THEN ROffset = 0: Row = R: COffset = 0: Column = C: EXIT SUB
WEND
END SUB
SUB SetDir (K AS STRING)
SELECT CASE ASC(RIGHT$(K$, 1))
CASE LEFTARROW: IF Column > 1 THEN COffset = -1
CASE UPARROW: IF Row > 1 THEN ROffset = -1
CASE RIGHTARROW: IF Column < 80 THEN COffset = 1
CASE DOWNARROW: IF Row < 24 THEN ROffset = 1
CASE ELSE:
END SELECT
END SUB
SUB SwapTiles (char1 AS STRING, char2 AS STRING)
DIM I AS INTEGER, J AS INTEGER
FOR I = 1 TO 24
FOR J = 1 TO 80
IF MID$(Board(I), J, 1) = char1 THEN
MID$(Board(I), J, 1) = char2
DrawPoint I, J
ELSEIF MID$(Board(I), J, 1) = char2 THEN
MID$(Board(I), J, 1) = char1
DrawPoint I, J
END IF
NEXT J
NEXT I
END SUB
FUNCTION WaitKey$
DO: K$ = INKEY$: LOOP WHILE K$ = "": WaitKey = K$
END FUNCTION
5Hastily-made example
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
x x
x x
x x
x x
x x
x x
x x
x x
x x
x x
x x
x xxxxx S x
x xQqQx SES x
x xq qx S x
x xxxxxxxPPPxxx x
x x. B x
x xxxxxxxpppxxx x
x x b x x
x xxxxx x
x x
x x
x x
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
. Player start spot
Space
x Wall
c Chip
S Chip socket (can only pass if you have all the required chips)
E Exit
F Flippers
W Water
G Green wall
g Green space
b Green button (switches green walls/floors and chips/bombs)
P Purple wall
p Purple space
B Purple button (switches purple walls/floors)
i Invisible wall
I Invisible wall (becomes visible when you touch it)
R Revealed invisible wall (don't use)
/ Fake blue space
? Fake blue wall
1 Yellow key
! Yellow lock
2 Green key (can be reused)
@ Green lock
3 Blue key
# Blue lock
4 Red key
$ Red lock
o Popup block (can only pass once)
t Blue teleporter - teleports player into/out of T-Space, where he can walk through *anything*
T Green teleporter - teleports player to next teleporter, found using reverse scanning
y Yellow teleporter - similar to green, but requires a Teleporter Key
Y Red teleporter - teleports player to the next teleporter in the direction you enter
k Teleporter key
C Block
d Dirt (cleared by player)
w Water droplets
D Switches water with droplets
~ Ice
v Force floor down
^ Force floor up
< Force floor left
> Force floor right
f Force field (only blocks in tspace)
* Bomb (detonated by a block)
a Ashes (cleared by a block)
q Green toggle bomb
Q Green toggle chip
` Ice boots
& Fire
7 Fire boots
, Sucker boots
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment