%begin ! %include "project:consts.imp" %const %integer restart=14 %byte spacing=true,ship direction=1,ship type=1 %integer ship col=-1,timer %integer no of men=3 %integer score=0 %integer max bomb factor=8 %integer no of invs=24,leftmost=1,rightmost=8,lowest=3 %integer no of bombs=0,sheet no=0 %integer shell row=-1,shell col=-1 %integer row,col,i,j %integer row offset=0,col offset=0 %integer init,step,final %integer legs in=false %integer tank pos %integer chs since esc=0 %integer buffer size=100 %integer bufflim,ibp,obp=0,iblim,char,ch %own %byte %array score board (1:4)='0' (*) %byte %array output buffer (1:100) %own %integer %array no in row (1:3)=8 (*) %own %integer %array no in col (1:8)=3 (*) %own %integer %array bomb row (1:5)=0 (*) %own %integer %array bomb col (1:5)=0 (*) %integer %array barrier (0:79) %external %integer %fn %spec random integer %record %format fm high score (%string (3) name,%integer score,check sum) %own %record (fm high score) %array score table (1:15)=0 (*) %record %format area (%integer llrow,llcol,urrow,urcol) %record (area) box=0 %external %routine %spec read record (%integer %name size, %record (*) %name rec) %external %routine %spec print record (%integer size, %record (*) %name rec) %external %routine %spec set default protection (%integer prot) %external %string (127) %fn %spec in file name %external %routine %spec delete (%string (127) file spec) %external %routine %spec terminal (%byte %name buff, %integer howmany) %external %integer %fn %spec check speed %external %integer %fn %spec keych %external %string (255) %fn %spec i to s (%integer num,length) %external %predicate %spec CHAR WAITING %alias "TTIO.CHR_WTNG" %c (%integername char, nchars) %external %routine %spec wait (%integer ms) %external %string (12) %fn %spec user name %external %string (127) %fn %spec time %external %string (127) %fn %spec date %external %routine %spec open append (%integer stream,%string (127) file spec) %own %byte %array screen pts (1:24)=true (*) %integer %fn random num (%integer max) %result=random integer*max//1000+1 %end %routine flush %if obp>0 %start terminal (output buffer (1),obp) obp=0 %finish %end %routine %spec escape (%byte ch) %routine raw out (%byte ch) ! Make sure that sixty characters are not output without an 'esc' ! Otherwise, VAX inserts a newline %if ch=esc %then chs since esc=0 %c %else chs since esc=chs since esc+1 %if chs since esc>=60 %then escape ('l') ;! Unlock keyboard %if obp=buffer size %then flush obp=obp+1 output buffer (obp)=ch %end %routine escape (%byte ch) raw out (esc) raw out (ch) %end %routine move to (%byte row,col) escape ('Y') raw out (32+row) raw out (32+col) %end %routine draw box (%integer llrow,llcol,urrow,urcol) %integer line move to (urrow,llcol) raw out ('s') ;! Top left raw out ('`') %for line=llcol+1,1,urcol-1 ;! Top side raw out ('l') ;! Top right %for line=urrow+1,1,llrow-1 %cycle ;! Two sides move to (line,llcol) raw out ('a') move to (line,urcol) raw out ('a') %repeat move to (llrow,llcol) raw out ('e') ;! Lower left raw out ('`') %for line=llcol+1,1,urcol-1 ;! Lower side raw out ('m') ;! Lower right box_llrow=llrow;box_llcol=llcol;box_urrow=urrow;box_urcol=urcol %end %string (80) %fn centre (%string (80) message) %integer no of spaces message=" ".message %for no of spaces=1,1,(80-length (message))>>1 %result=message %end %routine string print (%string (80) message,%integer row,col) %integer char move to (row,col) %for char=1,1,length (message) %cycle raw out (char no (message,char)) %repeat %end %byte %map invaders (%integer row,col) %result==screen pts ((row-1)*8+col) %end %routine screen position for (%integer %name inv row,inv col) inv row=2+(inv row-1)*3 + row offset inv col=5+(inv col-1)*4 + col offset %end %predicate hit invader (%integer %name row,col) row=row-2-row offset %false %if rem (row,3)=2 row=row//3+1 col=col-4-col offset %false %if rem (col,4)=3 col=col//4+1 %true %if 1<=row<=3 %and 1<=col<=8 %and invaders (row,col)=true %false %end %routine clear type ahead %integer char,ch %if char waiting (ch,char) %start ch=keych %for char=1,1,char %finish %end %routine %spec paint no of men %routine show score table %integer player no,size,winning no=-1,cs %record (fm high score) %name player %own %string (40) %array rank (0:9)= %c "A Launch Pad Disaster", "A Space Cretin", "A Space Waster", "A Space Hero", "A Whiz Kid", "A Space King", "A Space Adict", "Beyond Hope", "Beyond Belief", "The Best Thing Since Sliced Bread" %routine print player (%record (fm high score) %name pres player) string print (pres player_name,3+player no,35) string print (i to s (pres player_score,5),3+player no,40) %end %integer %fn check sum (%record (fm high score) %name player) %integer i,cs=0 cs=cs+charno (player_name,i) %for i=1,1,length (player_name) cs=cs+player_score %result=cs&255 %end %routine get money and run %integer player no,char,ch %string (127) file name clear type ahead flush file name=in file name close input select input (1) %if winning no#-1 %start player==score table (winning no) player_name=" " move to (3+winning no,35) flush char=1 %cycle ch=keych %exit %if ch=cr %if ch=del %start %continue %if char=1 raw out (bs);raw out ('_');raw out (bs) flush char=char-1 %continue %finish ch=ch-'a'+'A' %if 'a'<=ch<='z' %continue %unless ' '<=ch<='~' char no (player_name,char)=ch raw out (ch) flush char=char+1 %repeat %until char=4 %finish set default protection (0) open append (3,"dr1:[shm.cs3]unames.nam") select output (3) print string ("(".score table (winning no)_name.")"." ") %c %unless winning no=-1 print string (user name." ".date." ".time." ".i to s (score,0).snl) %begin %on * %start %return %finish close output %end open output (2,"dr1:[shm.games]scores.dat") select output (2) %for player no=1,1,15 %cycle player==score table (player no) player_check sum=check sum (player) print record (size of (player),player) %repeat close output select output (1) %begin %on * %start %return %finish delete (file name) %end %end %on 9 %start get money and run %if event_sub=1 %return %finish open input (2,"dr1:[shm.games]scores.dat") select input (2) move to (1,0) escape ('y') paint no of men escape ('4') draw box (21,31,1,49) escape ('3') escape ('G') escape ('j') string print (centre ("You Achieved the Rank of Being ".%c rank (score//1000)),23,0) %for player no=1,1,15 %cycle player==score table (player no) read record (size,player) cs=check sum (player) %unless cs=player_check sum %start player no=player no-1 %continue %finish %if winning no=-1 %and player_score < score %start score table (player no+1)=player %unless player no=15 winning no=player no player_score=score player_name="___" print player (player) player no=player no+1 %exit %if player no=16 %finish print player (score table (player no)) %repeat get money and run %end %routine paint score board %byte spacing=true %integer digit,temp score,power=1000,next dig temp score=score %for digit=1,1,4 %cycle next dig=temp score//power+'0' temp score=rem (temp score,power) power=power//10 %if next dig#score board (digit) %start %if spacing=true %start move to (0,71+digit) spacing=false %finish score board (digit)=next dig raw out (next dig) %else spacing=true %finish %repeat %end %routine paint barrier %integer barrier point move to (22,0) escape ('t') raw out (barrier (barrier point)) %for barrier point=0,1,79 %end %routine paint no of men move to (0,7) escape ('j') raw out (no of men+'0') %end %routine drop bomb %integer bomb no,inv no,row %return %if no of bombs=5 %for bomb no=1,1,5 %cycle %exit %if bomb row (bomb no)=0 %repeat %cycle inv no=random num (rightmost-leftmost+1)+leftmost-1 %repeat %until no in col (inv no)#0 bomb row (bomb no)=lowest bomb col (bomb no)=inv no screen position for (bomb row (bomb no),bomb col (bomb no)) bomb row (bomb no)=bomb row (bomb no)+2 no of bombs=no of bombs+1 move to (bomb row (bomb no),bomb col (bomb no)) raw out ('k') %end %predicate on lousy row %true %if shell row=2+row offset %or shell row=5+row offset %orc shell row=8+row offset %false %end %integer %fn abs (%integer n) %if n>=0 %then %result=n %else %result=-n %end %routine move shell %integer i,j %integer row,col,inv row,inv col,ship score %string (3) disp ship score %return %if shell row=-1 escape ('j') shell row=shell row-1 %if shell row=1 %and ship col-2<=shell col<=ship col+2 %start ship score=ship type*50*(3-abs (ship col-shell col)) %if score//800 < (score+ship score)//800 %start no of men=no of men+1 paint no of men %finish score=score+ship score paint score board disp ship score=i to s (ship score,0) disp ship score=" ".disp ship score %if disp ship score="50" timer=random num (4)+35 move to (1,ship col-1) ship col=-1 raw out (char no (disp ship score,col)) %for col=1,1,3 shell row=-1 %return %finish %if shell row=0 %start shell row=-1 %return %finish %return %if shell row=-1 inv row=shell row inv col=shell col %if hit invader (inv row,inv col) %start shell row=-1 invaders (inv row,inv col)=false no in row (inv row)=no in row (inv row)-1 no in col (inv col)=no in col (inv col)-1 row=inv row;col=inv col screen position for (row,col) %if score//800 < (score+(4-inv row)*10)//800 %start no of men=no of men+1 paint no of men %finish score=score+(4-inv row)*10 paint score board move to (row,col-1) raw out (' ') raw out (' ') raw out (' ') raw out (' ') move to (row+1,col-1) raw out (' ') raw out (' ') raw out (' ') raw out (' ') no of invs=no of invs-1 %if no of invs=0 %start sheet no=sheet no+1 %signal restart %finish %if inv col=leftmost %start %for j=inv col,1,rightmost %cycle %exit %if no in col (j)#0 %repeat leftmost=j %finish %if inv col=rightmost %start %for j=inv col,-1,leftmost %cycle %exit %if no in col (j)#0 %repeat rightmost=j %finish %if inv row=lowest %start %for i=inv row,-1,1 %cycle %exit %if no in row (i)#0 %repeat lowest=i %finish %else %unless on lousy row move to (shell row,shell col) raw out ('f') %finish %end %routine paint legs (%byte there) %if there=false %start raw out (' ') raw out (' ') raw out (' ') raw out (' ') %return %finish %if legs in=false %start raw out ('/') raw out (' ') raw out ('\') raw out (' ') %else raw out ('\') raw out (' ') raw out ('/') raw out (' ') %finish %end %routine paint invader (%integer row,col,type) move to (row,col-1) %if type=1 %start raw out ('s') raw out ('i') raw out ('l') %else %if type=2 raw out ('l') raw out ('i') raw out ('s') %else %if type=3 raw out (':') raw out ('i') raw out (':') %finish move to (row+1,col-1) paint legs (true) %end %routine draw all invaders %integer i,j,row,col %for i=1,1,3 %cycle row=i col=1 screen position for (row,col) move to (row,0) escape ('f') move to (row+1,0) escape ('f') %for j=1,1,8 %cycle row=i;col=j screen position for (row,col) paint invader (row,col,i) %if invaders (i,j)=true %repeat %repeat %end %routine draw tank move to (23,0) escape ('t') move to (23,tank pos-1) escape ('j') raw out ('s') raw out ('c') raw out ('l') %end %routine move ship %if timer=0 %start move to (1,0) %if ship col=-1 %start escape ('t') ship direction=random num (2) %if ship direction=1 %start ship col=1 %else move to (1,77) ship col=78 %finish ship type=random num (3) %if ship type=1 %start raw out ('[') raw out ('-') raw out (']') %else %if ship type=2 escape ('G') raw out ('{') raw out ('+') raw out ('}') escape ('F') %else raw out ('(') raw out ('*') raw out (')') %finish %else %if (ship col>=78 %and ship direction=1) %orc (ship col<=1 %and ship direction=2) ship col=-1 timer=random num (4)+35 escape ('t') %else %if ship direction=1 %start escape ('i') raw out (' ') ship col=ship col+1 %if ship type=3 %start raw out (' ') ship col=ship col+1 %finish %else ship col=ship col-1 escape ('O') %if ship type=3 %start ship col=ship col-1 escape('O') %finish %finish ship direction=-ship direction %if ship type=2 %and random num (40)=40 %finish %else timer=timer-1 %finish %end %routine move bombs %integer %name b row,bar pt %integer row,col,bomb no,b col %for bomb no=1,1,5 %cycle %unless bomb row (bomb no)=0 %start b row== bomb row (bomb no) b row=b row+1 %if (shell row>=b row>=shell row-2 %and bomb col (bomb no)=shell col) %orc b row=24 %start %unless b row=shell row-1 %or b row=24 %start escape ('j') move to (b row-1,bomb col (bomb no)) raw out (' ') %finish b row=0 no of bombs=no of bombs-1 %else %if b row=23 move to (22,bomb col (bomb no)) escape ('j') raw out (' ') %if tank pos-1<=bomb col (bomb no)<=tank pos+1 %start raw out (bel) raw out (bel) flush wait (500) no of men=no of men-1 %if no of men=0 %start show score table %stop %finish move to (23,0) escape ('t') draw tank paint no of men flush %finish %else %if b row=22 escape ('j') b col=bomb col (bomb no) bar pt==barrier (b col) %if bar pt=' ' %start move to (22,b col) raw out ('k') %else bar pt=bar pt-1 bar pt=' ' %if bar pt='0' move to (22,b col) raw out (bar pt) b row=0 no of bombs=no of bombs-1 %finish %finish %finish %repeat row=lowest;col=1 screen position for (row,col) move to (21,0) escape ('M') move to (row+2,0) escape ('L') drop bomb %if (no of bombs<=no of invs//max bomb factor+1 %c %and random num (2)=1) %end %routine read tank %integer ch,nchar,char,n %switch tank action (0:127) wait (5//no of invs+1) %if char waiting (ch,nchar) %start flush ch=keych -> tank action (ch) tank action ('4'): move to (23,0) ->end %if tank pos=5 escape ('O') escape ('O') tank pos=tank pos-2 ->end tank action ('6'): move to (23,0) ->end %if tank pos=75 escape ('i') raw out (' ') raw out (' ') tank pos=tank pos+2 ->end tank action ('5'): ! Shell ->end %unless shell row=-1 %if barrier (tank pos)=' ' %start shell row=22 shell col=tank pos move to (shell row,shell col) escape ('j') raw out ('f') ->end %else barrier (tank pos)=barrier (tank pos)-1 barrier (tank pos)=' ' %if barrier (tank pos)='0' move to (22,tank pos) escape ('j') raw out (barrier (tank pos)) %finish tank action (*): end: flush %finish %end %unless check speed=9600 %start print string ("Sorry buster, this program can only run at 9600 baud") new line %stop %finish %begin %integer i,j %on %event restart %start %finish %for i=1,1,3 %cycle no in row (i)=8 %for j=1,1,8 %cycle no in col (j)=3 invaders (i,j)=true %repeat %repeat timer=random num (4)+35 row offset=2*sheet no+2 col offset=0 leftmost=1;rightmost=8;lowest=3 shell row=-1;no of bombs=0 barrier (i)=' ' %for i=0,1,6 barrier (i)='4' %for i=7,1,11 barrier (i)=' ' %for i=12,1,21 barrier (i)='4' %for i=22,1,26 barrier (i)=' ' %for i=27,1,36 barrier (i)='4' %for i=37,1,41 barrier (i)=' ' %for i=42,1,51 barrier (i)='4' %for i=52,1,56 barrier (i)=' ' %for i=57,1,66 barrier (i)='4' %for i=67,1,71 barrier (i)=' ' %for i=72,1,79 bomb row (i)=0 %for i=1,1,5 no of invs=24 %if sheet no=0 %start score board (i)='0' %for i=1,1,4 escape ('v') Move to (0,2) raw out ('M');raw out ('e');raw out ('n');raw out (':') move to (0,65) raw out ('S');raw out ('c');raw out ('o');raw out ('r');raw out ('e') raw out (':') move to (0,75) raw out ('0') %else move to (1,0) escape ('y') %finish paint score board paint no of men escape ('F') draw all invaders paint barrier tank pos=39 draw tank flush wait (1000) step=-1 row offset=2*sheet no %cycle row offset=row offset+2 row=lowest col=leftmost screen position for (row,col) %if row>=20 %then %exit %if step=-1 %start escape ('i') step=1 %else escape ('j') step=-1 %finish %cycle %for i=1,1,3 %cycle %unless shell row=-1 %start escape ('j') move to (shell row,shell col) raw out (' ') %finish move ship move bombs move shell %unless shell row=-1 read tank row=i;col=1 screen position for (row,col) %unless row=23 %or i>lowest %start %if step=-1 %start move to (row,0) escape ('O') move to (row+1,0) escape ('O') %finish move to (row+1,0) escape ('t') move to (row+1,col-1) %for j=1,1,8 %cycle read tank %if invaders (i,j)=true %start escape ('j') row=i;col=j screen position for (row,col) move to (row+1,col-1) paint legs (true) %finish legs in=1-legs in %repeat %if step=1 %start escape ('i') move to (row,0) raw out (' ') move to (row+1,0) raw out (' ') %finish %finish legs in=1-legs in %repeat flush read tank %if step=1 %start %exit %if col offset+rightmost*4>=75 %else %exit %if col offset+(left most-1)*4=0 %finish col offset=col offset+step %repeat escape ('j') %unless on lousy row %start move to (shell row,shell col) raw out (' ') %finish row=lowest;col=1 screen position for (row,col) move to (row+2,0) escape ('M') escape ('M') %for i=1,1,5 %cycle %if row+2<=bomb row (i)<=row+3 %start bomb row (i)=0 no of bombs=no of bombs-1 %finish %repeat move to (2,0) escape ('L') escape ('L') draw tank %repeat show score table %end %end %of %program