Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курсовая САПЕР.docx
Скачиваний:
46
Добавлен:
27.10.2018
Размер:
560.83 Кб
Скачать

6. Результати роботи програмного продукту

На рисунках 6.1 – 6.3 представлені результати роботи програми у вигляді скріншотів.

Рисунки 6.1 та 6.2 демонструють процеси еволюції різних популяцій клітин при різному масштабі ігрового поля:

Рисунок 6.3 демонструє дію алгоритму розфарбування на довільний популяції:

Рис 6.1 Робота програми при великому масштабі

Рис 6.2 Робота програми за малого масштабу

Рис 6.3 Робота алгоритму розфарбування

Висновки

В ході цієї роботи було розроблено програмний продукт – ігрову програму «Game Life», що є комп’ютерною реалізацією гри «Життя», винайденої Дж. Конвеєм. Отримана розробка є класичною версією гри. Реалізовано гру на двовимірній ортогональній площині за стандартними правилами; реалізовано гру на торообразній поверхні, а також обмежених поверхнях з різним типом меж; розроблено та реалізовано алгоритм фарбування живих клітин, що спрощує аналіз еволюції популяції. Дана розробка дає користувачеві можливість збереження за завантаження ігрових світів із зовнішніх файлів з розширенням GLF.

Переваги даної розробки: низькі вимоги до апаратного та програмного забезпечення, порівняно з конкурентними продуктами, низькі вимоги до оперативної пам’яті, стабільна та коректна робота програми, зручний інтерфейс, гнучка система налаштувань, реалізація гри на торі, можливість збереження та завантаження гри в власний формат.

Серед недоліків варто зазначити: уповільнення роботи програми із ігровим полем велкого розміру розмірів на близькій до максимальної швидкості, неможливість створення поля більшого за 100x100 клітин.

Список використаної літератури

  1. Архангельский О. Я. 100 компонентов общего назначения Delphi 5 [Текст] : навч. посiбник / Олексій Якович Архангельский. - М.: Біном, 1999 - 134 с.

  2. Немнюгін С.А. Turbo Pascal. Программирование на языке высокого уровня [Текст] : навч. посiбник / Сергій Андрійович Немнюгін. - М.: Питер, 2008. - 544 с.

  3. Wikipedia, the free encyclopedia [Електронний ресурс]: Conway’s Game of Life.- Режим доступу: http://en.wikipedia.org/wiki/Conway's_Game_of_Life, вільний.- Назва з екрану.

  4. Wikipedia [Електронний ресурс]: Жызнь (игра).- Режим доступу: http://ru.wikipedia.org/wiki/Жызнь_(Игра), вільний.- Назва з екрану.

  5. Gamedev – Разработка игр [Електронний ресурс]: Форум разработчиков игр. - Режим доступу: http://www.gamedev.ru/forum/, вільний.- Назва з екрану.

Додаток а. Лістинг програми

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, ExtCtrls, StdCtrls, ComCtrls, Buttons;

type

TForm1 = class(TForm)

gametimer: TTimer;

TorusBordersButton: TRadioButton;

DeadBorderButton: TRadioButton;

AliveBorderButton: TRadioButton;

SpeedBar: TTrackBar;

MultiColorButton: TCheckBox;

RandomButton: TSpeedButton;

LifeImage: TImage;

PauseButton: TSpeedButton;

ClearFieldButton: TSpeedButton;

StartButton: TSpeedButton;

OpenGLF: TOpenDialog;

SaveGLF: TSaveDialog;

StepButton: TSpeedButton;

ResizeButton: TSpeedButton;

HelpButton: TSpeedButton;

SpeedLabel: TLabel;

CellSizeTrackBar: TTrackBar;

SaveButton: TSpeedButton;

LoadButton: TSpeedButton;

procedure FormInitialization(Sender: TObject);

procedure ontimerevent(Sender: TObject);

procedure TorusBordersButtonOn(Sender: TObject);

procedure AliveBorderOn(Sender: TObject);

procedure DeadBorderButtonOn(Sender: TObject);

procedure SpeenChange(Sender: TObject);

procedure RandomButtonClick(Sender: TObject);

procedure PauseButtonClick(Sender: TObject);

procedure MultiColorButtonClick(Sender: TObject);

procedure LifeImageMouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

procedure LifeImageMouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

procedure LifeImageMouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

procedure ClearFieldButtonClick(Sender: TObject);

procedure StartButtonClick(Sender: TObject);

procedure StepButtonClick(Sender: TObject);

procedure ResizeButtonClick(Sender: TObject);

procedure CellSizeTrackBarChange(Sender: TObject);

procedure HelpButtonClick(Sender: TObject);

procedure LoadButtonClick(Sender: TObject);

procedure SaveButtonClick(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

procedure FieldInit(FieldX00,FieldY00,FieldX11,FieldY11,xmaFieldX0,ymaFieldX0:integer);

procedure RandomizeField;

procedure SetTypeCell(x,y:integer;typee:integer);{set cell's type}

procedure SetCell(x,y:integer;state:integer);{set cell's state if it's type is 0}

procedure XorCell(x,y:integer);{change cell's state if it's type is 0}

procedure draw;

procedure DrawConsoleWithStep;

procedure DrawWithStep;

function max(a,b:integer):integer;

function min(a,b:integer):integer;

procedure StepForward;

function HSV2RGB(h: integer; s,v: double):TColor;

procedure ClearField;

function BecomeDead(a:integer):Boolean;

function BecomeAlive(a:integer):Boolean;

function TrickyMod(a,b:integer):Integer;

procedure FieldResize(FieldX00,FieldY00,FieldX11,FieldY11:Integer); overload;

procedure FieldResize(CellNumber:integer); overload;

procedure SetBorders(BorderType:integer);

{Tricky mod function for torus field}

const MaxMatrixSize=257;

type MatrixType=array[0..MaxMatrixSize]of array[0..MaxMatrixSize] of integer;

var

Form1: TForm1;

CellState:MatrixType;

{state: 0- dead, 1- alive}

CellType:MatrixType;

{type: 0- usual cell, 1- always alive cell, 2- always dead cell}

CellAge:MatrixType;

{Number of steps cell exist. Used to color cells}

temp:MatrixType;

{array for temporary use}

CellChangedOnMouseDown:array[0..MaxMatrixSize]of array[0..MaxMatrixSize]of Boolean;

xmax,ymax:integer;

FieldX0,FieldX1,FieldY0,FieldY1:integer;

colors:array[0..255]of TColor;

BordersAreDead: boolean;

FieldIsTorus: boolean;

BecomeAliveMin,BecomeAliveMax:Integer;

StayAliveMin,StayAliveMax:Integer;

MaxCellAge: integer;

FieldYStart: integer;

MultiColorMode: boolean;

CellSize: Double;

CurrMaxCellAge: integer;

CurrMouseButton: TMouseButton;

MouseButtonDown: boolean;

CurrRules: integer;

BordersType: integer;

procedure FieldWipe;

procedure FieldLoad(FileName: TFileName);

procedure FieldSave(FileName: TFileName);

implementation

uses Unit2;

{$R *.dfm}

function HSV2RGB(h: integer; s,v: double):TColor;

var

Hi: integer;

f,p,q,t,r,g,b: double;

begin

Hi:=(h div 60) mod 6;

f:=h/60-(h div 60);

p:=v*(1-s);

q:=v*(1-f*s);

t:=v*(1-(1-f)*s);

if Hi=0 then begin

r:=v;

g:=t;

b:=p;

end;

if Hi=1 then begin

r:=q;

g:=v;

b:=p;

end;

if Hi=2 then begin

r:=p;

g:=v;

b:=t;

end;

if Hi=3 then begin

r:=p;

g:=q;

b:=v;

end;

if Hi=4 then begin

r:=t;

g:=p;

b:=v;

end;

if Hi=5 then begin

r:=v;

g:=p;

b:=q;

end;

HSV2RGB:=256*256*round(r*255)+256*round(g*255)+round(b*255);

end;

function max(a,b:integer):integer;

begin

if (a>b) then b:=a;

max:=b;

end;

function min(a,b:integer):integer;

begin

if (a<b) then b:=a;

min:=b;

end;

function BecomeDead(a:integer):Boolean;

begin

BecomeDead:=(a<StayAliveMin) or (a>StayAliveMax);

end;

function BecomeAlive(a:integer):Boolean;

begin

BecomeAlive:=(a>=BecomeAliveMin) and (a<=BecomeAliveMax) ;

end;

function TrickyMod(a,b:integer):Integer;

begin

if(a<0)then TrickyMod:=b+1+1+a else

if(a>(b+1))then TrickyMod:=b+2-a else

TrickyMod:=a;

end;

procedure StepForward;

var i,imin,imax,j,jmin,jmax,NeighborN:integer;

begin

if(FieldIsTorus)then

begin

imin:=0;

imax:=xmax+1;

jmin:=0;

jmax:=ymax+1

end

else

begin

imin:=1;

imax:=xmax;

jmin:=1;

jmax:=ymax;

end;

CurrMaxCellAge:=1;

for i:=imin to imax do

for j:=jmin to jmax do

begin

NeighborN:=

CellState[TrickyMod(i+1,xmax) ][TrickyMod(j+1,ymax) ]+

CellState[TrickyMod(i+1,xmax) ][TrickyMod(j,ymax) ]+

CellState[TrickyMod(i+1,xmax) ][TrickyMod(j-1,ymax) ]+

CellState[TrickyMod(i,xmax) ][TrickyMod(j-1,ymax) ]+

CellState[TrickyMod(i-1,xmax) ][TrickyMod(j-1,ymax) ]+

CellState[TrickyMod(i-1,xmax) ][TrickyMod(j,ymax) ]+

CellState[TrickyMod(i-1,xmax) ][TrickyMod(j+1,ymax) ]+

CellState[TrickyMod(i,xmax) ][TrickyMod(j+1,ymax) ];

if BecomeDead(NeighborN) then

begin

temp[i,j]:=0;

CellAge[i,j]:=0;

end

else

if ((CellState[i,j]=0) and BecomeAlive(NeighborN)) then

begin

temp[i,j]:=1;

CellAge[i,j]:=0;

end

else

temp[i,j]:=CellState[i,j];

if(CellType[i,j]=0) then CellAge[i,j]:=CellAge[i,j]+1;

if(CellAge[i,j]>MaxCellAge)then CellAge[i,j]:=MaxCellAge;

if(CellType[i,j]=0) then CurrMaxCellAge:=max(CellAge[i,j],CurrMaxCellAge);

end;

for i:=imin to imax do

for j:=jmin to jmax do

if (CellType[i,j]=0) then

CellState[i,j]:=temp[i,j];

end;

procedure FieldWipe;

var i,j:Integer;

begin

for i:=0 to MaxMatrixSize do

for j:=0 to MaxMatrixSize do

begin

CellState[i,j]:=0;

CellType[i,j]:=0;

CellAge[i,j]:=0;

end;

end;

procedure FieldInit(FieldX00,FieldY00,FieldX11,FieldY11,xmaFieldX0,ymaFieldX0:integer);

var i,j:integer;

begin

begin

FieldX0:=FieldX00;

FieldX1:=FieldX11;

FieldY0:=FieldY00;

FieldY1:=FieldY11;

xmax:=xmaFieldX0;

ymax:=ymaFieldX0;

FieldWipe;

end;

end;

procedure FieldResize(CellNumber:integer); overload;

begin

xmax:=cellnumber;

ymax:=CellNumber;

ClearField;

end;

procedure FieldResize(FieldX00,FieldY00,FieldX11,FieldY11:Integer); overload;

begin

FieldX0:=FieldX00;

FieldX1:=FieldX11;

FieldY0:=FieldY00;

FieldY1:=FieldY11;

end;

procedure ClearField;

var i,imin,imax,j,jmin,jmax:integer;

begin

if(FieldIsTorus)then

begin

imin:=0;

imax:=xmax+1;

jmin:=0;

jmax:=ymax+1

end

else

begin

imin:=1;

imax:=xmax;

jmin:=1;

jmax:=ymax;

end;

for i:=imin to imax do

for j:=jmin to jmax do

begin

CellState[i,j]:=0;

end;

end;

procedure RandomizeField;

var i,imin,imax,j,jmin,jmax:integer;

begin

if(FieldIsTorus)then

begin

imin:=0;

imax:=xmax+1;

jmin:=0;

jmax:=ymax+1

end

else

begin

imin:=1;

imax:=xmax;

jmin:=1;

jmax:=ymax;

end;

for i:=imin to imax do

for j:=jmin to jmax do if(CellType[i,j]=0)then

CellState[i,j]:=random(2);

end;

procedure SetTypeCell(x,y:integer;typee:integer);{set cell's type}

begin

end;

procedure SetCell(x,y:integer;state:integer);{set cell's state if it's type is 0}

begin

if(CellType[x,y]=0)then

begin

CellState[x,y]:=STATE;

CellAge[x,y]:=0;

end;

end;

procedure XorCell(x,y:integer);{change cell's state if it's type is 0}

begin

if(CellType[x,y]=0)then

begin

CellState[x,y]:=1-CellState[x,y];

CellAge[x,y]:=0;

end;

end;

procedure draw;

var

i,j:integer;

begin

cellsize:=((FieldX1-FieldX0-1)/(xmax+2));//,(FieldY1-FieldY0+1)/(ymax+2));

for i:=0 to xmax+1 do

for j:=0 to ymax+1 do

begin

if(Form1.MultiColorButton.Checked)then

begin

if(CellState[i,j]=0)then

Form1.LifeImage.Canvas.Brush.Color:=colors[0]

else

Form1.LifeImage.Canvas.Brush.Color:=HSV2RGB((100+(240*(CellAge[i,j]))div (currMaxCellAge)),1,1)

end

else

Form1.LifeImage.Canvas.Brush.Color:=colors[CellState[i,j]];

Form1.LifeImage.Canvas.Rectangle(Round(FieldX0+i*cellsize),round(FieldY0+j*cellsize),round(FieldX0+(1+i)*cellsize)+1,1+round(FieldY0+(1+j)*cellsize));

end;

end;

procedure DrawConsoleWithStep;

var i,j:integer;

begin

stepForward;

for j:=0 to ymax+1 do

begin

writeln;

for i:=0 to xmax+1 do

if(CellState[i,j]=0)then

write(' ')

else

write('#');

end;

end;

procedure DrawWithStep;

begin

stepforward;

draw;

end;

procedure TForm1.FormInitialization(Sender: TObject);

begin

FieldIsTorus:=True;

BordersType:=0;

CurrRules:=1;

StayAliveMin:=2;

StayAliveMax:=3;

BecomeAliveMin:=3;

BecomeAliveMax:=3;

FieldYStart:=50;

MaxCellAge:=20;

FieldInit(1,1,form1.LifeImage.Width,form1.LifeImage.Height,24,24);

FieldResize(10);

randomizefield;

colors[1]:=HSV2RGB(100,1,1);

colors[0]:=$00FFFFFF;

draw;

end;

procedure TForm1.ontimerevent(Sender: TObject);

begin

DrawWithStep;

end;

procedure SetBorders(bordertype:integer);

var i,j,borderstate:Integer;

begin

BordersType:=bordertype;

if(BordersType<>0)then

begin

borderstate:=2-borderstype;

for i:=0 to xmax+1 do

begin

CellState[i,0]:=borderstate;

CellState[i,ymax+1]:=borderstate;

CellAge[i,0]:=0;

CellAge[i,ymax+1]:=0;

end;

for j:=0 to ymax+1 do

begin

CellState[0,j]:=borderstate;

CellState[xmax+1,j]:=borderstate;

CellAge[0,j]:=0;

CellAge[xmax+1,j]:=0;

end;

end

else

borderstype:=0;

for i:=0 to xmax+1 do

begin

CellType[i,0]:=borderstype;

CellType[i,ymax+1]:=borderstype;

end;

for j:=0 to ymax+1 do

begin

CellType[0,j]:=borderstype;

CellType[xmax+1,j]:=borderstype;

end;

end;

procedure TForm1.TorusBordersButtonOn(Sender: TObject);

const bordertype=0;

var i,j:Integer;

begin

FieldIsTorus:=True;

SetBorders(0);

draw;

end;

procedure TForm1.AliveBorderOn(Sender: TObject);

var i,j:Integer;

const bordertype=1;

const BorderState=1;

begin

FieldIsTorus:=False;

BordersAreDead:=False;

SetBorders(1);

draw;

end;

procedure TForm1.DeadBorderButtonOn(Sender: TObject);

var i,j:integer;

const bordertype=2;

const BorderState=0;

begin

FieldIsTorus:=False;

BordersAreDead:=true;

SetBorders(2);

draw;

end;

procedure TForm1.SpeenChange(Sender: TObject);

var r:Real;

begin

r:=(1024+60-SpeedBar.Position)/1024;

gametimer.Interval:=Trunc(1000*(r*r))

end;

procedure TForm1.RandomButtonClick(Sender: TObject);

begin

RandomizeField;

draw;

end;

procedure TForm1.PauseButtonClick(Sender: TObject);

begin

gametimer.Enabled:=false;

end;

procedure TForm1.MultiColorButtonClick(Sender: TObject);

begin

draw;

end;

procedure TForm1.LifeImageMouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

var i,j:Integer;

begin

MouseButtonDown:=false;

end;

procedure TForm1.LifeImageMouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

var i,j:integer;

begin

for i:=0 to MaxMatrixSize do

for j:=0 to MaxMatrixSize do

CellChangedOnMouseDown[i,j]:=False;

MouseButtonDown:=True;

CurrMouseButton:=Button;

if(x>0)and(y>0)and(CellSize>0)

then

begin

i:=trunc(x / CellSize);

j:=trunc(y / CellSize);

if(not CellChangedOnMouseDown[i,j])and(MouseButtonDown) then

begin

if(CurrMouseButton=mbLeft)then

begin

SetCell(i,j,1);

end else

if(CurrMouseButton=mbRight)then

begin

SetCell(i,j,0);

end else

if(CurrMouseButton=mbMiddle)then

begin

XorCell(i,j);

end;

CellChangedOnMouseDown[i,j]:=True;

draw;

end;

end;

end;

procedure TForm1.LifeImageMouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

var i,j:Integer;

begin

if(x>0)and(y>0)and(CellSize>0)

then

begin

i:=Trunc(x / CellSize);

j:=trunc(y / CellSize);

if(not CellChangedOnMouseDown[i,j])and(MouseButtonDown) then

begin

if(CurrMouseButton=mbLeft)then

begin

SetCell(i,j,1);

end else

if(CurrMouseButton=mbRight)then

begin

SetCell(i,j,0);

end else

if(CurrMouseButton=mbMiddle)then

begin

XorCell(i,j);

end;

CellChangedOnMouseDown[i,j]:=True;

draw;

end;

end;

end;

procedure TForm1.ClearFieldButtonClick(Sender: TObject);

begin

ClearField;

draw;

end;

procedure TForm1.StartButtonClick(Sender: TObject);

begin

gametimer.Enabled:=True;

end;

procedure TForm1.StepButtonClick(Sender: TObject);

begin

DrawWithStep;

end;

procedure TForm1.ResizeButtonClick(Sender: TObject);

begin

FieldWipe;

FieldResize(CellSizeTrackBar.Position);

SetBorders(BordersType);

draw;

end;

procedure TForm1.CellSizeTrackBarChange(Sender: TObject);

begin

ResizeButton.Caption:='Resize to '+inttostr(CellSizeTrackBar.Position+2);

end;

procedure TForm1.HelpButtonClick(Sender: TObject);

begin

if(not form2.visible)then

begin

Form2.Width:=300;

Form2.Height:=700;

end;

form2.visible:=not form2.visible;

end;

procedure TForm1.LoadButtonClick(Sender: TObject);

begin

gametimer.Enabled:=false;

if OpenGLF.Execute then

begin

fieldload(openglf.FileName);

end;

end;

procedure FieldLoad(FileName: TFileName);

var lfile:Text;

i,j,t:Integer;

begin

FieldWipe;

AssignFile(lfile,FileName);

Reset(lfile);

read(lfile,xmax);

read(lfile,ymax);

read(lfile,t);

FieldIsTorus:=t=1;

read(lfile,t);

BordersAreDead:=t=1;

if(fieldistorus)then

Form1.TorusBordersButton.Checked:=True

else

if(BordersAreDead)then

Form1.DeadBorderButton.Checked:=true

else

Form1.AliveBorderButton.Checked:=True;

read(lfile,borderstype);

SetBorders(borderstype);

for i:=0 to xmax+1 do

for j:=0 to ymax+1 do

read(lfile,cellstate[i,j]);

for i:=0 to xmax+1 do

for j:=0 to ymax+1 do

read(lfile,celltype[i,j]);

for i:=0 to xmax+1 do

for j:=0 to ymax+1 do

read(lfile,cellage[i,j]);

closefile(lfile);

draw;

end;

procedure FieldSave(FileName: TFileName);

var sfile:Text;

i,j:Integer;

begin

i:=Length(FileName);

AssignFile(sfile,FileName);

Rewrite(sfile);

Writeln(sfile,xmax,' ',ymax);

if(FieldIsTorus)then

Writeln(sfile,'1')

else

Writeln(sfile,'0');

if(BordersAreDead)then

Writeln(sfile,'1')

else

Writeln(sfile,'0');

Writeln(sfile,borderstype);

for i:=0 to xmax+1 do

begin

writeln(sfile,'');

for j:=0 to ymax+1 do

Write(sfile,cellstate[i,j],' ')

end;

for i:=0 to xmax+1 do

begin

writeln(sfile,'');

for j:=0 to ymax+1 do

Write(sfile,celltype[i,j],' ')

end;

for i:=0 to xmax+1 do

begin

writeln(sfile,'');

for j:=0 to ymax+1 do

Write(sfile,cellage[i,j],' ')

end;

closefile(sfile);

end;

procedure TForm1.SaveButtonClick(Sender: TObject);

begin

gametimer.Enabled:=false;

if saveGLF.Execute then

begin

FieldSave(saveglf.FileName);

end;

end;

end.

unit Unit2;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls, ComCtrls;

type

TForm2 = class(TForm)

HelpRichEdit: TRichEdit;

procedure FormActivate(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.FormActivate(Sender: TObject);

begin

HelpRichEdit.Lines.LoadFromFile('help.rtf');

end;

end.