'===========================================================================
' Subject: QB Shooter                         Date: 03-16-03 (  :  )       
'  Author: Keith Jennings                     Code: QB, PDS                
'  Origin: sturmges@aol.com                 Packet: GAMES.ABC
'===========================================================================
REM abash.bas
REM Keith Jennings

REM controls :-
REM left CTRL - move left
REM right ALT - move right
REM right SHIFT - fire
REM F key - cheat !
REM Q key - quit

TYPE alien
x AS INTEGER
y AS INTEGER
mx AS INTEGER
my AS INTEGER
mxc AS INTEGER
myc AS INTEGER
mr AS INTEGER
fired AS INTEGER
angle AS INTEGER
typ AS INTEGER    ' -1 = destroyed
xc AS INTEGER
yc AS INTEGER
r AS INTEGER
point1 AS INTEGER ' pointer to angles
point2 AS INTEGER ' pointer to times
point3 AS INTEGER ' pointer to graphics()
speed AS INTEGER
count AS INTEGER
dir AS INTEGER    ' left/right
xp AS INTEGER
yp AS INTEGER
temp AS INTEGER
ftime AS INTEGER      ' flight time
setup AS INTEGER
clockw AS INTEGER     '1= cwise 2= a cwise
health AS INTEGER
mspeed AS INTEGER
END TYPE

TYPE explode
x AS INTEGER
y AS INTEGER
pointer AS INTEGER
END TYPE

TYPE ship
x AS INTEGER
y AS INTEGER
END TYPE

TYPE missile
x AS INTEGER
y AS INTEGER
END TYPE

COMMON player AS ship

SCREEN 9
WIDTH 80, 43
DEFINT A-Z
DEF SEG = 0
POKE &H417, 0: POKE &H418, 0
CLS

CONST left = 1, right = 2, north = 3, south = 4
CONST llimit = 12, rlimit = 616
CONST normal = 0, expand = 1, swoop = 2, home = 3
CONST ulimit = 0, lrlimit = 326, cheat = 1

DIM SHARED aliens(40) AS alien, angles(80), choices(16), times!(40)
DIM SHARED expl(40) AS explode, shots(3) AS missile, graphics(800), 
pmax(8)
DIM SHARED pow(100), mbase(100), cmisl(100), pmisl(100), cas!(359), 
sas!(359)

REM set up graphics
FOR j = 0 TO 799 STEP 100
FOR y = 0 TO 11
FOR x = 0 TO 11
READ co
PSET (x, y), co
NEXT x, y
GET (0, 0)-(11, 11), graphics(j)
NEXT j
REM explosion
FOR y = 0 TO 11
FOR x = 0 TO 11
READ co
PSET (x, y), co
NEXT x, y
GET (0, 0)-(11, 11), pow(0)
PUT (0, 0), pow, XOR
REM pmisl(),cmisl()
FOR l = 1 TO 2
FOR y = 0 TO 10
FOR x = 0 TO 7
READ co
PSET (x, y), co
NEXT x, y
IF l = 1 THEN GET (0, 0)-(7, 10), pmisl(0)
IF l = 2 THEN GET (0, 0)-(7, 10), cmisl(0)
NEXT l
PUT (0, 0), cmisl(0), XOR
REM mbase()
FOR y = 0 TO 6
FOR x = 0 TO 11
READ co
PSET (x, y), co
NEXT x, y
GET (0, 0)-(11, 6), mbase(0)
FOR j = 1 TO 8: READ pmax(j): NEXT j
FOR j = 1 TO 8: choices(j) = j * 10: NEXT j
FOR j = 9 TO 16
choices(j) = 280 + j * 10
NEXT j
FOR j = 0 TO 359
cas!(j) = COS(j * 3.1415 / 180): sas!(j) = SIN(j * 3.1415 / 180)
NEXT j
h& = 0
DO
CLS
nPerRow = 2: height = 120: lives = 5: player.x = 200: player.y = 307: 
fq! = .95: als = 0: new& = 10000: upcount = 0
PUT (player.x, player.y), mbase, XOR
lvx = 12
FOR j = 1 TO lives
PUT (lvx, 343), mbase, XOR
lvx = lvx + 14
NEXT j
lvx = lvx - 14: s& = 0: acc = 5
LINE (llimit + 2, 314)-(rlimit + 4, 314), 2
COLOR 2
LOCATE 42, 3: PRINT "Score :"; STR$(s&) + STRING$(8 - LEN(STR$(s&)), 
32); "High :"; STR$(h&);
DO
max = nPerRow * 4
GOSUB init
RANDOMIZE TIMER: s = CINT(RND * 30): t! = TIMER: expandF = 0: hits = 0
s2 = CINT(RND * 5): t2! = TIMER: count = 0: tcount = INT(max / 3): form 
= 0: t3! = TIMER
mcount = 0: nshots = 0: pass1 = 0: pass2 = 0: scol = 1: ecol = nPerRow: 
newDir = -1
REM main
DO
a$ = UCASE$(INKEY$)
status = PEEK(&H418)
kbd = PEEK(&H417)
IF (kbd AND 4) AND player.x > llimit + 8 THEN
PUT (player.x, player.y), mbase, XOR
player.x = player.x - 8
PUT (player.x, player.y), mbase, XOR
END IF
IF (kbd AND 8) AND player.x < rlimit - 8 THEN
PUT (player.x, player.y), mbase, XOR
player.x = player.x + 8
PUT (player.x, player.y), mbase, XOR
END IF
FOR aliens = scol TO ecol
IF (aliens(aliens).typ <= normal AND expandF < 2) OR 
(aliens(aliens).typ > expand AND expandF < 2) THEN
IF aliens(aliens).typ = normal THEN PUT (aliens(aliens).x, 
aliens(aliens).y), graphics(aliens(aliens).point3 * 100 - 100), XOR
SELECT CASE aliens(aliens).dir
CASE right
aliens(aliens).x = aliens(aliens).x + 2
CASE left
aliens(aliens).x = aliens(aliens).x - 2
END SELECT
IF aliens(aliens).typ = normal OR form = 1 THEN
REM check bounds
IF aliens(aliens).x = llimit2 THEN
aliens(aliens).dir = right: newDir = right
ELSEIF aliens(aliens).x = rlimit2 THEN
aliens(aliens).dir = left: newDir = left
END IF
REM show
IF aliens(aliens).typ = normal THEN
IF aliens(aliens).point3 = pmax(aliens(aliens).point3) THEN 
aliens(aliens).point3 = aliens(aliens).point3 - 1 ELSE aliens(aliens).point3 = 
aliens(aliens).point3 + 1
PUT (aliens(aliens).x, aliens(aliens).y), 
graphics(aliens(aliens).point3 * 100 - 100), XOR
END IF
END IF
END IF
NEXT aliens
IF newDir > -1 THEN
FOR j = 1 TO ecol
aliens(j).dir = newDir
NEXT j
IF ecol = nPerRow * 4 THEN newDir = -1
END IF
REM break formation
IF TIMER - t2! >= s2 AND count < tcount THEN
tries = 0
DO
tries = tries + 1: IF tries = 50 THEN EXIT DO
j = CINT(RND * (max - 1) + 1)
LOOP UNTIL aliens(j).typ = normal OR (aliens(j).typ = expand AND 
aliens(j).temp = 0)
IF tries < 50 THEN
count = count + 1
aliens(j).typ = swoop: aliens(j).speed = CINT(RND + 1)
times!(aliens(j).point2) = TIMER: aliens(j).count = 0
aliens(j).ftime = CINT(RND * 5 + 5): aliens(j).r = 0
angles(aliens(j).point1) = choices(CINT(RND * 15 + 1))
aliens(j).xc = aliens(j).x: aliens(j).yc = aliens(j).y
aliens(j).xp = aliens(j).x: aliens(j).yp = aliens(j).y
s2 = CINT(RND * 5): t2! = TIMER
GOSUB normtest
END IF
END IF
REM diving invader
FOR rep = 1 TO 7
DO
als = als + 1
IF als > max THEN GOTO skipover
LOOP UNTIL aliens(als).typ = swoop OR aliens(als).typ = home
IF aliens(als).typ = swoop AND TIMER - times!(aliens(als).point2) <= 
aliens(als).ftime THEN
aliens(als).count = aliens(als).count + 1
IF aliens(als).count MOD aliens(als).speed = 0 THEN    ' ready to move
aliens(als).count = 0
aliens(als).r = aliens(als).r + 2
PUT (aliens(als).xp, aliens(als).yp), graphics(aliens(als).point3 * 100 
- 100), XOR
SELECT CASE angles(aliens(als).point1)
CASE IS > 270
tempx! = aliens(als).xc - aliens(als).r * cas!(90 - 
(angles(aliens(als).point1) MOD 360))
tempy! = aliens(als).yc + aliens(als).r * sas!(90 - 
(angles(aliens(als).point1) MOD 360))
aliens(als).xp = tempx!
aliens(als).yp = tempy!
CASE IS < 90
tempx! = aliens(als).xc + aliens(als).r * 
cas!(angles(aliens(als).point1))
tempy! = aliens(als).yc + aliens(als).r * 
sas!(angles(aliens(als).point1))
aliens(als).xp = tempx!
aliens(als).yp = tempy!
END SELECT
IF aliens(als).xp > rlimit OR aliens(als).xp < llimit THEN
IF aliens(als).xp > rlimit THEN aliens(als).xp = llimit
IF aliens(als).xp < llimit THEN aliens(als).xp = rlimit
aliens(als).xc = aliens(als).xp: aliens(als).yc = aliens(als).yp: 
aliens(als).r = 0
END IF
IF aliens(als).yp > lrlimit THEN
aliens(als).yp = ulimit: aliens(als).xc = aliens(als).xp
aliens(als).yc = aliens(als).yp: aliens(als).r = 0
END IF
hitF = 0: j = als: GOSUB hit1
IF hitF = 0 THEN
IF aliens(als).point3 = pmax(aliens(als).point3) THEN 
aliens(als).point3 = aliens(als).point3 - 1 ELSE aliens(als).point3 = aliens(als).point3 
+ 1
PUT (aliens(als).xp, aliens(als).yp), graphics(aliens(als).point3 * 100 
- 100), XOR
IF aliens(als).yp < height AND expandF < 2 THEN aliens(als).typ = home
END IF
END IF
END IF
REM looping invader
IF aliens(als).typ = swoop AND aliens(als).setup = 0 AND TIMER - 
times!(aliens(als).point2) > aliens(als).ftime THEN
SELECT CASE angles(aliens(als).point1)
CASE IS < 90
aliens(als).clockw = 1
aliens(als).r = CINT(RND * 70 + 10)
aliens(als).xc = aliens(als).xp - aliens(als).r * cas!((90 - 
angles(aliens(als).point1)))
aliens(als).yc = aliens(als).yp + aliens(als).r * sas!((90 - 
angles(aliens(als).point1)))
angles(aliens(als).point1) = 360 - (90 - angles(aliens(als).point1))
start = angles(aliens(als).point1)
turns = CINT(RND + 1)
min = 370 - start: maxi = 440 - start
add = CINT(RND * (maxi - min)) + min
angles(aliens(als).point1 + 1) = start + turns * 360 + add
CASE IS > 270
aliens(als).clockw = 2
aliens(als).r = CINT(RND * 70 + 10)
aliens(als).xc = aliens(als).xp + aliens(als).r * 
cas!(angles(aliens(als).point1) MOD 360)
aliens(als).yc = aliens(als).yp + aliens(als).r * 
sas!(angles(aliens(als).point1) MOD 360)
angles(aliens(als).point1) = (angles(aliens(als).point1) MOD 360) - 180
start = angles(aliens(als).point1)
turns = CINT(RND + 1)
min = -190 - start: maxi = -260 - start
add = CINT(RND * (maxi - min)) + min
angles(aliens(als).point1 + 1) = start - turns * 360 + add
END SELECT
aliens(als).setup = 1: aliens(als).count = 0
END IF
REM circular pattern
IF aliens(als).typ = swoop AND aliens(als).setup = 1 THEN
aliens(als).count = aliens(als).count + 1
IF aliens(als).count MOD aliens(als).speed = 0 THEN
PUT (aliens(als).xp, aliens(als).yp), graphics(aliens(als).point3 * 100 
- 100), XOR: aliens(als).count = 0
IF aliens(als).clockw = 1 THEN angles(aliens(als).point1) = 
angles(aliens(als).point1) + 2 ELSE angles(aliens(als).point1) = 
angles(aliens(als).point1) - 2
ang = angles(aliens(als).point1): ang = ang MOD 360
IF ang < 0 THEN ang = ang + 360
aliens(als).xp = aliens(als).xc + aliens(als).r * cas!(ang)
aliens(als).yp = aliens(als).yc + aliens(als).r * sas!(ang)
hor = aliens(als).xp - aliens(als).xc: ver = aliens(als).yp - 
aliens(als).yc
IF hor < 0 THEN hor = hor * -1: IF ver < 0 THEN ver = ver * -1
IF aliens(als).xp < llimit THEN aliens(als).xp = rlimit - 8: 
aliens(als).xc = rlimit + hor - 8
IF aliens(als).xp > rlimit THEN aliens(als).xp = llimit + 8: 
aliens(als).xc = llimit - hor + 8
IF aliens(als).yp < ulimit THEN aliens(als).yp = lrlimit - 8: 
aliens(als).yc = lrlimit + ver - 8
IF aliens(als).yp > lrlimit THEN aliens(als).yp = ulimit + 8: 
aliens(als).yc = ulimit - ver + 8
hitF = 0: j = als: GOSUB hit1
IF hitF = 0 THEN
IF aliens(als).point3 = pmax(aliens(als).point3) THEN 
aliens(als).point3 = aliens(als).point3 - 1 ELSE aliens(als).point3 = aliens(als).point3 
+ 1
PUT (aliens(als).xp, aliens(als).yp), graphics(aliens(als).point3 * 100 
- 100), XOR
IF aliens(als).yp < height AND expandF < 2 THEN aliens(als).typ = home: 
aliens(als).setup = 0
IF (aliens(als).clockw = 1 AND angles(aliens(als).point1) >= 
angles(aliens(als).point1 + 1)) OR (aliens(als).clockw = 2 AND 
angles(aliens(als).point1) <= angles(aliens(als).point1 + 1)) THEN
IF aliens(als).clockw = 2 THEN angles(aliens(als).point1) = 
(angles(aliens(als).point1) MOD 360) + 270
aliens(als).setup = 0: aliens(als).count = 0: aliens(als).speed = 
CINT(RND + 1)
times!(aliens(als).point2) = TIMER
aliens(als).ftime = CINT(RND * 5) + 5: aliens(als).r = 0
aliens(als).xc = aliens(als).xp: aliens(als).yc = aliens(als).yp
END IF
END IF
END IF
END IF
REM rejoin battle group
IF aliens(als).typ = home THEN
IF aliens(als).xp = aliens(als).x AND aliens(als).yp = aliens(als).y 
AND expandF < 2 THEN aliens(als).typ = normal: count = count - 1: s2 = 
CINT(RND * 5): t2! = TIMER: form = 0
IF aliens(als).xp = aliens(als).x AND aliens(als).yp = aliens(als).y 
AND expandF = 2 THEN
PUT (aliens(als).xp, aliens(als).yp), graphics(aliens(als).point3 * 100 
- 100), XOR
IF aliens(als).point3 = pmax(aliens(als).point3) THEN 
aliens(als).point3 = aliens(als).point3 - 1 ELSE aliens(als).point3 = aliens(als).point3 
+ 1
PUT (aliens(als).xp, aliens(als).yp), graphics(aliens(als).point3 * 100 
- 100), XOR
END IF
IF aliens(als).xp <> aliens(als).x OR aliens(als).yp <> aliens(als).y 
THEN
PUT (aliens(als).xp, aliens(als).yp), graphics(aliens(als).point3 * 100 
- 100), XOR
IF aliens(als).xp < aliens(als).x THEN aliens(als).xp = aliens(als).xp 
+ 1
IF aliens(als).xp > aliens(als).x THEN aliens(als).xp = aliens(als).xp 
- 1
IF aliens(als).yp < aliens(als).y THEN aliens(als).yp = aliens(als).yp 
+ 1
IF aliens(als).xp < llimit THEN aliens(als).xp = rlimit
IF aliens(als).xp > rlimit THEN aliens(als).xp = llimit
IF aliens(als).point3 = pmax(aliens(als).point3) THEN 
aliens(als).point3 = aliens(als).point3 - 1 ELSE aliens(als).point3 = aliens(als).point3 
+ 1
PUT (aliens(als).xp, aliens(als).yp), graphics(aliens(als).point3 * 100 
- 100), XOR
IF aliens(als).xp = aliens(als).x AND aliens(als).yp = aliens(als).y 
AND expandF < 2 THEN aliens(als).typ = normal: count = count - 1: s2 = 
CINT(RND * 5): t2! = TIMER: form = 0
END IF
END IF
NEXT rep
skipover:
IF als > max THEN als = 0
REM expansion
xdiv = (nPerRow / 2) * 12 + xstart
FOR aliens = scol TO ecol
IF aliens(aliens).typ = expand THEN
IF aliens(aliens).temp = 0 THEN PUT (aliens(aliens).x, 
aliens(aliens).y), graphics(aliens(aliens).point3 * 100 - 100), XOR
IF aliens(aliens).x >= xdiv THEN angle = 75 ELSE angle = 115
SELECT CASE aliens(aliens).dir
CASE south
aliens(aliens).r = aliens(aliens).r + 1
aliens(aliens).x = aliens(aliens).xc + aliens(aliens).r * cas!(angle)
aliens(aliens).y = aliens(aliens).yc + aliens(aliens).r * sas!(angle)
CASE north
aliens(aliens).r = aliens(aliens).r - 1
aliens(aliens).x = aliens(aliens).xc + aliens(aliens).r * cas!(angle)
aliens(aliens).y = aliens(aliens).yc + aliens(aliens).r * sas!(angle)
END SELECT
IF aliens(aliens).r = 0 THEN aliens(aliens).dir = south
IF aliens(aliens).r = 80 THEN aliens(aliens).dir = north
IF aliens(aliens).point3 = pmax(aliens(aliens).point3) THEN 
aliens(aliens).point3 = aliens(aliens).point3 - 1 ELSE aliens(aliens).point3 = 
aliens(aliens).point3 + 1
IF aliens(aliens).temp = 0 THEN PUT (aliens(aliens).x, 
aliens(aliens).y), graphics(aliens(aliens).point3 * 100 - 100), XOR
END IF
NEXT aliens
IF expandF = 1 THEN
FOR j = 1 TO max STEP nPerRow
IF aliens(j).x = xstart AND aliens > max THEN EXIT FOR
NEXT j
IF j <= max THEN
FOR j = 1 TO max
IF aliens(j).typ < normal THEN aliens(j).temp = aliens(j).typ
IF aliens(j).typ <= normal THEN
tdir = aliens(j).dir
aliens(j).typ = expand
aliens(j).dir = south
aliens(j).xc = aliens(j).x
aliens(j).yc = aliens(j).y
aliens(j).r = 0
t! = TIMER: s = CINT(RND * 20): expandF = 2
END IF
NEXT j
END IF
END IF
IF TIMER - t! >= s AND expandF = 2 AND aliens > max THEN
FOR j = 1 TO max
IF aliens(j).x = aliens(j).xc AND aliens(j).y = aliens(j).yc AND 
aliens(j).typ = expand THEN
FOR j = 1 TO max
IF aliens(j).temp = 0 AND aliens(j).typ = expand THEN aliens(j).typ = 
normal: aliens(j).dir = tdir
IF aliens(j).temp = -1 THEN aliens(j).typ = aliens(j).temp: 
aliens(j).dir = tdir
NEXT j
expandF = 0: t! = TIMER: s = CINT(RND * 30)
x = xstart: y = height
FOR j = 1 TO max
IF aliens(j).x <> x THEN aliens(j).x = x
IF aliens(j).y <> y THEN aliens(j).y = y
IF aliens(j).typ = swoop THEN aliens(j).dir = tdir
IF aliens(j).typ = home AND aliens(j).xp = aliens(j).x AND aliens(j).yp 
= aliens(j).y THEN aliens(j).typ = normal: aliens(j).dir = tdir: count 
= count - 1: s2 = CINT(RND * 5): t2! = TIMER: form = 0
x = x + 12
IF x > xstart + (nPerRow - 1) * 12 THEN x = xstart: y = y + 12
NEXT j
EXIT FOR
END IF
NEXT j
END IF
REM fire !
FOR j = 1 TO max
IF (aliens(j).fired = 1 AND aliens(j).angle > 0) THEN
PUT (aliens(j).mx, aliens(j).my), cmisl, XOR
aliens(j).mr = aliens(j).mr + aliens(j).mspeed
aliens(j).mx = aliens(j).mxc + aliens(j).mr * cas!(aliens(j).angle)
aliens(j).my = aliens(j).myc + aliens(j).mr * sas!(aliens(j).angle)
IF aliens(j).mx < llimit THEN aliens(j).mx = rlimit: aliens(j).mxc = 
rlimit: aliens(j).myc = aliens(j).my: aliens(j).mr = 0
IF aliens(j).mx > rlimit THEN aliens(j).mx = llimit: aliens(j).mxc = 
llimit: aliens(j).myc = aliens(j).my: aliens(j).mr = 0
IF aliens(j).my <= lrlimit THEN GOSUB hit2
IF aliens(j).my > lrlimit OR lives <= 0 OR hits = max THEN 
aliens(j).fired = 0: mcount = mcount - 1
IF aliens(j).my <= lrlimit AND hits < max AND lives > 0 THEN PUT 
(aliens(j).mx, aliens(j).my), cmisl, XOR
END IF
NEXT j
tries = 0
DO
tries = tries + 1
j = CINT(RND * (max - 1) + 1)
LOOP UNTIL (aliens(j).typ > expand AND aliens(j).xp <> player.x AND 
aliens(j).yp < player.y - 24 AND aliens(j).fired = 0) OR (aliens(j).typ = 
expand AND aliens(j).temp = 0 AND aliens(j).x <> player.x AND 
aliens(j).fired = 0) OR (aliens(j).typ = normal AND aliens(j).fired = 0) OR 
tries = 50
IF RND > fq! AND mcount < 5 AND lives > 0 AND tries < 50 THEN
IF aliens(j).typ <= expand THEN x = aliens(j).x: y = aliens(j).y ELSE x 
= aliens(j).xp: y = aliens(j).yp
hor = x - player.x: ver = player.y - y
IF hor < 0 THEN hor = hor * -1
rand! = RND
WHILE 1 - rand! >= .6
rand! = rand! + RND * rand!
WEND
hor = hor + rand! * acc * 16
IF aliens(j).typ > normal THEN aliens(j).angle = ATN(ver / hor) * 57.3 
ELSE aliens(j).angle = 90
IF player.x < x THEN aliens(j).angle = (90 - aliens(j).angle) + 90
aliens(j).fired = 1: aliens(j).mx = x + 2: aliens(j).my = y + 12
aliens(j).mxc = aliens(j).mx: aliens(j).myc = aliens(j).my: 
aliens(j).mr = 0
PUT (aliens(j).mx, aliens(j).my), cmisl, XOR: mcount = mcount + 1
IF nPerRow > 6 AND RND > 1 - ((max - hits) / max) THEN aliens(j).mspeed 
= 8 ELSE aliens(j).mspeed = 4
END IF
FOR j = 1 TO 3
IF shots(j).x > 0 THEN
PUT (shots(j).x, shots(j).y), pmisl, XOR
shots(j).y = shots(j).y - 4
IF shots(j).y >= ulimit THEN GOSUB hit3
IF shots(j).y < ulimit OR lives = 0 OR hits = max THEN shots(j).x = 0: 
nshots = nshots - 1
IF shots(j).y >= ulimit AND hits < max AND lives > 0 THEN PUT 
(shots(j).x, shots(j).y), pmisl, XOR
END IF
NEXT j
IF (kbd AND 1) AND nshots < 3 AND TIMER - t3! > .5 AND lives > 0 THEN
FOR j = 1 TO 3
IF shots(j).x = 0 THEN
shots(j).x = player.x + 2
shots(j).y = player.y - 12
PUT (shots(j).x, shots(j).y), pmisl, XOR
PLAY "mbmll64o4aco3faa"
EXIT FOR
END IF
NEXT j
nshots = nshots + 1: t3! = TIMER
END IF
IF TIMER - t! >= s AND expandF = 0 AND form = 0 THEN expandF = 1
REM remove explosions
FOR j = 1 TO max
IF (expl(j).pointer > 0 AND TIMER - times!(expl(j).pointer) > 1.5) OR 
hits = max OR lives <= 0 THEN
IF expl(j).pointer > 0 THEN PUT (expl(j).x, expl(j).y), pow, XOR
expl(j).pointer = 0
END IF
NEXT j
scol = ecol + 1: pass1 = pass1 + 1
IF pass1 = 1 THEN ecol = nPerRow * 2
IF pass1 = 2 THEN ecol = nPerRow * 3
IF pass1 = 3 THEN ecol = nPerRow * 4
IF pass1 = 4 THEN scol = 1: ecol = nPerRow: pass1 = 0
IF a$ = "Q" THEN lives = 0
IF a$ = CHR$(70) AND hits < max AND cheat THEN
DO
j = CINT(RND * (max - 1) + 1)
LOOP UNTIL (aliens(j).typ = expand AND aliens(j).temp = 0) OR 
aliens(j).typ = normal OR aliens(j).typ > expand
IF aliens(j).typ = normal OR aliens(j).typ = expand THEN
PUT (aliens(j).x, aliens(j).y), graphics(aliens(j).point3 * 100 - 100), 
XOR
x = aliens(j).x: y = aliens(j).y
ELSE
PUT (aliens(j).xp, aliens(j).yp), graphics(aliens(j).point3 * 100 - 
100), XOR
x = aliens(j).xp: y = aliens(j).yp
END IF
hits = hits + 1: IF aliens(j).typ > expand THEN count = count - 1
point2 = aliens(j).point2
GOSUB explode: SOUND 0, 0: PLAY "mbmll64o2da"
aliens(j).typ = -1: aliens(j).temp = -1
s& = s& + (5 - pmax(aliens(j).point3) / 2) * 100
IF s& >= new& THEN new& = new& + 10000
LOCATE 42, 10: COLOR 2: PRINT STR$(s&);
GOSUB normtest
END IF
IF lives <= 0 OR hits = max THEN pass2 = pass2 + 1
IF upcount > 0 THEN
upcount = upcount - 1
IF upcount = 0 OR lives <= 0 THEN
msgx1 = 256: msgx2 = 391: GOSUB hide
LOCATE 42, 32: PRINT STRING$(18, 32);
GOSUB hide
END IF
END IF
LOOP UNTIL (hits = max OR lives <= 0) AND pass2 = 2
height = height - 24
nPerRow = nPerRow + 2: acc = acc - 1: IF acc < 1 THEN acc = 5
IF height < 24 THEN height = 120
IF nPerRow > 10 THEN nPerRow = 2
IF nPerRow > 4 THEN fq! = .9 ELSE fq! = .95
IF nPerRow = 10 OR nPerRow = 8 THEN fq! = .8
LOOP UNTIL lives <= 0
IF s& > h& THEN LOCATE 42, 24: COLOR 2: PRINT STR$(s&);
LOCATE 18, 35: COLOR 14: PRINT "GAME OVER";
LOCATE 20, 29: IF s& > h& THEN PRINT "You have a high score": h& = s&
LOCATE 22, 35: PRINT "More (Y/N)"
DO
a$ = UCASE$(INKEY$)
LOOP UNTIL a$ = "Y" OR a$ = "N"
LOOP UNTIL a$ = "N"
CLS
END

explode:
FOR k = 1 TO max
IF expl(k).x = 0 THEN
expl(k).x = x: expl(k).y = y
expl(k).pointer = point2
PUT (x, y), pow, XOR
times!(point2) = TIMER
EXIT FOR
END IF
NEXT k
RETURN

normtest:
form = 0
FOR ja = 1 TO max
IF aliens(ja).typ = normal OR (aliens(ja).typ = expand AND 
aliens(ja).temp = 0) THEN EXIT FOR
NEXT ja
IF ja > max THEN form = 1
RETURN

REM ship hits player
hit1:
IF ABS(aliens(j).xp - player.x) <= 11 AND ((aliens(j).yp > player.y AND 
aliens(j).yp - player.y <= 6) OR aliens(j).yp <= player.y AND player.y 
- aliens(j).yp <= 11) THEN
hits = hits + 1: count = count - 1: lives = lives - 1
IF lvx >= 0 THEN PUT (lvx, 343), mbase, XOR
lvx = lvx - 14
hitF = 1: aliens(j).typ = -1: aliens(j).temp = -1
x = aliens(j).xp: y = aliens(j).yp: point2 = aliens(j).point2: GOSUB 
explode
SOUND 0, 0: PLAY "mbmll64o2da"
END IF
RETURN

REM missile hits player
hit2:
IF (aliens(j).mx < player.x AND player.x - aliens(j).mx <= 7) OR 
(aliens(j).mx >= player.x AND aliens(j).mx - player.x <= 11) THEN
IF (aliens(j).my < player.y AND player.y - aliens(j).my <= 10) OR 
(aliens(j).my >= player.y AND aliens(j).my - player.y <= 6) THEN
lives = lives - 1
IF lvx >= 0 THEN PUT (lvx, 343), mbase, XOR
PLAY "mbmll64o2acaceggacac"
lvx = lvx - 14
aliens(j).my = lrlimit + 1
END IF
END IF
RETURN

REM missile hits alien
hit3:
FOR l = 1 TO max
IF (aliens(l).typ = expand AND aliens(l).temp = 0) OR aliens(l).typ = 
normal OR aliens(l).typ > expand THEN
IF aliens(l).typ = normal OR aliens(l).typ = expand THEN
x = aliens(l).x: y = aliens(l).y
ELSE
x = aliens(l).xp: y = aliens(l).yp
END IF
IF (shots(j).x < x AND x - shots(j).x <= 7) OR (shots(j).x >= x AND 
shots(j).x - x <= 11) THEN
IF (shots(j).y < y AND y - shots(j).y <= 10) OR (shots(j).y >= y AND 
shots(j).y - y <= 11) THEN
REM a hit
aliens(l).health = aliens(l).health - 1
shots(j).y = ulimit - 1: IF aliens(l).health > 0 THEN PLAY 
"mbmll64o4dc": RETURN
PUT (x, y), graphics(aliens(l).point3 * 100 - 100), XOR
point2 = aliens(l).point2: GOSUB explode
SOUND 0, 0: PLAY "mbmll64o2da"
hits = hits + 1: IF aliens(l).typ > expand THEN count = count - 1
s& = s& + (5 - pmax(aliens(l).point3) / 2) * 100
IF s& >= new& AND lives < 10 THEN
lives = lives + 1: lvx = lvx + 14
PUT (lvx, 343), mbase, XOR
msgx1 = 256: msgx2 = 391: GOSUB hide: PLAY 
"mbmll64o2geco3geco4geco3agagagag"
LOCATE 42, 32: COLOR 14: PRINT "1 UP - WELL DONE !";
GOSUB hide: upcount = 100: new& = new& + 10000
END IF
msgx1 = 80: msgx2 = (9 + LEN(STR$(s&))) * 8 - 1: GOSUB hide
LOCATE 42, 10: COLOR 2: PRINT STR$(s&);
GOSUB hide: aliens(l).typ = -1: aliens(l).temp = -1
GOSUB normtest
EXIT FOR
END IF
END IF
END IF
NEXT l
RETURN

hide:
FOR v = 1 TO max
IF (aliens(v).fired = 1 AND aliens(v).angle > 0) THEN
IF (aliens(v).mx > msgx1 AND aliens(v).mx - msgx1 <= msgx2 - msgx1) OR 
(aliens(v).mx <= msgx1 AND msgx1 - aliens(v).mx <= 7) THEN
IF (aliens(v).my > 336 AND aliens(v).my - 336 <= 7) OR (aliens(v).my <= 
336 AND 336 - aliens(v).my <= 10) THEN
PUT (aliens(v).mx, aliens(v).my), cmisl, XOR
END IF
END IF
END IF
NEXT v
FOR v = 1 TO max
IF aliens(v).typ = swoop THEN
IF (aliens(v).xp > msgx1 AND aliens(v).xp - msgx1 <= msgx2 - msgx1) OR 
(aliens(v).xp <= msgx1 AND msgx1 - aliens(v).xp <= 11) THEN
IF (aliens(v).yp > 336 AND aliens(v).yp - 336 <= 7) OR (aliens(v).yp <= 
336 AND 336 - aliens(v).yp <= 11) THEN
PUT (aliens(v).xp, aliens(v).yp), graphics(aliens(v).point3 * 100 - 
100), XOR
END IF
END IF
END IF
NEXT v
RETURN

init:
xstart = (640 - (nPerRow * 12)) / 2
x = xstart: y = height
llimit2 = xstart - 80: rlimit2 = xstart + nPerRow * 12 + 68
FOR j = 1 TO max
IF j / nPerRow <= 1 THEN pointer = 1
IF j / nPerRow > 1 AND j / nPerRow <= 2 THEN pointer = 3
IF j / nPerRow > 2 AND j / nPerRow <= 3 THEN pointer = 5
IF j / nPerRow > 3 THEN pointer = 7
aliens(j).point3 = pointer + (j MOD 2)
PUT (x, y), graphics(aliens(j).point3 * 100 - 100), XOR
aliens(j).x = x: aliens(j).y = y: aliens(j).r = 0: aliens(j).setup = 0
aliens(j).dir = right: aliens(j).typ = 0: aliens(j).temp = 0: 
aliens(j).fired = 0
aliens(j).point1 = j * 2 - 1: x = x + 12: aliens(j).point2 = j
IF x > xstart + (nPerRow - 1) * 12 THEN x = xstart: y = y + 12
aliens(j).count = 0: aliens(j).angle = 0: aliens(j).health = CINT(RND * 
2 + 1)
NEXT j
FOR j = 1 TO max
expl(j).x = 0
NEXT j
FOR j = 1 TO 3
shots(j).x = 0
NEXT j
RETURN

DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,0,0,3,3,0,0,3,3,0
DATA 0,3,3,0,3,3,3,3,0,3,3,0,0,3,3,3,3,3,3,3,3,3,3,0
DATA 0,3,3,8,8,3,3,8,8,3,3,0,0,3,3,8,8,3,3,8,8,3,3,0
DATA 3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,3,3,3,3,3,3,0,0,0
DATA 0,0,0,0,0,3,3,0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,0,0
DATA 0,0,0,0,0,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,0,0
DATA 0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,3,3,3,3,3,3,0,0,0
DATA 0,3,3,8,8,3,3,8,8,3,3,0,0,3,3,8,8,3,3,8,8,3,3,0
DATA 0,3,3,3,3,3,3,3,3,3,3,0,0,3,3,3,3,3,3,3,3,3,3,0
DATA 0,3,3,0,0,3,3,0,0,3,3,0,0,3,3,0,0,0,0,0,0,3,3,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0
DATA 0,0,0,4,4,4,4,4,4,0,0,0,0,0,4,7,7,4,4,7,7,4,0,0
DATA 0,0,4,7,7,4,4,7,7,4,0,0,0,4,4,4,4,4,4,4,4,4,4,0
DATA 0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,12,0,4,4,0,12,0,0,0
DATA 0,0,12,12,0,4,4,0,12,12,0,0,0,12,12,12,0,4,4,0,12,12,12,0
DATA 0,12,12,12,0,4,4,0,12,12,12,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,12,12,12,0,4,4,0,12,12,12,0
DATA 0,12,12,12,0,4,4,0,12,12,12,0,0,0,12,12,0,4,4,0,12,12,0,0
DATA 0,0,0,12,0,4,4,0,12,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0
DATA 0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,0,0,0
DATA 0,0,4,7,7,4,4,7,7,4,0,0,0,0,4,7,7,4,4,7,7,4,0,0
DATA 0,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,5,5,0,0
DATA 0,5,0,0,5,0,0,5,0,0,5,0,0,5,0,0,0,0,0,0,0,0,5,0
DATA 0,5,0,0,5,5,5,5,0,0,5,0,0,5,5,5,5,2,2,5,5,5,5,0
DATA 0,0,5,5,5,2,2,5,5,5,0,0,0,0,0,5,5,5,5,5,5,0,0,0
DATA 0,0,5,0,0,5,5,0,0,5,0,0,0,5,5,0,0,5,5,0,0,5,5,0
DATA 0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,5,5,0,0
DATA 0,0,0,5,0,0,0,0,5,0,0,0,0,0,0,0,5,5,5,5,0,0,0,0
DATA 0,0,5,5,5,2,2,5,5,5,0,0,0,5,5,5,5,2,2,5,5,5,5,0
DATA 0,5,0,5,5,5,5,5,5,0,5,0,5,0,0,0,0,5,5,0,0,0,0,5
DATA 5,0,0,0,0,0,0,0,0,0,0,5,5,0,0,5,0,0,0,0,5,0,0,5
DATA 0,5,5,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,0,0,0,0,6,6,0
DATA 0,0,6,6,0,0,0,0,6,6,0,0,0,0,6,6,6,6,6,6,6,6,0,0
DATA 0,0,6,6,6,6,6,6,6,6,0,0,0,6,6,1,1,6,6,1,1,6,6,0
DATA 0,6,6,1,1,6,6,1,1,6,6,0,0,0,6,6,6,6,6,6,6,6,0,0
DATA 0,0,0,6,6,0,0,6,6,0,0,0,0,0,6,6,0,0,6,6,0,0,0,0
DATA 0,6,6,0,0,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,0,0,0,0,6,6,0,0,0
DATA 0,0,6,6,0,0,0,0,6,6,0,0,0,0,6,6,6,6,6,6,6,6,0,0
DATA 0,0,6,6,6,6,6,6,6,6,0,0,0,6,6,1,1,6,6,1,1,6,6,0
DATA 0,6,6,1,1,6,6,1,1,6,6,0,0,0,6,6,6,6,6,6,6,6,0,0
DATA 0,0,0,6,6,0,0,6,6,0,0,0,0,0,0,0,6,6,0,0,6,6,0,0
DATA 0,0,0,0,0,6,6,0,0,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,15,0,0,0,0,7,0
DATA 0,0,7,0,0,0,15,0,0,7,0,0,0,0,0,7,0,15,0,0,7,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,15,0,7,0,0,0,0,15,0
DATA 0,15,0,0,0,0,7,0,15,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,7,0,15,0,0,7,0,0,0,0,0,7,0,0,0,15,0,0,7,0,0
DATA 0,7,0,0,0,15,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,12,12,0,0,0,0,0,12,12,12,12,0,0
DATA 0,0,12,12,12,12,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,12,12,0,0,0,0,0,0,12,12,0,0,0
DATA 0,0,0,12,12,0,0,0,0,12,0,12,12,0,12,0
DATA 12,12,0,12,12,0,12,12,12,12,0,12,12,0,12,12
DATA 0,0,0,12,12,0,0,0,0,0,0,10,10,0,0,0
DATA 10,10,0,10,10,0,10,10,10,10,0,10,10,0,10,10
DATA 0,10,0,10,10,0,10,0,0,0,0,10,10,0,0,0
DATA 0,0,0,10,10,0,0,0,0,0,0,10,10,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,10,10,10,10,0,0
DATA 0,0,10,10,10,10,0,0,0,0,0,10,10,0,0,0
DATA 0,0,0,0,0,12,12,0,0,0,0,0,0,0,0,0,0,12,12,0,0,0,0,0
DATA 0,0,0,12,12,12,12,12,12,0,0,0,0,0,12,12,12,12,12,12,12,12,0,0
DATA 
0,12,12,12,12,12,12,12,12,12,12,0,12,12,12,12,12,12,12,12,12,12,12,12
DATA 12,12,12,12,12,12,12,12,12,12,12,12
DATA 2,2,4,4,6,6,8,8
