pascalabcnet/TestSamples/CompilationSamples/LifeU.pas

324 lines
6.5 KiB
ObjectPascal
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

unit LifeU;
uses Utils,GraphABC;
const
w=4;
w1=1;
m=300;
n=220;
x0=2;
y0=20;
mm=301;
nn=221;
mk=15;
nk=10;
var
a,b,sosedia,sosedib: array [0..nn,0..mm] of integer;
obnovA,obnovB: array [1..nk,1..mk] of boolean;
count: integer;
obn: boolean;
gen,mil,mil1: integer;
hn,hm: integer;
procedure DrawCell(i,j: integer);
begin
SetBrushColor(clBlack);
SetPenColor(clBlack);
FillRect(x0+(j-1)*w,y0+(i-1)*w,x0+j*w-w1,y0+i*w-w1);
end;
procedure ClearCell(i,j: integer);
begin
SetBrushColor(clWhite);
SetPenColor(clWhite);
FillRect(x0+(j-1)*w,y0+(i-1)*w,x0+j*w-w1,y0+i*w-w1);
end;
procedure DrawConfiguration;
var i,j,bb: integer;
begin
for i:=1 to n do
for j:=1 to m do
begin
bb:=b[i,j];
if a[i,j]<>bb then
if bb=1 then DrawCell(i,j)
else ClearCell(i,j);
end;
end;
procedure DrawConfigurationFull;
var i,j,bb: integer;
begin
for i:=1 to n do
for j:=1 to m do
begin
bb:=b[i,j];
if bb=1 then DrawCell(i,j)
else ClearCell(i,j);
end;
end;
procedure DrawField;
var i: integer;
begin
SetPenColor(clLightGray);
for i:=0 to m do
begin
if i mod hm = 0 then
SetPenColor(clGray)
else SetPenColor(clLightGray);
Line(x0+i*w-1,y0,x0+i*w-1,y0+n*w);
end;
for i:=0 to n do
begin
if i mod hn = 0 then
SetPenColor(clGray)
else SetPenColor(clLightGray);
Line(x0,y0+i*w-1,x0+m*w,y0+i*w-1);
end;
end;
procedure IncSosedi(i,j: integer);
var i1,i2,j1,j2: integer;
begin
if i=1 then i1:=n else i1:=i-1;
if i=n then i2:=1 else i2:=i+1;
if j=1 then j1:=m else j1:=j-1;
if j=m then j2:=1 else j2:=j+1;
Inc(SosediB[i1,j1]);
Inc(SosediB[i1,j]);
Inc(SosediB[i1,j2]);
Inc(SosediB[i,j1]);
Inc(SosediB[i,j2]);
Inc(SosediB[i2,j1]);
Inc(SosediB[i2,j]);
Inc(SosediB[i2,j2]);
end;
procedure DecSosedi(i,j: integer);
var i1,i2,j1,j2: integer;
begin
if i=1 then i1:=n else i1:=i-1;
if i=n then i2:=1 else i2:=i+1;
if j=1 then j1:=m else j1:=j-1;
if j=m then j2:=1 else j2:=j+1;
Dec(SosediB[i1,j1]);
Dec(SosediB[i1,j]);
Dec(SosediB[i1,j2]);
Dec(SosediB[i,j1]);
Dec(SosediB[i,j2]);
Dec(SosediB[i2,j1]);
Dec(SosediB[i2,j]);
Dec(SosediB[i2,j2]);
end;
procedure SetCell(i,j: integer);
begin
if b[i,j]=0 then
begin
b[i,j]:=1;
obn:=true;
IncSosedi(i,j);
end;
Inc(count);
end;
procedure UnSetCell(i,j: integer);
begin
if b[i,j]=1 then
begin
b[i,j]:=0;
obn:=true;
DecSosedi(i,j);
end;
Dec(count);
end;
procedure Init;
var i,j,ik,jk,xc,yc: integer;
begin
xc:=n div 2;
yc:=m div 2;
// xc:=1;
// yc:=1;
for i:=0 to n+1 do
for j:=0 to m+1 do
b[i,j]:=0;
a:=b;
sosedib:=b;
Count:=0;
SetCell(xc,yc);
SetCell(xc,yc+1);
SetCell(xc,yc+2);
SetCell(xc-1,yc+2);
SetCell(xc+1,yc+1);
SosediA:=SosediB;
for ik:=1 to nk do
for jk:=1 to mk do
obnovB[ik,jk]:=true;
obnovA:=obnovB;
end;
procedure OnlyCase(i,j: integer);
begin
case SosediA[i,j] of
0..1,4..9:
if b[i,j]=1 then
begin
b[i,j]:=0;
obn:=true;
DecSosedi(i,j);
ClearCell(i,j);
Dec(count);
end;
3: if b[i,j]=0 then
begin
b[i,j]:=1;
obn:=true;
IncSosedi(i,j);
DrawCell(i,j);
Inc(count);
end;
end; {case}
end;
procedure NextGen;
var
i,j,ik,jk,ik1,jk1,ik2,jk2,ifirst,jfirst,ilast,jlast: integer;
l,r,u,d,lu,ld,ru,rd: boolean;
begin
for ik:=1 to nk do
begin
for jk:=1 to mk do
begin
obn:=false;
ifirst:=(ik-1)*hn+1;
ilast:=(ik-1)*hn+hn;
jfirst:=(jk-1)*hm+1;
jlast:=(jk-1)*hm+hm;
if obnovA[ik,jk] then
begin
for i:=ifirst to ilast do
begin
for j:=jfirst to jlast do
begin
case SosediA[i,j] of
0..1,4..9: if b[i,j]=1 then
begin
b[i,j]:=0;
obn:=true;
DecSosedi(i,j);
ClearCell(i,j);
Dec(count);
end;
3: if b[i,j]=0 then
begin
b[i,j]:=1;
obn:=true;
IncSosedi(i,j);
DrawCell(i,j);
Inc(count);
end;
end; {case}
end;
end
end
else
begin
if ik=1 then ik1:=nk else ik1:=ik-1;
if ik=nk then ik2:=1 else ik2:=ik+1;
if jk=1 then jk1:=mk else jk1:=jk-1;
if jk=mk then jk2:=1 else jk2:=jk+1;
l:=obnovA[ik,jk1];
r:=obnovA[ik,jk2];
u:=obnovA[ik1,jk];
d:=obnovA[ik2,jk];
lu:=obnovA[ik1,jk1];
ld:=obnovA[ik2,jk1];
ru:=obnovA[ik1,jk2];
rd:=obnovA[ik2,jk2];
if u then
begin
i:=ifirst;
for j:=jfirst+1 to jlast-1 do
OnlyCase(i,j);
end;
if d then
begin
i:=ilast;
for j:=jfirst+1 to jlast-1 do
OnlyCase(i,j);
end;
if l then
begin
j:=jfirst;
for i:=ifirst+1 to ilast-1 do
OnlyCase(i,j);
end;
if r then
begin
j:=jlast;
for i:=ifirst+1 to ilast-1 do
OnlyCase(i,j);
end;
if u or l or lu then
OnlyCase(ifirst,jfirst);
if u or r or ru then
OnlyCase(ifirst,jlast);
if d or l or ld then
OnlyCase(ilast,jfirst);
if d or r or rd then
OnlyCase(ilast,jlast);
end;
obnovB[ik,jk]:=obn;
end;
end;
end;
procedure Start;
begin
SetWindowCaption('Игра "Жизнь"');
if (m mod mk<>0) or (n mod nk<>0) then
begin
writeln('Размер кластера не согласован с размером поля. Программа завершена');
exit
end;
hm:=m div mk;
hn:=n div nk;
Cls;
SetWindowSize(x0+m*w,y0+n*w);
CenterWindow;
SetFontName('Arial');
SetFontSize(10);
Init;
TextOut(25,0,'Поколение '+IntToStr(gen));
TextOut(765,0,'Жителей: '+IntToStr(count)+' ');
DrawField;
DrawConfiguration;
mil:=Milliseconds;
gen:=0;
while true do
begin
gen:=gen+1;
SetBrushColor(clWhite);
TextOut(25,0,'Поколение: '+IntToStr(gen));
TextOut(765,0,'Жителей: '+IntToStr(count)+' ');
a:=b;
SosediA:=SosediB;
obnovA:=obnovB;
NextGen;
if gen mod 1000 = 0 then
begin
mil1:=Milliseconds;
writeln(gen,' ',(mil1-mil)/1000);
mil:=mil1;
end;
end;
end;
end.