110 lines
4.5 KiB
Plaintext
110 lines
4.5 KiB
Plaintext
def Width=40, Height=25-1, \playing area including border
|
|
StartLength = 10, \starting length of snake including head
|
|
Morsels = 10; \number of food items constantly offered
|
|
int Heading; \direction snake is heading
|
|
def Up, Down, Left, Right;
|
|
int Length, \current length of snake including head
|
|
Score; \number of food items eaten
|
|
char SnakeX(10000), \location of each segment including head
|
|
SnakeY(10000), \ample room to grow
|
|
FoodX(Morsels), FoodY(Morsels); \location of each food item
|
|
def Black, Blue, Green, Cyan, Red, Magenta, Brown, White, \attribute colors
|
|
Gray, LBlue, LGreen, LCyan, LRed, LMagenta, Yellow, BWhite; \EGA palette
|
|
|
|
proc PlaceFood(N); \Place Nth food item in playing area
|
|
int N;
|
|
[FoodX(N):= Ran(Width-3) + 1; \pick random location inside borders
|
|
FoodY(N):= Ran(Height-3) + 1;
|
|
Cursor(FoodX(N), FoodY(N)); \show food
|
|
Attrib(Red<<4+LRed);
|
|
ChOut(6, ^@);
|
|
]; \PlaceFood
|
|
|
|
|
|
int X, Y, I, C;
|
|
[SetVid($01); \set 40x25 text mode
|
|
ShowCursor(false); \turn off flashing cursor
|
|
|
|
Attrib(Blue<<4+LBlue); \show borders
|
|
Cursor(0, 0);
|
|
for X:= 0 to Width-1 do ChOut(6, ^+);
|
|
Cursor(0, Height-1);
|
|
for X:= 0 to Width-1 do ChOut(6, ^+);
|
|
for Y:= 0 to Height-1 do
|
|
[Cursor(0, Y); ChOut(6, ^+);
|
|
Cursor(Width-1, Y); ChOut(6, ^+);
|
|
];
|
|
Attrib(Black<<4+White); \show initial score
|
|
Cursor(0, 24);
|
|
Text(6, "Score: 0");
|
|
Score:= 0;
|
|
|
|
SnakeX(0):= Width/2; \start snake head at center
|
|
SnakeY(0):= Height/2;
|
|
Heading:= Left;
|
|
Length:= StartLength;
|
|
for I:= 1 to Length-1 do \segments follow head to the right
|
|
[SnakeX(I):= SnakeX(I-1) + 1;
|
|
SnakeY(I):= SnakeY(I-1);
|
|
];
|
|
for I:= 0 to Morsels-1 do PlaceFood(I); \sow some tasty food
|
|
|
|
\Continuously move snake
|
|
loop \--------------------------------------------------------------------------
|
|
[Attrib(Black<<4+White); \remove tail-end segment
|
|
Cursor(SnakeX(Length-1), SnakeY(Length-1));
|
|
ChOut(6, ^ );
|
|
Attrib(Green<<4+Yellow); \add segment at head location
|
|
Cursor(SnakeX(0), SnakeY(0));
|
|
ChOut(6, ^#);
|
|
|
|
\Shift coordinates toward tail (+1 in case a segment gets added)
|
|
for I:= Length downto 1 do \segment behind head gets head's coords
|
|
[SnakeX(I):= SnakeX(I-1);
|
|
SnakeY(I):= SnakeY(I-1);
|
|
];
|
|
if ChkKey then \key hit--get new movement direction
|
|
[repeat C:= ChIn(1) until C # 0; \remove arrow keys' prefix byte
|
|
case C of
|
|
$1B: exit; \Escape, and scan codes for arrow keys
|
|
$48: if Heading # Down then Heading:= Up;
|
|
$50: if Heading # Up then Heading:= Down;
|
|
$4B: if Heading # Right then Heading:= Left;
|
|
$4D: if Heading # Left then Heading:= Right
|
|
other []; \ignore any other keystrokes
|
|
];
|
|
case Heading of \move head to its new location
|
|
Up: SnakeY(0):= SnakeY(0)-1;
|
|
Down: SnakeY(0):= SnakeY(0)+1;
|
|
Left: SnakeX(0):= SnakeX(0)-1;
|
|
Right:SnakeX(0):= SnakeX(0)+1
|
|
other [];
|
|
Cursor(SnakeX(0), SnakeY(0)); \show head at its new location
|
|
ChOut(6, ^8);
|
|
|
|
for I:= 0 to Morsels-1 do
|
|
if SnakeX(0)=FoodX(I) & SnakeY(0)=FoodY(I) then
|
|
[Score:= Score+1; \ate a morsel
|
|
Attrib(Black<<4+White);
|
|
Cursor(7, 24);
|
|
IntOut(6, Score*10);
|
|
PlaceFood(I); \replenish morsel
|
|
Length:= Length+1; \grow snake one segment
|
|
I:= Morsels; \over eating can be bad--quit for loop
|
|
Sound(1, 1, 1500); \BURP!
|
|
Sound(1, 1, 1000);
|
|
];
|
|
if I = Morsels then Sound(0, 2, 1); \no sound adds delay of 2/18th second
|
|
|
|
if SnakeX(0)=0 or SnakeX(0)=Width-1 or
|
|
SnakeY(0)=0 or SnakeY(0)=Height-1 then
|
|
quit; \snake hit border--game over
|
|
for I:= 1 to Length-1 do
|
|
if SnakeX(0)=SnakeX(I) & SnakeY(0)=SnakeY(I) then
|
|
quit; \snake bit itself--game over
|
|
]; \loop -----------------------------------------------------------------------
|
|
for I:= 1 to 8 do Sound(1, 1, 4000*I); \death dirge
|
|
Sound(0, 36, 1); \pause 2 seconds to see result
|
|
OpenI(1); \flush any pending keystrokes
|
|
]
|