Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Курсовые / 1 / LIFECELL / ТЕХНИЧ~1

.DOC
Скачиваний:
18
Добавлен:
17.04.2013
Размер:
202.24 Кб
Скачать

Московский Государственный Институт Электронной Техники

(Технический Университет)

Курсовая работа по курсу

Организация вычислительных процессов”:

программа “Жизнь клеток”.

Выполнила cтудентка группы МП28

Безуглова Е.А.

Проверил доцент Полосухин Б.М.

Кафедра ИПОВС.

2001 год.

Техническое задание.

Данная программа моделирует жизнь гипотетической колонии живых клеток , которые выживают , размножаются или погибают в соответствии со следующими правилами .Клетка выживает если только она имеет двух или трёх соседей из восьми возможных (рис.1).Если у клетки один сосед или вовсе ни одного , она погибает в изоляции (рис.2).Если клетка имеет четырёх или более соседей, она погибает от перенаселения (рис.3).В любой пустой позиции , у которой ровно три соседа , в следующем поколении появляется новая клетка (рис.4).Размер “жизненного пространства” задаётся пользователем.Начальное распределение клеток задаётся датчиком случайных чисел.

Рис.1 Рис.2 Рис.3 Рис.4

Листинг программы.

MOUSE.H

#include<stdio.h>

#include<conio.h>

#include<iostream.h>

#include<dos.h>

#include<stdlib.h>

void initmouse()

{

asm

{

mov AX,0

int 0x33

};

}

void showmouse()

{

asm

{

mov AX,1

int 0x33

};

}

void hidemouse()

{

asm

{

mov AX,2

int 0x33

};

}

void mouselimit(int x1,int y1,int x2,int y2)

{

asm

{

mov AX,7

mov CX,x1

mov DX,x2

int 0x33

mov AX,8

mov CX,y1

mov DX,y2

int 0x33

};

}

int mousepressed()

{

int f;

asm

{

mov ax,5

mov bx,1

int 33h

and ax,1

mov f,ax

}

return f;

}

int mousegetx()

{

int x;

asm

{

mov ax,3

int 33h

mov x,cx

}

return x;

}

int mousegety()

{

int y;

asm {

mov ax,3

int 33h

mov y,dx

}

return y;

}

WORK.H

#include "mouse.h"

#include <graphics.h>

#include <bios.h>

#include <dos.h>

#define ESC 27

#define ENTER 13

#define PROBEL 32

struct cell

{

int x; //X-coordinate of the cell

int y; //Y-coordinate of the cell

int init; //dead or alive

} mas[60][45],mas1[60][45];

int generation;

int N, //length of the field

M; //width of the field

void init_cell();

void init_screen();

void redact_cell();

void xor_cell(int ex,int ey);

int begin_life();

void copy_mas(struct cell m1[60][45],struct cell m2[60][45]);

//procedure of the initialization of the cells

void init_cell()

{

int i=0,j=0,k,m;

setcolor(YELLOW);

randomize();

//life of the cells inserted at random

for(m=0;m<M;m++,j+=10)

{

for(k=0;k<N;k++,i+=10)

{

mas[k][m].x=55+i;

mas[k][m].y=55+j;

mas[k][m].init=rand()%2;

}

i=0;

}

//show alive sells

for( m=0;m<M;m++)

for( k=0;k<N;k++)

if (mas[k][m].init==1)

ellipse(mas[k][m].x,mas[k][m].y,0,360,4,4);

}

void init_screen()

{

//size of the field

printf("Enter size of the game field \n");

printf("lengthwise (up to 55): ");

scanf("%d",&N);

printf("in width (up tu 40): ");

scanf("%d",&M);

clrscr();

///////////////////initialization of the graphic regime///////////////

/* request auto detection */

int gdriver = DETECT, gmode, errorcode;

/* initialize graphics mode */

initgraph(&gdriver, &gmode, "d:\\progra~1\\bc\\bgi");

/* read result of initialization */

errorcode = graphresult();

if (errorcode != grOk) /* an error occurred */

{

printf("Graphics error: %s\n", grapherrormsg(errorcode));

printf("Press any key to halt:");

getch();

exit(1); /* return with error code */

}

//draw upper line

setfillstyle(SOLID_FILL,BLUE);

bar(1,20,679,35);

outtextxy(5,25," Generation: ");

outtextxy(250,25,"ESC - exit");

outtextxy(390,25,"ENTER - look at the evolution");

//draw field limits

setfillstyle(EMPTY_FILL,0);

rectangle(50,50,50+(N*10),50+(M*10));

//initialization of the begining state of the cells

init_cell();

//initialization of the mouse

//it can't go out of the field

initmouse();

showmouse();

mouselimit(51,51,(N*10)+49,(M*10)+49);

}

void xor_cell(int ex,int ey)

{

int k=0,m=0;

for(int i=50;i<(50+N*10);i+=10,k++) if(ex<i) break;

for(int j=50;j<(50+M*10);j+=10,m++) if(ey<j) break;

k--;m--;

if (mas[k][m].init==0)

{

setcolor(YELLOW);

hidemouse();

ellipse(mas[k][m].x,mas[k][m].y,0,360,4,4);

showmouse();

mas[k][m].init=1;

}

else

{

setwritemode(XOR_PUT);

setcolor(0);

hidemouse();

ellipse(mas[k][m].x,mas[k][m].y,0,360,4,4);

showmouse();

mas[k][m].init=0;

setwritemode(COPY_PUT);

hidemouse();

ellipse(mas[k][m].x,mas[k][m].y,0,360,4,4);

showmouse();

setcolor(YELLOW);

}

}

void copy_mas(struct cell m1[60][45],struct cell m2[60][45])

{

for(int i=0;i<N;i++)

for(int j=0;j<M;j++)

{

m2[i][j].x=m1[i][j].x;

m2[i][j].y=m1[i][j].y;

m2[i][j].init=m1[i][j].init;

}

}

int begin_life()

{

int count=0;

char ss[10];

hidemouse();

//draw upper line

setfillstyle(SOLID_FILL,BLUE);

bar(1,20,679,35);

setcolor(WHITE);

outtextxy(5,25," Generation: ");

outtextxy(250,25,"ESC - exit");

outtextxy(390,25,"SPASE - edit evolution");

union inkey {

char ch[2];

int i;

} c;

//endless cycle,in which keyboard adn mouse are asked

for(;;)

{

//if a key pressed,then ESC check

if (bioskey(1))

{

c.i=bioskey(0);

if (c.ch[0]==ESC)

{ setfillstyle(SOLID_FILL,BLUE);

bar(190,200,410,260);

setfillstyle(SOLID_FILL,YELLOW);

bar(195,205,405,255);

setcolor(BLACK);

outtextxy(240,210,"Congralution!");

itoa(generation,ss,10);

outtextxy(210,225,"You cells have lived :");

outtextxy(240,240,ss);

outtextxy(265,240,"generations!");

getch();

exit(1);}

if (c.ch[0]==PROBEL)

{

setfillstyle(SOLID_FILL,BLUE);

bar(1,20,679,35);

setcolor(WHITE);

outtextxy(5,25," Generation: ");

outtextxy(250,25,"ESC - exit");

outtextxy(390,25,"ENTER - look at the evolution ");

showmouse(); return 0;

}

}

//initialization of the subsidiary massif

copy_mas(mas,mas1);

int N1=N-1,M1=M-1;

//data about new generation are put in to the mas1

for(int i=0;i<N;i++)

for(int j=0;j<M;j++)

{

count=0;

//////1) corner cells/////////////////////////////

if ((mas[i][j].init==1) && (i==0) && (j==0))

{count=mas[i][j+1].init+mas[i+1][j+1].init+

+mas[i+1][j].init;

if ((count==2) || (count==3)) mas1[i][j].init=1;

else mas1[i][j].init=0;

}

if ((mas[i][j].init==0) && (i==0) && (j==0))

{count=mas[i][j+1].init+mas[i+1][j+1].init+

+mas[i+1][j].init;

if (count==3) mas1[i][j].init=1;

else mas1[i][j].init=0;

}

if ((mas[i][j].init==1) && (i==N1) && (j==0))

{count=mas[i-1][j].init+mas[i-1][j+1].init+

mas[i-1][j].init;

if ((count==2) || (count==3)) mas1[i][j].init=1;

else mas1[i][j].init=0;

}

if ((mas[i][j].init==0) && (i==N1) && (j==0))

{count=mas[i-1][j].init+mas[i-1][j+1].init+

mas[i-1][j].init;

if (count==3) mas1[i][j].init=1;

else mas1[i][j].init=0;

}

if ((mas[i][j].init==1) && (i==N1) && (j==M1))

{count=mas[i-1][j-1].init+mas[i-1][j].init+

mas[i][j-1].init;

if ((count==2) || (count==3)) mas1[i][j].init=1;

else mas1[i][j].init=0;

}

if ((mas[i][j].init==0) && (i==N1) && (j==M1))

{count=mas[i-1][j-1].init+mas[i-1][j].init+

mas[i][j-1].init;

if (count==3) mas1[i][j].init=1;

else mas1[i][j].init=0;

}

if ((mas[i][j].init==1) && (i==0) && (j==M1))

{count=mas[i+1][j].init+mas[i][j-1].init+

mas[i+1][j-1].init;

if ((count==2) || (count==3)) mas1[i][j].init=1;

else mas1[i][j].init=0;

}

if ((mas[i][j].init==0) && (i==0) && (j==M1))

{count=mas[i+1][j].init+mas[i][j-1].init+

mas[i+1][j-1].init;

if (count==3) mas1[i][j].init=1;

else mas1[i][j].init=0;

}

//////2) regional cells///////////////////////////

if ((mas[i][j].init==1) && (i>0) && (i<N1) && (j==0))

{count=mas[i-1][j].init+mas[i-1][j+1].init+

mas[i][j+1].init+mas[i+1][j].init+

mas[i+1][j+1].init;

if ((count==2) || (count==3)) mas1[i][j].init=1;

else mas1[i][j].init=0;

}

if ((mas[i][j].init==0) && (i>0) && (i<N1) && (j==0))

{count=mas[i-1][j].init+mas[i-1][j+1].init+

mas[i][j+1].init+mas[i+1][j].init+

mas[i+1][j+1].init;

if (count==3) mas1[i][j].init=1;

else mas1[i][j].init=0;

}

if ((mas[i][j].init==1) && (j>0) && (i==N1) && (j<M1))

{count=mas[i][j-1].init+mas[i][j+1].init+

mas[i-1][j+1].init+mas[i-1][j].init+

mas[i-1][j-1].init;

if ((count==2) || (count==3)) mas1[i][j].init=1;

else mas1[i][j].init=0;

}

if ((mas[i][j].init==0) && (j>0) && (i==N1) && (j<M1))

{count=mas[i][j-1].init+mas[i][j+1].init+

mas[i-1][j+1].init+mas[i-1][j].init+

mas[i-1][j-1].init;

if (count==3) mas1[i][j].init=1;

else mas1[i][j].init=0;

}

if ((mas[i][j].init==1) && (i>0) && (i<N1) && (j==M1))

{count=mas[i-1][j-1].init+mas[i][j-1].init+

mas[i+1][j-1].init+mas[i-1][j].init+

mas[i+1][j].init;

if ((count==2) || (count==3)) mas1[i][j].init=1;

else mas1[i][j].init=0;

}

if ((mas[i][j].init==0) && (i>0) && (i<N1) && (j==M1))

{count=mas[i-1][j-1].init+mas[i][j-1].init+

mas[i+1][j-1].init+mas[i-1][j].init+

mas[i+1][j].init;

if (count==3) mas1[i][j].init=1;

else mas1[i][j].init=0;

}

if ((mas[i][j].init==1) && (j>0) && (i==0) && (j<M1))

{count=mas[i][j-1].init+mas[i][j+1].init+

mas[i+1][j-1].init+mas[i+1][j].init+

mas[i+1][j+1].init;

if ((count==2) || (count==3)) mas1[i][j].init=1;

else mas1[i][j].init=0;

}

if ((mas[i][j].init==0) && (j>0) && (i==0) && (j<M1))

{count=mas[i][j-1].init+mas[i][j+1].init+

mas[i+1][j-1].init+mas[i+1][j].init+

mas[i+1][j+1].init;

if (count==3) mas1[i][j].init=1;

else mas1[i][j].init=0;

}

//////3) central cells///////////////////////////////

if ((mas[i][j].init==1) && (j>0) && (i>0) && (j<M1) && (i<N1))

{count=mas[i-1][j-1].init+mas[i][j-1].init+

mas[i+1][j-1].init+mas[i-1][j].init+

mas[i+1][j].init+mas[i-1][j+1].init+

mas[i][j+1].init+mas[i+1][j+1].init;

if ((count==2) || (count==3)) mas1[i][j].init=1;

else mas1[i][j].init=0;

}

if ((mas[i][j].init==0) && (j>0) && (i>0) && (j<M1) && (i<N1))

{count=mas[i-1][j-1].init+mas[i][j-1].init+

mas[i+1][j-1].init+mas[i-1][j].init+

mas[i+1][j].init+mas[i-1][j+1].init+

mas[i][j+1].init+mas[i+1][j+1].init;

if (count==3) mas1[i][j].init=1;

else mas1[i][j].init=0;

}

}

copy_mas(mas1,mas);

for( int m=0;m<M;m++)

for( int k=0;k<N;k++)

{

if (mas[k][m].init==1) setcolor(YELLOW);

else setcolor(0);

ellipse(mas[k][m].x,mas[k][m].y,0,360,4,4);

}

generation++;

setfillstyle(SOLID_FILL,BLUE);

bar(130,20,160,35);

setcolor(WHITE);

itoa(generation,ss,10);

outtextxy(140,25,ss);

delay(300);

}

}

void redact_cell()

{

int x1,y1;

//subsidiary strusture,which helps to define code of the pressed key

union inkey {

char ch[2];

int i;

} c;

//endless cycle,in which keyboard adn mouse are asked

for(;;)

{

//polling of the keyboard and the mouse

if (bioskey(1))

{

c.i=bioskey(0);

if (c.ch[0]==ESC)

{setfillstyle(SOLID_FILL,BLUE);

bar(190,200,410,260);

setfillstyle(SOLID_FILL,YELLOW);

bar(195,205,405,255);

setcolor(BLACK);

outtextxy(250,215,"You lose!");

outtextxy(200,235,"You didn't breed any cell!");

getch();

exit(1);}

if (c.ch[0]==ENTER) begin_life();

}

if(mousepressed()!=0)

{

x1=mousegetx();

y1=mousegety();

//draw or eraze electeed cell

while (mousepressed()!=0); xor_cell(x1,y1);

}

}

}

START.CPP

#include "work.h"

void main()

{

init_screen();

redact_cell();

closegraph();

}

Схема алгоритма.

Руководство пользователя.

После запуска программы на экране появляется приглашение ввести размеры

Игрового поля : сначала по горизонтали(в пределах 55),затем по вертикали(в пределах

40).После этого на экране будет представлено “жизненное пространство” клеток.

Перед началом игры можно сразу произвести редактирование поколения.Для этого

нужно воспользоваться мышкой,чей курсор появится на экране(причём курсор не

может выйти за границы игрового поля,очерченные белым контуром).Пользуясь левой кнопкой мыши можно удалять или наоборот добавлять клетки.Чтобы посмотреть развитие клеток достаточно нажать клавишу ENTER.В верхней части экрана можно видеть,сколько поколений прожили клетки.Для того,чтобы отредактировать развивающуюся колонию необходимо нажать клавишу SPASE(ПРОБЕЛ),внести необходимые исправления и затем нажать снова ENTER.Выход из программы осуществляется при помощи клавиши ESC.

Пояснения к программе.

Данная программа состоит из трёх частей : двух заголовочных файлов mouse.h и

work.h и собственно самой программы start.cpp.

В заголовочном файле mouse.h содержатся функции для работы с мышкой.Они основаны на использовании прерывания $33.Это прерывание MS-DOS,т.е оно обрабатывается в программном обеспечении операционной системы.Все эти функции написаны с использованием языка ASSEMBLER.

Функция INITMOUSE( ) инициализирует мышку,функция SHOWMOUSE( ) включает отображение курсора на текущей видеостранице,функция HIDEMOUSE( ) выключает отображение курсора.С помощью функции MOUSELIMIT( ) задаётся предел движения курсора,функция MOUSEPRESSED( ) следит за нажатием кнопки мышки,а функции MOUSEGETX( ) и MOUSEGETY( ) определяют координаты точки,где была нажата

кнопка мыши(куда указывал курсор).

Файл work.h содержит необходимые функции для непосредственной работы самой программы.В начале с помощью директивы препроцессора #include включаются заголовочные файлы стандартной библиотеки –graphics.h,bios.h и dos.h,-а токже описанный выше файл mouse.h.Далее директивой #define создаются символические константы ESC,ENTER и PROBEL,поэтому вместо последующих появлений этих идентификаторов будет автоматически подставлены заменяющие значения :

27,13 и 32 соответственно.Потом идёт описание структуры cell,которая состоит из трёх целочисленных полей : первое содержит х-координату клетки,второе содержит

у-координату ,в третьем поле содержится либо 1(если клетка жива),либо 0(если клетка мертва).Массив mas представляет собой двумерный массив таких структур.

Далее идёт описание функций:

INIT_CELL( )-она инициализирует начальное состояние клеток с

помощью датчика случайных чисел , данные о клетках заносятся в

массив MAS.Затем первое поколение выводится на экран с помощью

функции ELLIPSE(int x,int y,int start,int end,int xr,int yr),прототип которой

содержится в файле graphics.h.Эта функция рисует эллипс текущим

цветом,поэтому предварительно с помощью функции SETCOLOR(yellow)

текущим был установлен желтый цвет.Центр эллипса имеет координаты(х,у),

радиусы по направлениям х и у определяются xr и yr соответственно.Start и

end определяют,какая часть эллипса будет нарисована(в нашем случае он

изображен целиком);

INIT_SCREEN( )-в начале этой функции на экран с помощью функции

PRINTF (её прототип находится в файле stdio.h,который подключён в файле

mouse.h)выводится приглашение ввести размеры игрового поля ,функцией

SCANF считываются введённые данные; происходит отчистка окна

функцией CLRSCR( ) из conio.h (он также подключён в mouse.h).

Графический режим инициализируется функцией INITGRAPH( ),эта функция

при использовании DETECT(как в нашем случае) автоматически определяет

тип видеоустройства системы и определяет видеорежим с наибольшим

разрешением.С помощью функции GRAPHRESULT( ) определяется,успешно

ли прошла инициализация,если она неуспешна,выдаётся сообщение об

ошибке и выполнение программы прекращается.Если инициализация

успешна,начинается прорисовка игрового поля .Для этого используются

функции из файла graphics.h:

SETFILLSTYLE-устанавливает стиль и цвет заливки,

в нашем случае сплошная заливка синим цветом

(solid_fill,blue),затем заливка цветом фона(empty_fill,0).

BAR-рисует прямоугольную панель

OUTTEXTXY-выводит текстовую строку,начиная с точки

с указанными координатами

RECTANGLE-изображает прямоугольник,определённый

своими координатами;

далее в функции вызывается выше описанная функция init_cell и процедуры

из файла mouse.h для работы с мышкой.

XOR_CELL(int ex,int ey)-удаляет или добавляет клетку,которой

Соответствуют координаты(ex,ey),здесь ипользуется функция

SETWRITEMODE(int wmode),которая определяет внешний вид выводимых

Данных: если параметр wmode принимает значение xor_put ,то выводимые

Далее данные будут взаимодействовать с существующим на экране

Изображением,если же wmode принимает значение copy_put,то выводимые

Данные будут замещать любые образы на экране.

COPY_MAS-копирует один двумерный массив из структур cell

в другой.

BEGIN_LIFE( )-одна из самых главных функций,в ней происходит

Формирование новых поколений в соответствии с правилами игры ,

Обрабатывается нажатие клавиш ESC,ENTER.Здесь используются

Функции:

BIOSKEY(int cmd)-прототип этой функции содержится в

файле bios.h.Она выполняет прямые операции с

клавиатурой.Параметр cmd определяет,какая именно операция

будет выполняться.Если cmd равен 0 ,то функция возвращает

нажатую клавишу,если cmd равен 1 ,то функция выполняет

проверку нажатия клавиши,она возвращает значение нажатой

клавиши,которое является ненулевым в случае нажатия клавиши

и нулевым в противном случае.

ITOA(int num,char *str,int radix)-прототип этой функции

находится в файле stdlib.h.Она конвертирует целое число num в

строчный эквивалент и помещает результат в строку,на которую

указывает параметр str.Основание системы счисления для записи

выходной строки определено параметром radix,который может

принимать значения в интервале от 2 до 36.Функция возвращает

указатель на str.

GETCH( )-прототип находится в файле conio.h,возвращает

очередной символ с консоли,но не выводит этот символ на экран.

REDACT_CELL( )-функция для редактирования развития клеток.

Файл START.CPP является самой программой,к нему с помощью директивы

#include подключён файл work.h,содержащий все необходимые функции для работы с “колонией” клеток.Также здесь используется функция CLOSEGRAPH( ),прототип которой находится в файле graphics.h.Эта функция деактивирует графическое окружение,что включает в себя возврат системе памяти,использовавшейся для графических драйверов и шрифтов.

Заключение.

Данная программа даёт возможность более широко ознакомиться с функциями

для работы с графикой в Си++,она даёт опыт по работе с анимацией,то есть с выводом

динамического (изменяющегося) изображения,кроме того наблюдение над совокупностью большого числа поколений данной игры может доставить некоторое удовольствие и даже определённое ощущение собственной значимости , ведь

судьбы виртуального сообщества в руках игрока!

Cписок литературы.

1.С.А.Немнюгин “Turbo Pascal”,издательство ”Питер”,Санкт-Петербург,2000 год.

2.Герберт Шилд “Программиривание на Borland C++”,издательство “Попурри”,Минск,1998 год.

3.Х.М.Дейтел,П.Дж.Дейтел “Как программировать на С”,издательство “Бином”,Москва,2000 год.

15

Соседние файлы в папке LIFECELL