This is a QBASIC program, which I wrote when I was eighteen - before I started studying programming formally at university. It's a sort of platform game, only there's nobody to shoot at except the wall and powerups for your gun are totally useless (except the first one). Still, it shows what my programming was like when I was eighteen, which is its historical interest.
Assuming you have a QBASIC interpreter in the first place, don't try running this straight under Windows on a modern computer. Use a DOS emulator such as DOSBOX from http://dosbox.sourceforge.net/ instead, and set the number of CPU cycles per second to something like 5376. Set it too high (or without using an emulator) and your man will only be able to jump straight up and down (i.e. no jumping over things) which will make the very first room impossible. Set it too low, and the whole thing will be in slow motion. You'll want to set it just right, and on my computer it's optimised for 5376 cycles per second. YMMV.
REM Display Instructions
CLEAR : SCREEN 12: CLS : RANDOMIZE TIMER
FOR x = 1 TO 7
COLOR x: PRINT "INSTRUCTIONS"
NEXT x
PRINT ""
PRINT "*** KEYS ***"
PRINT "* Arrow keys (except down) to move, space to fire, q to quit."
PRINT ""
PRINT "*** PLEASE DON'T ***"
PRINT "* Do not hold down more than one key at a time. If you do, your actions may"
PRINT " be misinterpreted."
PRINT ""
PRINT "*** GAME ELEMENTS ***"
PRINT "* Just walk over objects to pick them up."
PRINT "* Watch for messages in the top left corner."
PRINT "* Shoot wall switches and stand on platform switches. Switches can be"
PRINT " recognised by their colour."
PRINT ""
REM Prompt To Continue
PRINT "Continue?"
COLOR 0: INPUT cont$
CLS
REM Define keys
up$ = CHR$(0) + CHR$(72)
lft$ = CHR$(0) + CHR$(75)
rght$ = CHR$(0) + CHR$(77)
fire$ = " ": quit$ = "q"
REM Define constants
CONST hmov = 10
CONST bspacing = 10
CONST mesgstay = 100
CONST mesgclr = 6
CONST roomclr = 7: CONST manclr = 6
CONST objclr = 4: CONST bulletclr = 10
CONST switchwclr = 5: CONST switchpclr = 3
REM Define Initial Environment Variables
room = 1
hposback = 50
movedirback = hmov
vmovinit = 20
REM Define Environment Dimensions
pit = 481: cheatpit = 1000
leftside = 10: rightside = 590
rooms = 4: plats = 6
REM Define Other Variables
gravity = 2.3: accelgainfreq = 3
manfreq = 3: gunfreq = 1
manheight = 20: gunheight = 10
REM Define arrays
DIM wall(rooms, plats)
DIM platr(rooms, plats): DIM platg(rooms, plats)
DIM switchr(rooms, plats - 1): DIM switchg(rooms, plats - 1)
DIM onr(rooms, plats - 1): DIM ong(rooms, plats - 1)
REM Define room 1 platforms
platr(1, 1) = 200: platg(1, 1) = 400
platr(1, 2) = 150: platg(1, 2) = 350
platr(1, 3) = 200: platg(1, 3) = 300
platr(1, 4) = 180: platg(1, 4) = 375
platr(1, 5) = 150: platg(1, 5) = 481
platr(1, 6) = 320: platg(1, 6) = 330
wall(1, 1) = 75: wall(1, 2) = 175: wall(1, 3) = 305
wall(1, 4) = 355: wall(1, 5) = 455: wall(1, 6) = rightside + 10
REM Define room 2 platforms
platr(2, 1) = 225: platg(2, 1) = 330
platr(2, 2) = 170: platg(2, 2) = 300
platr(2, 3) = 120: platg(2, 3) = 481
platr(2, 4) = 201: platg(2, 4) = 260
platr(2, 5) = 201: platg(2, 5) = 481
platr(2, 6) = 201: platg(2, 6) = 300
wall(2, 1) = 105: wall(2, 2) = 205: wall(2, 3) = 305
wall(2, 4) = 405: wall(2, 5) = 505: wall(2, 6) = rightside + 10
REM Define room 3 platforms
platr(3, 1) = 200: platg(3, 1) = 300
platr(3, 2) = 200: platg(3, 2) = 300
platr(3, 3) = 250: platg(3, 3) = 260
platr(3, 4) = 250: platg(3, 4) = 260
platr(3, 5) = 150: platg(3, 5) = 260
platr(3, 6) = 50: platg(3, 6) = 180
wall(3, 1) = 105: wall(3, 2) = 205: wall(3, 3) = 305
wall(3, 4) = 455: wall(3, 5) = 555: wall(3, 6) = rightside + 10
REM Define room 4 platforms
platr(4, 1) = 50: platg(4, 1) = 180
platr(4, 2) = 75: platg(4, 2) = 200
platr(4, 3) = 75: platg(4, 3) = 200
platr(4, 4) = 75: platg(4, 4) = 200
platr(4, 5) = 75: platg(4, 5) = 200
platr(4, 6) = 75: platg(4, 6) = 200
wall(4, 1) = 105: wall(4, 2) = 205: wall(4, 3) = 305
wall(4, 4) = 405: wall(4, 5) = 505: wall(4, 6) = rightside + 10
REM Define visible switches
switchr(1, 3) = 1: switchp(1, 6) = 1
switchr(2, 2) = 1: switchg(2, 1) = 1
switchr(3, 2) = 1: switchg(3, 2) = 1: switchp(3, 5) = 1
switchr(4, 1) = 1: switchg(4, 1) = 1
REM Define Guns
DIM gun(rooms, plats)
gun(1, 3) = 1
gun(2, 4) = 1
gun(3, 2) = 1
gun(3, 6) = 1
REM Define variables reset on death
5 hpos = hposback: GOSUB 10
vpos = ground
vmov = vmovinit
movedir = movedirback
REM Start Main cycle
DO UNTIL action$ = quit$
REM [Main cycle] Record cycle number as measure of time
time = time + 1
IF time = 1000000 THEN
time = 0
lostcount = 1
END IF
REM [Main cycle] Print number lives lost
LOCATE 1, 1
COLOR mesgclr
PRINT "LIVES LOST ="; deaths
REM [Main cycle] Display Messages
IF mesgtime > 0 THEN LOCATE 2, 1
PRINT message$
IF (time - mesgtime) MOD 1000000 = mesgstay THEN
mesgtime = 0
CLS
END IF
REM [Main cycle] Draw platforms
IF platmov = 1 THEN CLS
platmov = 0
FOR x = 1 TO plats
IF switchp(room, x) = 1 THEN
COLOR switchpclr
ELSE
COLOR roomclr
END IF
LINE (wall(room, x - 1), platg(room, x))-(wall(room, x), platg(room, x))
LINE (wall(room, x - 1), platr(room, x))-(wall(room, x), platr(room, x))
NEXT x
REM [Main cycle] Draw walls
FOR x = 1 TO plats - 1
IF switchg(room, x) = 1 THEN
COLOR switchwclr
ELSE
COLOR roomclr
END IF
LINE (wall(room, x), platg(room, x))-(wall(room, x), platg(room, x + 1))
IF switchr(room, x) = 1 THEN
COLOR switchwclr
ELSE
COLOR roomclr
END IF
LINE (wall(room, x), platr(room, x))-(wall(room, x), platr(room, x + 1))
NEXT x
REM [Main cycle] Detect keypress
action$ = INKEY$
REM [Main cycle] Horizontal movement and room entry
IF time / manfreq = INT(time / manfreq) THEN
IF action$ = lft$ THEN
hpos = hpos - hmov: movedir = -hmov
ELSEIF action$ = rght$ THEN
hpos = hpos + hmov: movedir = hmov
ELSEIF action$ = "" THEN
IF prevaction$ = lft$ THEN
hpos = hpos - hmov: movedir = -hmov
ELSEIF prevaction$ = rght$ THEN
hpos = hpos + hmov: movedir = hmov
END IF
END IF
END IF
IF hpos < leftside THEN
room = room - 1
hpos = rightside
platmov = 1
ELSEIF hpos > rightside THEN
room = room + 1
hpos = leftside
platmov = 1
END IF
IF room = 0 THEN
room = 1
hpos = leftside
platmov = 0
ELSEIF room = rooms + 1 THEN
COLOR mesgclr
IF lostcount = 1 THEN
PRINT "You made it to the end, but I lost count of how long you took. Hit Enter."
ELSEIF lostcount = 0 THEN
PRINT "You have got all the way to the end in"; time; "program cycles. Hit Enter!"
INPUT cont$
END
END IF
END IF
GOSUB 10
REM [Main cycle] Narrow passage detection
IF ground - roof <= gravity + ABS(vmov) THEN
IF vpos <= ground AND vpos + gravity - vmov >= ground THEN
vpos = ground
ELSEIF vpos >= roof AND vpos + gravity + vmov <= roof THEN
vpos = ground
END IF
END IF
REM [Main cycle] Prevent walking through walls
IF (prevground > ground AND vpos > ground) OR (prevroof < roof AND vpos - manheight < roof) THEN
hpos = hpos - movedir
GOSUB 10
END IF
REM [Main cycle] Check Platform Switches
onp(room, plat) = 1
IF vpos = ground THEN
IF onp(3, 5) = 1 THEN
IF manheight < 20 THEN
manheight = manheight + .5
CLS
END IF
IF gunheight < 10 THEN
gunheight = gunheight + .25
END IF
END IF
IF onp(1, 6) = 1 THEN
IF wall(1, 5) <> 405 THEN
wall(1, 5) = 405
wall(1, 4) = 305
wall(1, 3) = 205
platmov = 1
mesgtime = time
message$ = "Just to show I can move walls, too..."
END IF
END IF
END IF
onp(room, plat) = 0
REM [Main cycle] Jumping
IF action$ = up$ THEN
jumpseq = 1
END IF
IF jumpseq = 1 AND prevjumpseq = 0 THEN
vpos = vpos - vmov
END IF
REM [Main cycle] Falling
IF vpos < ground AND prevvpos = prevground THEN
IF jumpseq = 0 THEN
vmov = 0
END IF
END IF
IF time / accelgainfreq = INT(time / accelgainfreq) THEN
IF vpos < ground THEN
vmov = vmov - gravity
vpos = vpos - vmov
END IF
END IF
REM [Main cycle] Prevent passing through platforms
IF vpos - manheight < roof THEN
vmov = -ABS(vmov)
vpos = roof + manheight
ELSEIF vpos > ground THEN
vpos = ground
END IF
IF vpos = ground THEN
jumpseq = 0
vmov = vmovinit
END IF
REM [Main cycle] Death from falling in pit
IF ground >= pit AND vpos >= ground THEN
deaths = deaths + 1
mesgtime = time
message$ = "You fell and died..."
GOTO 5
END IF
REM [Main cycle] Erase man (body, leg, leg, arms, face, head)
COLOR 0
LINE (prevhpos, prevvpos - gunheight)-(prevhpos, prevvpos - manheight)
LINE (prevhpos, prevvpos - gunheight)-(prevhpos - 5, prevvpos)
LINE (prevhpos, prevvpos - gunheight)-(prevhpos + 5, prevvpos)
LINE (prevhpos - 5, prevvpos - gunheight)-(prevhpos + 5, prevvpos - gunheight)
LINE (prevhpos + 5 * SGN(prevmovedir), prevvpos - manheight)-(prevhpos, prevvpos - gunheight)
LINE (prevhpos + 5 * SGN(prevmovedir), prevvpos - manheight)-(prevhpos, prevvpos - manheight)
REM [Main cycle] Draw man (body, leg, leg, arms, face, head)
COLOR manclr
LINE (hpos, vpos - gunheight)-(hpos, vpos - manheight)
LINE (hpos, vpos - gunheight)-(hpos - 5, vpos)
LINE (hpos, vpos - gunheight)-(hpos + 5, vpos)
LINE (hpos - 5, vpos - gunheight)-(hpos + 5, vpos - gunheight)
LINE (hpos + 5 * SGN(movedir), vpos - manheight)-(hpos, vpos - gunheight)
LINE (hpos + 5 * SGN(movedir), vpos - manheight)-(hpos, vpos - manheight)
REM [Main cycle] Draw Objects
FOR x = 1 TO plats
IF gun(room, x) = 1 THEN
COLOR objclr
objhpos = (wall(room, x) - wall(room, x - 1)) / 2 + wall(room, x - 1)
objvpos = platg(room, x)
LINE (objhpos - 5, objvpos - 10)-(objhpos + 5, objvpos - 10)
LINE (objhpos - 5, objvpos - 10)-(objhpos - 5, objvpos - 5)
END IF
NEXT x
REM [Main cycle] Pick Up Objects
IF gun(room, plat) = 1 AND vpos = ground THEN
objhpos = (wall(room, plat) - wall(room, plat - 1)) / 2 + wall(room, plat - 1)
IF ABS(hpos - objhpos) < 10 THEN
gun(room, plat) = 0
radius = radius + 1
mesgtime = time
message$ = "MORE GUN POWER!!"
CLS
END IF
END IF
REM [Main cycle] Initiate shooting
IF action$ = fire$ AND prevshootseq = 0 AND radius > 0 THEN
shootseq = 1
shootdir = movedir
bvpos = vpos - gunheight
firehpos = hpos
END IF
IF shootseq = 1 THEN
REM [Main cycle] [Shooting] Begin moving bullet
IF time / gunfreq = INT(time / gunfreq) THEN
fire = fire + 1
bhpos = firehpos + SGN(shootdir) * fire * bspacing + 10
REM [Main cycle] [Shooting] [Moving bullet] Find ground and roof where bullet is
FOR x = 1 TO plats
IF bhpos > wall(room, x - 1) AND bhpos < wall(room, x) THEN
bplat = x
bground = platg(room, bplat)
broof = platr(room, bplat)
END IF
NEXT x
REM [Main cycle] [Shooting] [Moving bullet] Detect Bullet Hitting Lower Wall (and activate switch)
IF bvpos > bground THEN
shootseq = 0
IF shootdir > 0 THEN
ong(room, bplat - 1) = 1
ELSEIF shootdir < 0 THEN
ong(room, bplat) = 1
END IF
IF ABS(hpos - 300) <> 290 THEN
IF ong(2, 1) = 1 THEN
platr(2, 6) = 200: platr(3, 1) = 200
mesgtime = time: message$ = "Something moved..."
END IF
IF ong(3, 2) = 1 THEN
platr(2, 6) = 260: platr(3, 1) = 260
mesgtime = time: message$ = "The roof lowered..."
END IF
IF ong(4, 1) = 1 THEN
FOR x = 3 TO 6
platg(4, x) = RND * 750
IF platg(4, x) < platr(4, x) THEN x = x - 1
NEXT x
mesgtime = time: message$ = "Watch this!"
END IF
END IF
IF shootdir > 0 THEN ong(room, bplat - 1) = 0
IF shootdir < 0 THEN ong(room, bplat) = 0
platmov = 1
END IF
REM [Main cycle] [Shooting] [Moving bullet] Detect Bullet Hitting Upper Wall (and activate switch)
IF bvpos < broof THEN
shootseq = 0
IF shootdir > 0 THEN onr(room, bplat - 1) = 1
IF shootdir < 0 THEN onr(room, bplat) = 1
IF ABS(hpos - 300) <> 290 THEN
IF onr(1, 3) = 1 THEN
platr(1, 6) = 225
mesgtime = time: message$ = "The door opened..."
END IF
IF onr(2, 2) = 1 THEN
platr(2, 5) = 130
platr(2, 6) = 290: platr(3, 1) = 290
mesgtime = time: message$ = "You probably thought this would let you through..."
END IF
IF onr(3, 2) = 1 THEN
mesgtime = time: message$ = "YOU HAVE BEEN TRANSFORMED INTO A RAT!"
manheight = 2: gunheight = 1
END IF
IF onr(4, 1) = 1 THEN
FOR x = 3 TO 6
platr(4, x) = RND * 450
IF platr(4, x) > platg(4, x) THEN x = x - 1
mesgtime = time: message$ = "Watch this!"
NEXT x
END IF
END IF
IF shootdir > 0 THEN onr(room, bplat - 1) = 0
IF shootdir < 0 THEN onr(room, bplat) = 0
platmov = 1
END IF
REM [Main cycle] [Shooting] [Moving bullet] Check bullet still moving
IF bhpos < 0 THEN shootseq = 0
IF bhpos > 600 THEN shootseq = 0
IF prevroom <> room THEN shootseq = 0
IF shootseq = 0 THEN fire = 0
REM [Main cycle] [Shooting] [Moving bullet] Draw bullet
FOR x = 1 TO radius
CIRCLE (prevbhpos, bvpos), x, 0
NEXT x
IF shootseq = 1 THEN
FOR x = 1 TO radius
CIRCLE (bhpos, bvpos), x, bulletclr
NEXT x
END IF
REM [Main cycle] Finish moving bullet and shooting
END IF
END IF
REM [Main cycle] Store variables redefined each cycle
prevhpos = hpos: prevvpos = vpos
prevground = ground: prevroof = roof
prevshootseq = shootseq: prevjumpseq = jumpseq
prevmovedir = movedir
prevbhpos = bhpos
prevroom = room
IF action$ <> "" THEN prevaction$ = action$
IF time / manfreq = INT(time / manfreq) THEN prevaction$ = ""
IF vpos = ground THEN IF ground < pit THEN hposback = hpos: movedirback = movedir
REM Finish Main Cycle
LOOP
END
10 REM Find current platform - GOSUB WHEN horizontal position redefined
FOR x = 1 TO plats
IF hpos > wall(room, x - 1) THEN
IF hpos < wall(room, x) THEN
ground = platg(room, x): roof = platr(room, x)
plat = x
END IF
END IF
NEXT x
RETURN