0% found this document useful (0 votes)
4K views28 pages

Snee Snoo Snake Game Turbo Pascal Code

SneeSnoo Snake is a fun and challenging PC arcade style game written in TurboPascal by Bruce Lamar Rosenberg. This file contains the complete 47 pages of the original code. It is all here. It contains some very advanced adaptive algorithms for 1987 when it was written. If anyone has means of automatically converting this code please contact me.

Uploaded by

brues
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4K views28 pages

Snee Snoo Snake Game Turbo Pascal Code

SneeSnoo Snake is a fun and challenging PC arcade style game written in TurboPascal by Bruce Lamar Rosenberg. This file contains the complete 47 pages of the original code. It is all here. It contains some very advanced adaptive algorithms for 1987 when it was written. If anyone has means of automatically converting this code please contact me.

Uploaded by

brues
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 28

{$S+}

{$R+} {Range checking off}


{$I-} {I/O checking off}
{$N-} {No numeric coprocessor}

program SneeSnooSnake;

{ COPYRIGHT (C) 1986, 1987, 1989 BRUCE LAMAR ROSENBERG }

Uses
Crt, {Unit found in TURBO.TPL}
Dos; {Unit found in TURBO.TPL}

const
version = '5.0'; { current version of program }
snakefile = 'SNAKE.DAT'; { filename where top 20 scores saved }
lin = 6; {length of straight line to keep from going back over self, i.e.,
goes in straight line for LIN moves. }
snlen = 13; { length of snake, approx. 2 times lin }
toplist = 1;
botlist = 20; { size of score list }
namelen = 21; { length of name & namearray for entry on score list }
p = 1.112; { twelfth root of two squared for generating musical scale }
pctime = 8.460; { time taken by IBM pc to do chkspeed routine }

type
regrec = record
ax,bx,cx,dx,bp,di,si,ds,es,flags: integer;
end;
snptr = ^snrec;
snrec = record
x,y : byte;
next : snptr;
end;
namearray = array [toplist..botlist] of string[namelen];
scorearray = array [toplist..botlist] of real;
namestr = string[namelen];
censtr = string[80];
rnamestr = string[6];

var
autodem,demo,dying,deadly,bitten,NoFile,bagged,tooclose,soundon : boolean;
quickout,keyed,ReadOnce,firsttime, timeout : boolean;
CPUspeed,pscore,time,starttime : real;
n2autodem,nticks,bagdelay,i,n : byte;
head, neck, tail : snptr;
nsnakes,ndsnakes,nbites,ndbites : byte;
j,k : byte;
xt,yt,oldx,oldy,deltx,delty : integer;
OldBagCmd,BagCmd,SnooHead,SnooBody,SneeHead,SneeBody,ch,menusel : char;
SnooHdColor,SnooBdColor,SneeHdColor,SneeBdColor : byte;
name : namearray; score : scorearray;
pname : namestr;
rname : rnamestr;
regs : regrec;
dancedelay,blx,bly,oldblx,oldbly : integer;
waitbag,waitsn,autodelay,nrobo,ns : integer;
minX,minY,maxX,maxY,oldtime,alldelay : integer;
KPthisTime,KPlastTime,wipetrail : boolean;
btx,bty,nlen,n2die : integer;
rslack,tcount,L,R,T,B,bagszx,bagszy,bitedx,bitedy : integer;
bagVSsnake,gamespeed,robodelay,difbagged,oldbagged,nbagged : integer;
supvtime,playtime,timeleft,elapsedtime,incrdelay,decrdelay : integer;
KeyScan,OldScan : byte;
OldVec,exitsave : pointer;
{============================================================================}
procedure initialize;
var
ns : byte;
begin
minX := 1;
maxX := 78; {hor. text screen limit, STARTS AT 1 at LEFT, NOT 0! }
{ don't use 80 because screen handler automatically puts in CR,LF }
minY := 1;
maxY := 24; { vert. text screen limit, STARTS AT 1 at TOP, NOT 0! }
{don/t go to line 25 because screen control then starts scrolling }
SnooBody := '%';
SnooHead := '�';
SneeBody := '0';
SneeHead := char(2); { happy face }
SnooHdColor := white;
SnooBdColor := cyan;
SneeHdColor := lightred;
SneeBdColor := lightgreen;
quickout := false;
soundon := true;
autodem := true;
n2autodem:= 10;
autodelay := 100; { time between doticks for self-running prompt }
playtime := 120; { 120 seconds or two minutes }
robodelay := 1;
rslack := 1; { slack distance for robot movement }
dancedelay := 10; { delay for snake dance rate }
alldelay := 1; { starting value, delays both snake and bag movement }
bagdelay := 1;
n2die := 5; { # bites before die }
bagszx := 3; { bag size in x }
bagszy := 2; { bag size in y }
bitedx := 5; { snake striking distance in x }
bitedy := 4; { snake striking distance in y }
supvtime := 3; { interval (seconds) at which supervisegame called }
(*** this time interval is critical to the speed change algorithm ***)
end; { initialize }
{============================================================================}
procedure showoff_init;
begin
demo := true;
soundon := true; { true;}
playtime := 25; { changed from 120 seconds or two minutes }
n2die := 4; { # bites before die }
end;
{============================================================================}
function timer: real;
var
regs: regrec; {assign record}
ah,al,ch,cl,dh: byte;
hr,mn,sc,th : byte;
begin
ah := $2c; { call DOS fcn to get system time }
with regs do
begin
ax := ah shl 8 + al;
end;
intr($21,Dos.Registers(regs)); {call interrupt}
with regs do
begin
hr := cx shr 8; { LO(cx) }
mn := cx mod 256; { HI(cx) }
sc := dx shr 8; { more significant byte }
th := dx mod 256; { less significant byte }
end;
timer := ((hr*3600)+(mn*60)+sc)+(th/100); { returns time in seconds }
end; { function timer }
{----------------------------------------------------------------------------}
function chkspeed : real;

var elapstime, init, fin : real;


nt,nu : integer;
sum : longint;
begin
init := timer;
for nt := 1 to 200 do
begin
for nu := 1 to 1000 do
sum := sum + 1;
end;
fin := timer;
elapstime := fin-init;
chkspeed := elapstime;
end;
{----------------------------------------------------------------------------}
function KeyHit(VAR ch: char) : boolean;
begin
regs.AX := $0600; { call DOS Direct Console I/O }
regs.DX := 255; { choses read func w/o echo }
intr($21,Dos.Registers(regs)); { invoke a DOS function request }
ch := char(regs.AX);
KeyHit := ch <> Chr(0); { return the boolean }
end; { function KeyHit }
{----------------------------------------------------------------------------}
function monochrome: boolean;
var regs : regrec;
begin
intr(17,Dos.Registers(regs));
if (regs.ax) and $0030 = $30 then monochrome := true
else monochrome := false;
end; { function monochrome }
{----------------------------------------------------------------------------}
procedure setvidmode;
var regs : regrec;
begin
with regs do
begin
if monochrome then ax := $0007 else ax := $0003;
end; { with }
intr(16,Dos.Registers(regs));
end; { procedure setvidmode }
{----------------------------------------------------------------------------}
procedure curson;
var regs : regrec;
begin
with regs do
begin
ax := $0100;
if monochrome then cx := $0B0C else cx := $0607;
end; { with }
intr(16,Dos.Registers(regs));
end; { procedure curson }
{----------------------------------------------------------------------------}
procedure cursoff;
var regs : regrec;
begin
with regs do
begin
ax := $0100;
cx := $2000;
end; { with }
intr(16,Dos.Registers(regs));
end; { procedure cursoff }
{----------------------------------------------------------------------------}
procedure cen(cstring : censtr);
begin
gotoxy(40-length(cstring) div 2,wherey);
write(cstring);
end;
{----------------------------------------------------------------------------}
procedure cenln(cstring : censtr);
begin
gotoxy(40-length(cstring) div 2,wherey);
writeln(cstring);
end;
{----------------------------------------------------------------------------}
procedure censcr(cstring : censtr);
begin
gotoxy(40-length(cstring) div 2,12);
write(cstring);
end;
{----------------------------------------------------------------------------}
procedure upscale;
var
n : byte;
s : real;
begin
n := 0;
s:= 880.0;
for n := 1 to 12 do
begin
s := s*p;
if soundon then sound(trunc(s));
delay(30);
nosound;
delay(16-n);
end;
end;
{----------------------------------------------------------------------------}
procedure dnscale;
var
n : byte;
s : real;
begin
n := 0;
s:= 1760.0;
for n := 1 to 12 do
begin
s := s/p;
if soundon then sound(trunc(s));
delay(30);
nosound;
delay(16-n);
end;
end;
{----------------------------------------------------------------------------}
procedure uptweet;
var
i : byte;
s : real;
begin
s := 1760.0;
begin
for i := 1 to 12 do
begin
s := s*p;
if soundon then sound(trunc(s));
delay((16-i));
end;
end;
nosound;
end;
{----------------------------------------------------------------------------}
procedure dntweet;
var
i : byte;
s : real;
begin
s := 3520.0;
begin
for i := 1 to 12 do
begin
s := s/p;
if soundon then sound(trunc(s));
delay((16-i));
end;
end;
nosound;
end;
{----------------------------------------------------------------------------}
procedure dotick;
var
i : byte;
s : real;
begin
s := 1000.0;
begin
if soundon then sound(trunc(s));
delay(4);
end;
nosound;
end;

{----------------------------------------------------------------------------}
function GetKey: char;
var ch : char;
begin
Ch := crt.readkey;
memw[0:$41a] := memw[0:$41c]; {Clears keyboard buffer quickly by
setting head & tail equal to each other}
GetKey := ch;
end;
{----------------------------------------------------------------------------}
procedure ClrKey;
begin
memw[0:$41a] := memw[0:$41c]; {Clears keyboard buffer quickly by
setting head & tail equal to each other}
end;
{----------------------------------------------------------------------------}
procedure AutoContinue;
begin
timeout := false;
nticks := 0;
textcolor(white);
gotoxy(1,25);
write('Press a key for menu ----');
gotoxy(35,25);
write('RUN AUTO DEMO');
gotoxy(25,25);
cursoff;
repeat
delay(autodelay);
dotick;
write('>');
nticks := succ(nticks);
timeout := nticks = n2autodem;
until timeout or keypressed;
if keypressed then
begin
ClrKey;
autodem := false
end else
autodem := true;
curson;
uptweet;
end;
{----------------------------------------------------------------------------}
procedure PressToContinue;
begin
textcolor(white);
gotoxy(1,25);
write('Press a key for menu --- ');
repeat until keypressed;
ClrKey;
end;
{----------------------------------------------------------------------------}
procedure menu; FORWARD;
{----------------------------------------------------------------------------}
procedure afterdeath; { return to menu through here if killed }
var
ncells : integer;
begin
gotoxy(1,1);
port[$3D9] := black;
textcolor(0);
for ncells := 1 to 2000 do write(char(219));
curson;
textbackground(black);
textcolor(white);
end;
{============================================================================}
procedure ZeroScoreArray;
var
n : byte;
begin
for n := toplist to botlist do
begin
name[n] := '';
repeat name[n] := name[n] + '.' until length(name[n]) = namelen;
score[n] := 0;
end;
end;
{----------------------------------------------------------------------------}
procedure WriteScoreArray;
var
infile : text;
n : byte;
begin
assign(infile,snakefile);
rewrite(infile);
for n := toplist to botlist do
begin
writeln(infile,name[n],' ',score[n]);
end;
close(infile);
end;
{----------------------------------------------------------------------------}
procedure ReadScoreArray;
var
infile : text;
n :byte;
begin
assign(infile,snakefile);
{$I-} reset(infile) {$I+}; { check if the 'snake.dat' file exists. }
NoFile := (IOresult = 2);
if NoFile then { if not, then create it }
begin
zeroscorearray;
writescorearray;
end
else
close(infile); { When using autodemo I had to add this to prevent
"too many files open" error.}
assign(infile,snakefile); { NOW that it exists, we can read from it }
reset(infile); { without crashing. }
for n := toplist to botlist do
begin
readln(infile,name[n],score[n]);
end;
close(infile);
end;
{----------------------------------------------------------------------------}
function roboname : rnamestr;

type
tristr = string[3] ;
var
vowels : string[7] ;
consonants : string[20] ;
rname1,rname2 : string[3];
ch : char;
{----------------------------------------------------------------------------}
procedure rnameinit;
begin
consonants := 'bdfgklmnprssttvwz';
vowels := 'aaeeiou';
{ consonants := 'BDFGKLMNPRSSTTVWZ';
vowels := 'AAEEIOU';
}
randomize;
end;
{----------------------------------------------------------------------------}

function triad: tristr;


var tri : string[3]; v1,c1,c2 : integer;
begin
c1 := 1+trunc(random(length(consonants)));
v1 := 1+trunc(random(length(vowels)));
c2 := 1+trunc(random(length(consonants)));
tri := consonants[c1];
tri := tri+ vowels[v1];
tri := tri+ consonants[c2];
triad := tri
end;

begin
rnameinit;
rname1 := triad;
rname2 := triad;
ch := char(ord(rname1[1])-$20); { capitalize first letter of name }
rname1[1] := ch;
roboname := rname1 + rname2;
end;
{----------------------------------------------------------------------------}
procedure robowrite;
var numstr : string[3]; nr : integer;
begin
nrobo := nrobo + 1;
rname := roboname;
str(nrobo:3,numstr);
pname := 'I '+rname+', robot #'+numstr+',';
for nr := 1 to length(pname) do
begin
write(pname[nr]);
dotick;
delay(200);
end;
end;
{----------------------------------------------------------------------------}
procedure checkscore;
var
i,j,k,n,insertpos : byte;
begin
if (pscore < score[botlist]) or (pscore <= 0) then
begin
gotoxy(1,11);
writeln('Sorry Hunter, your score of ',pscore:5:2,' is not in the top 20.');
if pscore < 0 then pscore := 0;
if autodem then AutoContinue else PressToContinue;
exit;
end
else
begin
while keypressed do ch:= readkey;
insertpos := toplist;
if pscore > score[toplist] then
begin
gotoxy(1,11);
writeln('WOW! You scored ',pscore:5:2,'. Hail the New Champion!');
end
else
begin
gotoxy(1,11);
writeln('Jolly Good! Your score of ',pscore:5:2,' is in the top 20.');
end;
writeln;
write('OK, SneeSnoo Snaker, enter your name here :');
for i := 1 to namelen do write('.');
write(':');
gotoxy(wherex-(namelen+1),wherey);
if demo then robowrite
else
read(pname);
repeat pname := pname + '.' until length(pname) = namelen;
{ find insert position }
while pscore < score[insertpos] do insertpos := succ(insertpos);
{ shift all down, starting at list bottom & losing lowest score }
for k := botlist-1 downto insertpos do { botlist > insertpos }
begin { **** must run this loop from bottom up! }
score[k+1] := score[k];
name[k+1] := name[k];
end;
score[insertpos] := pscore; { put new values in their place }
name[insertpos] := pname;
end;
end;
{----------------------------------------------------------------------------}
procedure listscores;
var
n : byte;
begin
clrscr;
cenln('HERE ARE THE SCORES FOR');
cenln('The Top 20 SneeSnoo Snake Snatchers:');
writeln;
for n := toplist to botlist do
begin
gotoxy(12,n+3);
writeln(n:3,'. ',name[n],' scored ',score[n]:5:2,' points per minute.');
end;
if autodem then AutoContinue else PressToContinue;
end;
{=========================== END SCOREBIZ ==============================}
procedure SnakeBiz;
FORWARD;
{----------------------------------------------------------------------------}
procedure die;
var
s : real;
ncells : integer;
nl,nshud : byte;
begin
s := 220;
clrscr;
gotoxy(1,1);
port[$3D9] := 15;
textcolor(15);
textbackground(15);
for ncells := 1 to 2000 do write(chr(219));
textcolor(black);
for nl := 1 to 16 do
begin
gotoxy(1,9 + nl);
cen(' ');
end;
gotoxy(1,15);
cen(' YOUR WORLDLY PROBLEMS ARE OVER. ');
gotoxy(1,18);
cen(' HUNTER, REST IN PEACE! ');
for nshud := 1 to 7 do
begin
s := s/p;
if soundon then sound(trunc(s));
delay(600+30*nshud);
end;
nosound;
afterdeath;
end;
{----------------------------------------------------------------------------}
procedure newsnake;
var
corner,nratl : byte;
begin
randomize;
new(head); new(neck); new(tail);
{ create beginning position for snake }
head^.x :=minX + trunc(random(maxX));
head^.y :=minY + trunc(random(maxY));
(*
for nratl := 1 to 30 do
begin
gotoxy(head^.x,head^.y);
write('#');
dotick;
delay(30);
gotoxy(head^.x,head^.y);
write(' ');
end;

corner := 1 + trunc(trunc(random(4));
case corner of
1: begin head^.x := maxX; head^.y := maxY; end; { bot. rt. }
2: begin head^.x := minX; head^.y := maxY; end; { bot. left }
3: begin head^.x := maxX; head^.y := minY; end; { top rt. }
4: begin head^.x := minX; head^.y := minY; end; { top left }
end;
*)
head^.next := head;
tail := head; neck := head; { set all pointers to head }
(* deltx := trunc(random(3))-1; delty := trunc(random(3))-1;
oldx := deltx; oldy := delty;
*)
nlen:=0; wipetrail := false;
end;
{----------------------------------------------------------------------------}
procedure eraseOldSnake;
begin
repeat { erase old snake }
gotoxy(tail^.x, tail^.y);
write(chr(32)); { write blank over snake tail end }
tail := tail^.next; { link to record one up ahead }
dispose(head^.next); { clear the old tail from memory }
head^.next := tail; { stores value of tail for disposal }
until head^.next = head;
dispose(head^.next);
head:=nil; neck:=nil; tail:=nil;
end;
{----------------------------------------------------------------------------}
procedure bagshut;
var
k,n,nbs : byte;
begin
L := blx - bagszx; R := blx + bagszx;
T := bly - bagszy; B := bly + bagszy;
textcolor(white);
gotoxy(L,T); write('�'); { scanwise order }
gotoxy(R,T); write('�');
gotoxy(L,B); write('�');
gotoxy(R,B); write('�');
uptweet;
bagged :=((head^.x >= blx-bagszx) and
(head^.x <= blx+bagszx) and
(head^.y >= bly-bagszy) and
(head^.y <= bly+bagszy));

tooclose :=((head^.x >= blx-bitedx) and


(head^.x <= blx+bitedx) and
(head^.y >= bly-bitedy) and
(head^.y <= bly+bitedy));

if bagged then
begin
eraseOldSnake;
if deadly then begin
ndsnakes := succ(ndsnakes);
L := blx - bagszx; R := blx + bagszx;
T := bly - bagszy; B := bly + bagszy;
textcolor(SnooBdColor);
gotoxy(L,T); write(SnooBody); { scanwise order }
gotoxy(R,T); write(SnooBody);
gotoxy(L,B); write(SnooBody);
gotoxy(R,B); write(SnooBody);
censcr('Snagged Snoo # ');
textcolor(SnooHdColor);
write(ndsnakes:2,' ',SnooHead);
uptweet;
upscale;
end else begin
nsnakes := succ(nsnakes);
L := blx - bagszx; R := blx + bagszx;
T := bly - bagszy; B := bly + bagszy;
textcolor(SneeBdColor);
gotoxy(L,T); write(SneeBody); { scanwise order }
gotoxy(R,T); write(SneeBody);
gotoxy(L,B); write(SneeBody);
gotoxy(R,B); write(SneeBody);
censcr('Snatched Snee # ');
textcolor(SneeHdColor);
write(nsnakes:2,' ',SneeHead);
upscale; { message displayed while music plays }
end;
gotoxy(10,12); clreol;
end; { bagged the snake }
if not bagged and tooclose then
begin
bitten := true;
if not deadly then
begin
nbites := succ(nbites);
{ change bag temporarily when bitten }
L := blx - bagszx; R := blx + bagszx;
T := bly - bagszy; B := bly + bagszy;
textcolor(SneeHdColor);
gotoxy(L,T); write(SneeHead); { scanwise order }
gotoxy(R,T); write(SneeHead);
gotoxy(L,B); write(SneeHead);
gotoxy(R,B); write(SneeHead);
port[$3d9] := 4; { make border red }
textcolor(SneeHdColor);
censcr('Snee Bite!');
dnscale; { message displayed while music plays }
port[$3d9] := 2; { make border green }
end else
begin
ndbites := succ(ndbites);
if ndbites = n2die then
begin
clrscr;
dying := true;
exit;
end;
L := blx - bagszx; R := blx + bagszx;
T := bly - bagszy; B := bly + bagszy;
textcolor(SnooHdColor);
gotoxy(L,T); write(SnooHead); { scanwise order }
gotoxy(R,T); write(SnooHead);
gotoxy(L,B); write(SnooHead);
gotoxy(R,B); write(SnooHead);
port[$3d9] := 15; { make border bright white }
dntweet;
gotoxy(28,12);
write((n2die-ndbites):2,' More & You DIE!');
dnscale; { message displayed while music plays }
port[$3d9] := 2; { make border green }
end; { if deadly }
for k := 1 to 40 do SnakeBiz; { make snake dance joyfully }
nosound; { turn snake dance sound off }
gotoxy(10,12); clreol;
bitten := false;
end; { bitten by snake }
if bagged then newsnake; { generate new snake starting point }
end;
{----------------------------------------------------------------------------}
procedure fastout;
begin
clrscr;
port[$3D9] := black; { set border to black }
curson; { turn cursor back on }
quickout := true;
{ halt; fast way out of the game if boss comes in }
end;
{----------------------------------------------------------------------------}
procedure robotplayer(VAR bcmd : byte);
begin
if (trunc(random(8)) > 4) then
begin
L := blx-bagszx; R := blx+bagszx; { L = left, R = right }
T := bly-bagszy; B := bly+bagszy; { T = top, B = bottom edges of bag }

if (head^.x < L) then bcmd := 34; { move L }


if (head^.x > R) then bcmd := 35; { move R }
if (head^.y < T) then bcmd := 21; { move U }
if (head^.y > B) then bcmd := 48; { move D }

if (((head^.x >= L-rslack) and


(head^.x <= R {+rslack} ) and
(head^.y >= T-rslack) and
(head^.y <= B {+rslack} )) and (trunc(random(2)) > 0))
then bcmd := 57; { close bag }
end;
end;
{-----------------------------------------------------------------------------}
(*
{$f+}
procedure Myexit;
{$f-}
begin
if exitcode <> 0 then
setintvec(9,oldvec);
exitproc := exitsave;
end;
{-----------------------------------------------------------------------------}
procedure ReadScan; interrupt;
begin
KeyScan := port[$60]; { read the keyboard hardware port }
inline($9C/$FF/$1E/OldVec); {call old int vector}
end;
{----------------------------------------------------------------------------}
*)
procedure BagBiz;
{ ************* bag business **************}
var
BagCmd,nb : byte; ch : char;

begin { read keyboard for inputs controlling bag }


BagCmd := 128;
blx := oldblx; bly := oldbly; { restore bag location to old }

if demo then robotplayer(BagCmd);

(* else
begin
exitsave := exitproc;
exitproc := @myexit;
GetIntVec(9, OldVec);
SetIntVec(9, @ReadScan);

BagCmd := keyscan; { keyscan gotten by Readscan interrupt proc. above }

SetIntVec(9, OldVec); { restore int09 vector before leaving }


end;
See procedure ReadScan above as well as MyExit for ISR
BagCmd:=port[$60];
{ Unless using an AT, can't read keyboard output directly as above,
for XT's must use int09 service routine }
*)

memw[0:$41c] := memw[0:$41a]; { this sets DOS kbd buffer head = tail


thus clearing it, prevents buffer overflow }

begin
case BagCmd of
34 : { bag left }
begin
btx:=blx-1;
if btx-bagszx >= minX then blx := btx;
end;
35 : { bag right }
begin
btx:=blx+1;
if btx+bagszx <= maxX+1 then blx := btx;
end;
21 : { bag up }
begin
bty:=bly-1;
if bty-bagszy >= minY then bly := bty;
end;
48 : { bag down }
begin
bty:=bly+1;
if bty+bagszy <= maxY then bly := bty;
end;
1 : begin
fastout; { esc key to abort current game }
exit;
end;
57 : { spacebar to close bag }
begin
bagshut; { close bag & determine results, }
{ whether bagged, bitten and/or dying }
if dying then exit;
end;
128..255 : begin end;
{ else dotick }
end ;{ case }
end; { if keypressed and case }
if not ((oldbly = bly) and (oldblx = blx)) then
begin
L := oldblx - bagszx; R := oldblx + bagszx; { erase old bag }
T := oldbly - bagszy; B := oldbly + bagszy;
textcolor(black);
gotoxy(L,T); write('�'); { scanwise order }
gotoxy(R,T); write('�');
gotoxy(L,B); write('�');
gotoxy(R,B); write('�');
end;
(* end; { if keypressed and case }
*) L := blx - bagszx; R := blx + bagszx; { draw new bag }
T := bly - bagszy; B := bly + bagszy;
textcolor(yellow);
gotoxy(L,T); write('�'); { scanwise order }
gotoxy(R,T); write('�');
gotoxy(L,B); write('�');
gotoxy(R,B); write('�');
oldblx := blx; oldbly := bly; { save old bag location for erasing bag }

end; { procedure BagBiz and return to playgame }


{----------------------------------------------------------------------------}
procedure updatetime;
begin
time := timer;
elapsedtime := trunc(time - starttime); {must take diff before trunc}
timeleft := trunc(playtime-elapsedtime);
end;
{----------------------------------------------------------------------------}
procedure computescore;
begin
nbagged := nsnakes + (4 * ndsnakes) - nbites - (2 * ndbites);
pscore := 60 * nbagged / elapsedtime;
end;
{----------------------------------------------------------------------------}
procedure displayscorebar;
begin
gotoxy(1,25);
textcolor(white);textbackground(black);
write
(' # Bagged=',nbagged:2,' # Bites=',(nbites + ndbites):2);
write
(' Score=',pscore:5:2,' Time=',timeleft:3);
write
(' Delay=',alldelay:3,' Quit=F1 Send $10');
textbackground(black);
end; { do score bar at bottom of screen }
{----------------------------------------------------------------------------}
procedure SnakeBiz;
var
j,xt, yt : integer;
membytes : real;
begin
nlen := succ(nlen);
if (nlen > snlen) then nlen := 1;

deltx := oldx; delty := oldy; { let the new increments equal the old }

if (nlen = 1) or (deltx = 0) { 0 means no change } then


deltx := trunc(random(3)) - 1; { gen new x incr, 0, 1, or 2; minus 1}
xt := head^.x + deltx; { the -1 shifts the increment, so +1 or -1 }
if (xt > maxX) then deltx := trunc(random(2)) - 1; { scrn rt side limit }
if (xt < minX) then deltx := trunc(random(2)); { scrn left side limit }

if (nlen = 5) or (delty = 0) then


delty := trunc(random(3))-1; {gen new y increment }
yt := head^.y + delty;
if (yt > maxY) then delty := trunc(random(2)) - 1; { screen bottom limit }
if (yt <= minY) then delty := trunc(random(2)); { screen top limit }

head^.x := head^.x + deltx; { new x location of head }


if head^.x > maxX then head^.x := maxX; { fail-safe }
if head^.x < minX then head^.x := minX; { fail-safe }
head^.y := head^.y + delty; { new y location of head }
if head^.y > maxY then head^.y := maxY; { fail-safe }
if head^.y < minY then head^.x := minY; { fail-safe }

oldx := deltx; oldy := delty; { remember the current increments }

if (nlen = snlen) then wipetrail := true;


if wipetrail then { start following the head, erasing last char
once the snake has grown to full length }
begin
gotoxy(tail^.x, tail^.y);
write(chr(32)); { write blank over snake tail end }
tail := tail^.next; { link to record one up ahead }
dispose(head^.next); { clear the old tail from memory }
head^.next := tail; { set head next pointer to new tail }
end;
gotoxy(head^.x,head^.y);
if deadly then
begin { write head for poisonous snake }
textcolor(SnooHdColor);
write(snoohead); { face with fangs }
end else
begin { write head for nonpoisonous snake }
textcolor(SneeHdColor);
write(sneehead); { solid happy face }
end;
gotoxy(neck^.x,neck^.y);
{ overwrite the old head with body symbol }
if deadly then
begin
textcolor(SnooBdColor);
write(SnooBody);
end else
begin
textcolor(SneeBdColor);
write(SneeBody);
end;
if bitten and not dying then
begin
If soundon then sound(trunc(random(2640))+1760);
delay(dancedelay);
end { IF BITTEN: DANCING SOUND FOR SNAKE AFTER BITING HUNTER }
else delay(alldelay);
neck := head; { neck now points to snake's old head record }
new(head); { create a new snake head record }
head^.x := neck^.x; head^.y := neck^.y; { fill with old head loc }
neck^.next := head; { link neck (old head) to new head }
head^.next := tail; { point head next to the new tail (circular list) }
end;
{============================================================================}
procedure controlspeed;
var
incrdelay,decrdelay : integer;
begin
if alldelay <= 100 then
begin
decrdelay := alldelay div 16; { 16, % of delay is consistent
with psychophysical power (S. S. Stevens) law }
incrdelay := alldelay div 32; { 32 }
end else
begin
decrdelay := alldelay div 8; { 8 }
incrdelay := alldelay div 16; { 16 }
end;
difbagged := nbagged - oldbagged;
if difbagged >= 1 then alldelay := alldelay - decrdelay;
{ speeds up the game }
if difbagged <= 0 then alldelay := alldelay + incrdelay;
{ slows down the game }
if alldelay >= 160 then alldelay := 160;
if alldelay <= 50 then alldelay := 50;
oldbagged := nbagged; { nbagged gets incremented in computescore }
end;
{--------------------------------------------------------------------------}
procedure finalscorebiz;
begin
readscorearray; { read scores from SNAKEFILE file }
checkscore; { compare present score with top 20, ask for name if in }
if (pscore < score[botlist]) or (pscore <= 0) then exit;
writescorearray; { write new score array to disk }
listscores; { display new scores to player }
end;
{--------------------------------------------------------------------------}
procedure supervisegame;
begin
{ every 3 seconds, display scores and determine whether to
make snake deadly and/or to speedup or slowdown game }
deadly := false;
if elapsedtime > 0 then computescore;
displayscorebar;
if trunc(random(2)) = 1 then
deadly := true; { make snake deadly half of the time }

{ controlspeed;
}

end;
{--------------------------------------------------------------------------}
procedure setGameScrn;
begin
port[$3D9] := GREEN; { SET BORDER COLOR }
cursoff;
textbackground(black);
clrscr;
end;
{--------------------------------------------------------------------------}
procedure initgame;
begin
bagVSsnake := 13; { # of allowed bag moves per snake move }
gamespeed := 30;
waitsn := round(gamespeed * CPUspeed);
waitbag := round(waitsn / bagVSsnake);
{ the following initialization is necessary }
nsnakes := 0; nbites := 0; ndsnakes := 0; ndbites := 0;
difbagged := 0; nbagged := 0; oldbagged := 0;
blx := 40; bly := 12; oldblx := 40; oldbly := 12;
elapsedtime := 0; timeleft := playtime;
starttime := timer; { gets time for start of game }
time := timer;
alldelay := 1; pscore := 0.0;
bitten := false;
deadly := false;
dying := false;
FirstTime := true;
BagCmd := 'x';
ReadOnce := false;
minX := 1; minY := 1;
maxX :=79; maxY :=24;
quickout := false;
end;
{--------------------------------------------------------------------------}
procedure exitgame;
begin
clrscr; curson;
finalscorebiz;
port[$3d9]:=black;
textcolor(yellow);
clrscr;
end;
{--------------------------------------------------------------------------}
procedure playgame;
var
ncycles : integer;
begin
initgame;
setGameScrn;
newsnake;
repeat
ncycles := succ(ncycles);
if (ncycles mod waitsn = 0) then SnakeBiz;
updatetime;
if not bitten then
begin
if (ncycles mod waitbag = 0) then BagBiz;
if quickout then
begin
(* SetIntVec(9, OldVec); { restore int09 vector before leaving }
*)
exit;
end;
if dying then
begin
(* SetIntVec(9, OldVec); { restore int09 vector before leaving }
*)
exit;
end;
{ next 4 lines are logic for doing supervisegame
once and only once every supvtime seconds }
if elapsedtime > oldtime then tcount := succ(tcount);
if (elapsedtime > oldtime) and (tcount = supvtime) then supervisegame;
{ skips line above if elapsedtime in seconds has not changed }
if tcount > supvtime then tcount := 1;
oldtime := elapsedtime;
end;
bitten := false;
if ncycles = 32000 then ncycles := 0;
until timeleft <= 0; { end of repeat-until loop - main playgame loop }
(* SetIntVec(9, OldVec); { restore int09 vector before leaving }
*)
{ if quickout then exit;
}
exitgame;
end; { playgame and return to menu }
{============================================================================}
procedure intro;
var
tx,ty,tc,nbord : byte;
nw : integer;
begin
cursoff;
randomize;
dancedelay := 20;
textbackground(black);
clrscr;
port[$3D9] := 1+trunc(random(7));
gotoxy(1,2);
write(' ');
textcolor(SneeBdColor);
for nw := 1 to 11 do
begin
write(SneeBody);
dotick;
delay(50);
end;
textcolor(SneeHdColor); write(SneeHead);
write(' S n e e ');
sound(880);
delay(1000);
nosound;
textcolor(SneeHdColor); write(SneeHead);
textcolor(SneeBdColor);
for nw := 1 to 11 do
begin
write(SneeBody);
dotick;
delay(50);
end;
write(' ');

initgame;
bitten := true; dying := false;
minY := 3; maxY := 23;
minX := 2; maxX := 35;
deadly := false; { make the snake a Snee-Snake }
{gotoxy(minX+((maxX-minX) div 2),minY+((maxY-minY) div 2));
}
newsnake;
for nw := 1 to 100 do
begin
snakebiz;
end;
eraseOldSnake;
nosound;

gotoxy(43,2);
textcolor(SnooBdColor);
for nw := 1 to 11 do
begin
write(SnooBody);
dotick;
delay(50);
end;
textcolor(SnooHdColor); write(SnooHead);
write(' S n o o ');
sound(660);
delay(1000);
nosound;
textcolor(SnooHdColor); write(SnooHead);
textcolor(SnooBdColor);
for nw := 1 to 11 do
begin
write(SnooBody);
dotick;
delay(50);
end;

initgame;
bitten := true; dying := false;
minY := 3; maxY := 23;
minX := 45; maxX := 77;
gotoxy(minX+((maxX-minX) div 2),minY+((maxY-minY) div 2));
deadly := true; { make the snake a Snoo-Snake }
newsnake;
for nw := 1 to 100 do
begin
snakebiz;
end;
eraseOldSnake;
nosound;

window(10,5,20,12);
tc := 10+trunc(random(6));
textcolor(tc);
uptweet;
writeln(' 0000 ');
writeln(' 0 00 ');
writeln(' 00 ');
writeln(' 0000 ');
writeln(' 00 ');
writeln(' 00 0 ');
writeln(' 0000 ');
delay(100);
window(23,5,31,12);
tc := 8 + (succ(tc) mod 8);
textcolor(tc);
dntweet;
gotoxy(1,3);
writeln(' 00000 ');
writeln('00 00 ');
writeln('00 00 ');
writeln('00 00 ');
writeln('00 00');
delay(100);
window(34,5,44,12);
tc := 10+ (succ(tc) mod 6);
textcolor(tc);
uptweet;
gotoxy(1,3);
writeln(' 000 ');
writeln('00 00 ');
writeln('00 00 ');
writeln('00 000 ');
writeln(' 000 00');
delay(100);
window(44,5,56,12);
tc := 10+ (succ(tc) mod 6);
textcolor(tc);
dntweet;
writeln('00 ');
writeln(' 00 ');
writeln(' 00 00 ');
writeln(' 00 00 ');
writeln(' 0000 ');
writeln(' 00 000 ');
writeln(' 00 00');
delay(100);
window(58,5,67,12);
tc := 10+ (succ(tc) mod 6);
textcolor(tc);
uptweet;
gotoxy(1,3);
writeln(' 0000 ');
writeln('00 00 ');
writeln('00 000 ');
writeln(' 00 ');
writeln(' 00000 ');
delay(100);
window(1,1,80,25);
gotoxy(69,5);
tc := 10+ (succ(tc) mod 6);
write('TM');
delay(100);
gotoxy(1,14);textcolor(lightred);cen('Version 5.0');
gotoxy(1,16);
cenln('Copyright (C) 1986, 1987, 1989 by Bruce L. Rosenberg');
gotoxy(1,19);
cenln('Version 5.0 of SNEESNOO SNAKE TM has arrived!');
cenln
('Alright, folks, here''s the scoop. I really want to run that');
cenln
('$10,000.00 INTERNATIONAL S N E E S N O O S N A K E (TM) CONTEST');
cenln
('by the end of 1990; but it''s up to you. I need 5000 $10 checks to do it.');
cenln
('If you hotshot SNEESNOO SNAKERS want a chance at the prize, form a club!');
cenln
('Let the AUTO DEMO run for a while. Can you beat the Robot''s scores?');
gotoxy(1,25);
curson;
if autodem then AutoContinue else PressToContinue;
end;
{--------------------------------------------------------------------------}
procedure instruct;
begin
clrscr;
textcolor(lightgreen);
cenln(' INSTRUCTIONS FOR THE GAME OF SNEESNOO SNAKE TM');
writeln;
writeln
('You are a herpetologist for Megalop Zoo. Your assignment is to go to the ');
writeln
('Foetid Forest of Amazonia and catch rare SneeSnoo Snakes. Poisonous Snoo''s');
write
('head is a white ');
write(SnooHead);
write(' & it''s body is a cyan ');
write(SnooBody);
writeln('. Nonvenomous Snee''s head is');
write
('a red ',SneeHead,' & it''s body is a green ');
write(SneeBody);
writeln('. You control movement of a bag,');
writeln
('which is a rectangle. To catch the snake you close the bag. SneeSnoo can ');
writeln
('enter from any side. Closing bag with the Snee head inside , gets 1 snake,');
writeln
('or 4 snakes if a Snoo. If outside bag, but within striking distance, it ');
writeln
('bites and you drop 1 snake, 2 if venomous. Five venomous bites & you DIE!!');
writeln
('Your score is the total number of snakes bagged per minute. You have a time');
writeln
('limit. Time in seconds remaining is shown in the lower right. Good Luck!');
writeln;
textcolor(lightred);
writeln;
cen('C O N T R O L K E Y S');
writeln('
');
cenln('"Y" key moves bag up. ');
cenln('"B" key moves bag down. ');
cenln('"H" key moves bag right.');
cenln('"G" key moves bag left. ');
textcolor(lightgreen);
writeln;
cenln('Space bar closes bag. ESC aborts to DOS during play.');
if autodem then AutoContinue else PressToContinue;
end;
{----------------------------------------------------------------------------}
procedure moreinfo;
begin
clrscr;textcolor(lightgreen);
gotoxy(1,1);
cen(' FURTHER INFORMATION ON THE GAME OF SNEESNOO SNAKE TM ');
gotoxy(1,3);textcolor(yellow);
cenln
('This game was written in TurboPascal 5.5 (TM Borland International). ');
cenln
('It consists of over 1300 lines of code. Although copyrighted by');
cenln
('the author, Bruce L. Rosenberg, approval is given for noncommercial');
cenln
('use and distribution by users'' groups (at a nominal fee) and for placing');
cenln
('on private computer bulletin boards. Consideration will be given to');
cenln
('offers from commercial firms regarding licensing on a royalty basis.');
writeln;
cenln
('Send a $10.00 check for latest version on disk (plus source), and to be');
cenln
('notified about the $10,000.00 INTERNATIONAL SNEESNOO SNAKE CONTEST. This');
cenln
('contest will be held after 5,000 people send $10 each. It''s up to you!');
cenln(
'This offer is for personal use and is not a license for commercial use.');
writeln;
cenln
('Send inquiries and checks to : ');
writeln;
cenln('Bruce L. Rosenberg');
cenln('23 N. Chelsea Avenue');
cenln('Atlantic City, NJ 08401');
writeln;
cenln
('Any suggestions for improvements or ideas for games can be mailed to');
cenln
('the above address, via voice phone evenings at (609) 345-4712, or');
cenln
('leave message on Compuserve, 73547,402.');
if autodem then AutoContinue else PressToContinue;
end;
{----------------------------------------------------------------------------}
procedure options;
var
resp : char;
begin
clrscr;
setvidmode;
soundon := false;
write('Do you want sound? (Y or N) : ');
repeat resp := getKey; until upcase(resp) in ['Y','N'];
if upcase(resp)='Y' then
begin
soundon := true;
upscale;
end;
writeln;
writeln;
if not(monochrome) then
begin
write('You are using a color graphics adapter card.');
textcolor(lightgreen);
writeln;
writeln('And this message should be green on color monitors.');
writeln;
textcolor(yellow);
end else
begin
textcolor(15);
writeln;
Writeln('You are using a monochrome adapter (this should be bright).');
textcolor(7);
writeln('Whereas this message should be dim.');
textcolor(yellow);
end;
writeln;writeln;
write('Do you want to reset all the high scores? (Y or N) : ');
repeat resp := GetKey until upcase(resp) in ['Y','N'];
if (upcase(resp) = 'Y') then
begin
writeln;writeln;
textcolor(white);
write('Press "Y" again to confirm : ');
resp := 'N';
repeat resp := Getkey until upcase(resp) in ['Y','N'];
if (upcase(resp) = 'Y') then
begin
zeroscorearray;
writescorearray;
writeln;writeln;
textcolor(yellow);
writeln('All scores set to zero, history about to be made.');
writeln;writeln;
end; { confirm reset all scores }
end; { first time ask reset scores }
if autodem then AutoContinue else PressToContinue;
end; { options }
{----------------------------------------------------------------------------}
procedure showoff;
begin
showoff_init;
repeat
playgame;
if dying then die; if not autodem then exit;
instruct; if not autodem then exit;
playgame;
if dying then die; if not autodem then exit;
intro; if not autodem then exit;
playgame;
if dying then die; if not autodem then exit;
moreinfo; if not autodem then exit;
until not autodem
end;
{----------------------------------------------------------------------------}
procedure menu;
var
ch : char;
begin
demo := false;
autodem := false;
clrscr;textcolor(lightgreen); port[$3D9] := blue; { sets border }
gotoxy(1,2);
cen('M A I N M E N U F O R S N E E S N O O S N A K E (TM)');
gotoxy(1, wherey + 3);
cen('1. BEGINNING SCREEN ');
gotoxy(1, wherey + 2);
cen('2. GAME INSTRUCTIONS ');
gotoxy(1, wherey + 2);
cen('3. FURTHER INFORMATION');
gotoxy(1, wherey + 2);
cen('4. PLAY GAME ');
gotoxy(1, wherey + 2);
cen('5. AUTO-DEMO ');
gotoxy(1, wherey + 2);
cen('6. DISPLAY SCORES ');
gotoxy(1, wherey + 2);
cen('7. CHANGE OPTIONS ');
gotoxy(1, wherey + 2);
cen('8. EXIT TO DOS ');
gotoxy(1,25);textcolor(white);
write('Please choose one of the above numbers (1 to 8) ... ');
gotoxy(54,25);
repeat menusel := GetKey;
if not (menusel in ['1'..'8']) then
begin
gotoxy(54,25);
write('Wrong key, try again. ');
write(chr(7));
gotoxy(54,25);
clreol;
end;
until menusel in ['1' .. '8'];
dntweet;
uptweet;
case menusel of
'1': intro;
'2': instruct;
'3': moreinfo;
'4': begin
playgame;
if dying then die;
if quickout then
begin
menusel :='8';
exit;
end;
end;
'5': begin
autodem := true;
demo := true;
showoff
end;
'6': begin
readscorearray;
listscores;
end;
'7': options;
'8': exit;
else menu;
end;
end;
{----------------------------------------------------------------------------}
procedure prelimbiz;
begin
nrobo := 0;
clrscr;
censcr('Please wait, checking CPU speed.');
CPUspeed := pctime/chkspeed;
gotoxy(wherex - 32,wherey +2);
write('Speed Relative to IBM PC = ');
write(CPUspeed:5:3);
delay(2500);
clrscr;
end;
{----------------------------------------------------------------------------}
procedure farewell;
begin
curson;
clrscr;
gotoxy(1,10);
cen('Thanks for playing S N E E S N O O S N A K E TM !');
gotoxy(1,12);
cen('Copyright (C) 1986, 1987, 1989 by Bruce L. Rosenberg');
delay(2000);
clrscr;
end;
{----------------------------------------------------------------------------}
BEGIN {MAIN PROGRAM}
prelimbiz; { check CPU speed so game will run same on all PCs. }
initialize;
readscorearray; {checks to see if file there, if not, makes it}
(* intro; { display introductory screen }
if autodem then showoff;
initialize;
*)
repeat menu until menusel = '8';
{ if not quickout then farewell;
}
END.
{============================================================================}
{============================================================================}
{$I-} {$R-} {$S-}
program KeyIn; {compile this to an EXE with TPC, then run it)}
{ by Michael Day }
uses crt,dos; {Example: C>TPC KEYIN }
var KeyScan,OldScan : byte;
ch : char;
OldVec,exitsave : pointer;
{$f+}
procedure Myexit;
{$f-}
begin
if exitcode <> 0 then setintvec(9,oldvec);
exitproc := exitsave;
end;

procedure ReadScan; interrupt;


begin
KeyScan := port[$60];
inline($9C/$FF/$1E/OldVec); {call old int vector}
end;

begin
exitsave := exitproc;
exitproc := @myexit;
GetIntVec(9, OldVec);
SetIntVec(9, @ReadScan);
repeat
{ if oldscan <> keyscan then
}
write(keyscan:4);
OldScan := KeyScan;
(* if keypressed then ch := readkey; { clears dos key buffer }
*)
until false; {ch = #27; }
SetIntVec(9, OldVec);
end.

You might also like