home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
mbug
/
mbug130.arc
/
LIFE.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1979-12-31
|
13KB
|
372 lines
program life;
{ LIFE.PAS - Game of life
Written by Keith Wood 03/09/89 }
type area = array [0..1049] of byte;
const init_pcg : array [1..2,0..15] of byte =
{ bee = '(' and ')' }
((60,67,68,36,28,99,132,137,114,28,7,0,0,0,0,0),
(240,8,8,16,32,240,152,44,76,184,224,0,0,0,0,0));
var board : array [0..24,0..41] of byte;
board2 : area absolute board;
x_curs, y_curs : byte;
num_gen : integer;
finished, stepping : boolean;
load_pcg : byte absolute $FA80;
{$I JOYSTICK.INC}
procedure draw_board;
type screen = array [1..23,1..80] of byte;
const full1 = $A8;
full2 = $A9;
empty = $20;
var x, y : byte;
scr_ram : screen absolute $F000;
scr_set : screen;
begin
for y := 1 to 23 do
begin
board[y,0] := 0; board[y,41] := 0;
for x := 1 to 40 do
if board[y,x]=0 then
begin
scr_set[y,2*x-1] := empty; scr_set[y,2*x] := empty
end
else
begin
scr_set[y,2*x-1] := full1; scr_set[y,2*x] := full2
end
end;
scr_ram := scr_set;
lowvideo; gotoxy(24,24); write(num_gen:5); normvideo;
gotoxy(1,25)
end;
procedure next_generation;
var n : byte;
m, ul, up, ur, lf, rt, dl, dn, dr : integer;
next : area;
begin
next := board2;
ul := 0; up := 1; ur := 2; lf := 42; rt := 44; dl := 84; dn := 85; dr := 86;
for m := 43 to 1006 do
begin
n := next[ul]+next[up]+next[ur]+next[lf]+next[rt]+next[dl]+next[dn]+next[dr];
case n of
0,1,4..8 : board2[m] := 0; { loneliness or overcrowding }
3 : board2[m] := 1 { birth }
end;
ul := ul+1; up := up+1; ur := ur+1; lf := lf+1;
rt := rt+1; dl := dl+1; dn := dn+1; dr := dr+1
end;
num_gen := num_gen+1;
draw_board
end;
procedure write_options(placing : boolean);
begin
gotoxy(36,24);
if placing then
begin
write('ASDFEX'); lowvideo; write(' Move '); normvideo; write(' ');
lowvideo; write(' Select '); normvideo; write('0');
lowvideo; write(' Clear '); normvideo; write('P');
lowvideo; write('attern '); normvideo; write('B');
lowvideo; write('egin '); normvideo
end
else
begin
lowvideo; write(' '); normvideo; write('S');
lowvideo; write('tep '); normvideo; write('R');
lowvideo; write('un '); normvideo; write('P');
lowvideo; write('lace '); normvideo; write('Q');
lowvideo; write('uit '); normvideo
end;
gotoxy(1,25)
end;
procedure clear_board;
begin
fillchar(board,1050,0);
num_gen := 1;
draw_board
end;
procedure patterns;
const glider : array [1..3,1..3] of byte =
((0,1,0),(0,0,1),(1,1,1));
blinker : array [1..3,1..9] of byte =
((1,0,0,0,0,0,0,0,1),(1,0,0,1,1,1,0,0,1),(1,0,0,0,0,0,0,0,1));
rocker : array [1..4,1..4] of byte =
((0,1,0,0),(0,0,1,1),(1,1,0,0),(0,0,1,0));
conveyor : array [1..9,1..9] of byte =
((1,1,0,0,0,0,0,0,0),(1,0,1,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0),
(0,0,1,0,1,0,0,0,0),(0,0,0,0,0,0,0,0,0),(0,0,0,0,1,0,1,0,0),
(0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,1,0,1),(0,0,0,0,0,0,0,1,1));
distributor : array [1..12,1..12] of byte =
((0,0,0,0,0,0,1,1,0,0,0,0),(0,0,0,0,0,0,1,1,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,0,1,1,1,1,0,0,0,0),
(1,1,0,1,0,0,0,0,1,0,0,0),(1,1,0,1,0,0,0,1,1,0,0,0),
(0,0,0,1,0,1,0,0,1,0,1,1),(0,0,0,1,0,0,1,0,1,0,1,1),
(0,0,0,0,1,1,1,1,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,1,1,0,0,0,0,0,0),(0,0,0,0,1,1,0,0,0,0,0,0));
heart : array [1..13,1..13] of byte =
((0,0,0,0,1,1,0,1,1,0,0,0,0),(0,0,0,0,1,0,0,0,1,0,0,0,0),
(0,0,0,0,0,1,1,1,0,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,0,0,0),
(1,1,0,0,0,1,1,1,0,0,0,1,1),(1,0,1,0,1,0,0,0,1,0,1,0,1),
(0,0,1,0,1,0,0,0,1,0,1,0,0),(1,0,1,0,1,0,0,0,1,0,1,0,1),
(1,1,0,0,0,1,1,1,0,0,0,1,1),(0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,1,1,1,0,0,0,0,0),(0,0,0,0,1,0,0,0,1,0,0,0,0),
(0,0,0,0,1,1,0,1,1,0,0,0,0));
bounce : array [1..11,1..14] of byte =
((0,0,0,0,0,1,1,0,0,0,0,0,0,0),(0,0,0,0,0,1,1,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),(1,1,0,0,0,1,1,1,1,0,0,0,1,1),
(1,0,1,0,1,0,0,0,0,1,0,1,0,1),(0,0,1,0,1,1,0,0,0,1,0,1,0,0),
(1,0,1,0,1,0,0,0,0,1,0,1,0,1),(1,1,0,0,0,1,1,1,1,0,0,0,1,1),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,1,1,0,0,0,0,0),
(0,0,0,0,0,0,0,1,1,0,0,0,0,0));
jays : array [1..6,1..9] of byte =
((0,0,1,1,0,1,1,0,0),(0,0,0,0,0,0,0,0,0),
(0,0,0,1,0,1,0,0,0),(0,0,0,1,0,1,0,0,0),
(1,1,0,1,0,1,0,1,1),(0,1,1,0,0,0,1,1,0));
diamond : array [1..8,1..8] of byte =
((0,0,0,1,1,0,0,0),(0,0,1,0,0,1,0,0),
(0,1,0,0,0,0,1,0),(1,0,0,0,0,0,0,1),
(1,0,0,0,0,0,0,1),(0,1,0,0,0,0,1,0),
(0,0,1,0,0,1,0,0),(0,0,0,1,1,0,0,0));
cycle1 : array [1..8,1..8] of byte =
((0,0,0,0,1,0,0,0),(1,1,1,1,0,1,0,0),
(1,1,1,0,1,0,1,0),(0,0,0,0,0,1,0,1),
(0,0,0,0,0,0,1,0),(0,0,0,0,0,1,1,0),
(0,0,0,0,0,1,1,0),(0,0,0,0,0,1,1,0));
cycle2 : array [1..7,1..7] of byte =
((0,0,0,1,1,0,0),(0,1,0,1,0,0,0),(1,0,0,0,0,0,1),
(0,1,0,0,0,1,1),(0,0,0,0,0,0,0),
(0,0,0,1,0,1,0),(0,0,0,0,1,0,0));
cycle3 : array [1..13,1..13] of byte =
((0,0,1,1,1,0,0,0,1,1,1,0,0),(0,0,0,0,0,0,0,0,0,0,0,0,0),
(1,0,0,0,0,1,0,1,0,0,0,0,1),(1,0,0,0,0,1,0,1,0,0,0,0,1),
(1,0,0,0,0,1,0,1,0,0,0,0,1),(0,0,1,1,1,0,0,0,1,1,1,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0),(0,0,1,1,1,0,0,0,1,1,1,0,0),
(1,0,0,0,0,1,0,1,0,0,0,0,1),(1,0,0,0,0,1,0,1,0,0,0,0,1),
(1,0,0,0,0,1,0,1,0,0,0,0,1),(0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,1,1,1,0,0,0,1,1,1,0,0));
var x, y : byte;
ch : char;
scr_ram : byte absolute $F000;
begin
fillchar(scr_ram,23*80,' ');
gotoxy(32,2); write('A Glider');
gotoxy(32,3); write('B Blinker');
gotoxy(32,4); write('C Rocker');
gotoxy(32,5); write('D Conveyor');
gotoxy(32,6); write('E Distributor');
gotoxy(32,7); write('F Heart');
gotoxy(32,8); write('G Bounce');
gotoxy(32,9); write('H Jays');
gotoxy(32,10); write('I Diamond');
gotoxy(32,11); write('J Cycle 1');
gotoxy(32,12); write('K Cycle 2');
gotoxy(32,13); write('L Cycle 3');
gotoxy(32,20); write('Select pattern');
gotoxy(1,25);
repeat
read(kbd,ch); ch := upcase(ch)
until ch in ['A'..'L','Q'];
if ch<>'Q' then
begin
fillchar(board,1050,0);
case ch of
'A' : for y := 1 to 3 do for x := 1 to 3 do
board[y+1,x+1] := glider[y,x];
'B' : for y := 1 to 3 do for x := 1 to 9 do
board[y+10,x+15] := blinker[y,x];
'C' : for y := 1 to 4 do for x := 1 to 4 do
board[y+10,x+18] := rocker[y,x];
'D' : for y := 1 to 9 do for x := 1 to 9 do
board[y+7,x+15] := conveyor[y,x];
'E' : for y := 1 to 12 do for x := 1 to 12 do
board[y+5,x+14] := distributor[y,x];
'F' : for y := 1 to 13 do for x := 1 to 13 do
board[y+5,x+13] := heart[y,x];
'G' : for y := 1 to 11 do for x := 1 to 14 do
board[y+6,x+13] := bounce[y,x];
'H' : for y := 1 to 6 do for x := 1 to 9 do
board[y+8,x+15] := jays[y,x];
'I' : for y := 1 to 8 do for x := 1 to 8 do
board[y+8,x+16] := diamond[y,x];
'J' : for y := 1 to 8 do for x := 1 to 8 do
board[y+8,x+16] := cycle1[y,x];
'K' : for y := 1 to 7 do for x := 1 to 7 do
board[y+8,x+16] := cycle2[y,x];
'L' : for y := 1 to 13 do for x := 1 to 13 do
board[y+5,x+13] := cycle3[y,x]
end;
num_gen := 1
end;
draw_board
end;
procedure move_up;
begin
if y_curs>1 then y_curs := y_curs-1
end;
procedure move_down;
begin
if y_curs<23 then y_curs := y_curs+1
end;
procedure move_left;
begin
if x_curs>1 then x_curs := x_curs-1
end;
procedure move_right;
begin
if x_curs<40 then x_curs := x_curs+1
end;
procedure move_left_lots;
begin
if x_curs<5 then x_curs := 1 else x_curs := x_curs-4
end;
procedure move_right_lots;
begin
if x_curs>36 then x_curs := 40 else x_curs := x_curs+4
end;
procedure select;
begin
board[y_curs,x_curs] := 1-board[y_curs,x_curs]; gotoxy(2*x_curs-1,y_curs);
if board[y_curs,x_curs]=0 then write(' ')
else begin lowvideo; write('()'); normvideo end;
gotoxy(1,25)
end;
procedure placement;
var ch : char;
j : byte;
begin
write_options(true);
repeat
repeat
gotoxy(2*x_curs-1,y_curs); lowvideo; write(' ');
normvideo; gotoxy(1,25); delay(30);
gotoxy(2*x_curs-1,y_curs); write(' '); gotoxy(1,25); delay(30);
gotoxy(2*x_curs-1,y_curs);
if board[y_curs,x_curs]=0 then write(' ')
else begin lowvideo; write('()'); normvideo end;
gotoxy(1,25); delay(30);
j := joystick
until keypressed or (j>0);
if keypressed then
begin
read(kbd,ch); ch := upcase(ch)
end
else
begin
ch := #$00;
if (j and $80)>0 then ch := ' '
else if (j and $08)>0 then ch := 'D'
else if (j and $04)>0 then ch := 'S'
else if (j and $02)>0 then ch := 'X'
else if (j and $01)>0 then ch := 'E'
end;
case ch of
'E',^E : move_up;
'X',^X : move_down;
'S',^S : move_left;
'D',^D : move_right;
'A' : move_left_lots;
'F' : move_right_lots;
' ' : select;
'0' : clear_board;
'P' : patterns
end
until ch = 'B';
write_options(false)
end;
procedure initialise;
var ch : char;
begin
clrscr;
check_joy;
init_joystick;
move(init_pcg,load_pcg,32);
gotoxy(30,2); write('Conway''s Game of Life');
gotoxy(15,4); write('The board consists of an array of 40 by 23 cells,');
gotoxy(15,5); write('each of which can be either occupied or empty.');
gotoxy(15,7); write('New generations are formed by examining each cell :');
gotoxy(15,9); write('If it is occupied and has less than two neighbours');
gotoxy(15,10); write('(including diagonals) then it will die from loneliness.');
gotoxy(15,12); write('It it is occupied and has more then three neighbours');
gotoxy(15,13); write('then it will die from overcrowding.');
gotoxy(15,15); write('If it is empty and has exactly three neighbours');
gotoxy(15,16); write('then it will become occupied (a birth).');
gotoxy(15,18); write('Several patterns are defined for your use.');
gotoxy(29,20); write('Press any key to start.');
repeat until keypressed or (joystick>$80);
if keypressed then read(kbd,ch)
else init_joystick;
clrscr;
lowvideo;
gotoxy(2,24); write(' LIFE Generation :',' ':57);
normvideo;
write_options(false);
clear_board;
x_curs := 20; y_curs := 12;
finished := false; stepping := true;
placement
end;
procedure finalise;
var m : integer;
pcg_rom : byte absolute $F000;
pcg_ram : array [1..2048] of byte absolute $F800;
begin
clrscr;
port[11] := 1;
move(pcg_rom,pcg_ram,2048);
port[11] := 0;
for m := 1 to 2048 do pcg_ram[m] := not pcg_ram[m]
end;
procedure process_actions;
var ch : char;
begin
next_generation;
if stepping then
begin
gotoxy(33,24); write('Press key'); gotoxy(1,25);
repeat until keypressed;
gotoxy(33,24); lowvideo; write(' ');
normvideo; gotoxy(1,25)
end;
if keypressed then
begin
read(kbd,ch); ch := upcase(ch)
end
else ch := #$00;
case ch of
'S' : stepping := true;
'R' : stepping := false;
'P' : placement;
'Q' : finished := true
end
end;
begin
initialise;
repeat
process_actions
until finished;
finalise
end.