
ФЕДЕРАЛЬНОЕ АГЕНТСТВО ПО ОБРАЗОВАНИЮ
ГОСУДАРСТВЕННОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ
ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ
ЛИПЕЦКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
КАФЕДРА АВТОМАТИЗИРОВАННЫХ СИСТЕМ УПРАВЛЕНИЯ
Индивидуальное домашнее задание
по дисциплине
«Теория вычислительных процессов»
|
Студент |
|
|
|
Филатов А.А. |
| ||||||||
|
|
|
подпись, дата |
|
фамилия, инициалы |
| ||||||||
|
Группа |
|
АС-09-1 |
|
|
|
| |||||||
|
|
|
|
|
|
| ||||||||
|
Принял |
|
|
|
|
| ||||||||
|
|
|
|
|
Гаев Л.В. |
| ||||||||
|
ученая степень, звание |
|
подпись, дата |
|
фамилия, инициалы |
|
Липецк 2012
Оглавление
Оглавление 2
Задание кафедры 3
1. Описание модели 3
1.1. Общее описание модели 3
1.2.Начальное положение 3
1.3. Описание интерфейса 4
1.3.1 Элементы управления 5
1.3.2 Отображение статистики в интерфейсе 5
1.4. Описание видов 5
1.5. Описание статистики 5
2. Листинг программы 6
2.1. Класс животного 6
2.2. Основной класс 12
3. Пример работы 20
3.1. Пример 1 20
3.2. Пример 2 22
3.3. Пример 3 23
Вывод 25
Задание кафедры
Написать программную реализацию заданной модели, организовать сбор статистики модели.
Вариант: 2 вида растительноядных животных, конкурирующих за пищу.
1. Описание модели
1.1. Общее описание модели
Имеется поле N x N клеток.
Есть 2 вида животных.
Животные борются за ресурсы (трава).
Трава появляется в случайных клетках с заданной интенсивностью.
Все время квантуется.
Каждый квант здоровье особи уменьшается на 0,2%
Животное сделавшее 100 ходов погибает от старости
Если показатель сытости животного заполнен менее чем на 70%, животное ищет пищу: если пища попадает в область видимости, животное устремляется к ней.
Если показатель сытости животного заполнен более чем на 70%, животное считается сытым и ищет другую сытую особь с целью получения потомства.
Если показатель сытости особи опускается до нуля, особь погибает, а на месте ее смерти появляется трава.
После появления потомства показатель сытости особей-родителей опускается на 50%
Каждая новая особь получает показатель сытости, равный 50%
На одной клетке одновременно может находиться одна особь.
При появлении потомства, особи должны находиться в соседних ячейках.
Появление новой особи происходит в соседних клетках с особями. Если все клетки заняты, потомство не появляется, но показатель сытости особей уменьшается на соответствующее значение.
После съедания пищи показатель сытости пополняется на 10 единиц.
1.2.Начальное положение
Некоторое число клеток заполнено травой
Есть несколько особей первого вида и несколько особей второго вида
1.3. Описание интерфейса
Интерфейс представляет собой окно, разделенное на две части:
В левой части отображается статистика и элементы управления.
В правой части отображено поле и текущее положение всех особей каждого вида, а также ресурсов.
У каждого вида имеется своя пиктограмма:
Если животное ищет партнера, в верхнем правом углу отображается пиктограмма сердца.
У каждой особи есть полоса здоровья, отображающая текущее состояние.
1.3.1 Элементы управления
Слева кнопка, позволяющая останавливать/запускать процесс моделирования
Справа кнопка, по нажатию на которую сохраняется отчет в папку с исполняемым файлом и именем “report.txt”
1.3.2 Отображение статистики в интерфейсе
Текущий квант
Текущее число особей | среднее число особей с начала моделирования
1.4. Описание видов
У каждого вида есть следующие параметры:
Здоровье
Область видимости
Скорость
Число потомков
Число квантов, необходимое для завершения спаривания
1.5. Описание статистики
Статистика сохраняется в файл по нажатию соответствующей кнопки и содержит:
Время создания отчета
Число квантов на момент создания отчета
Среднее и текущее число особей каждого вида
Параметры видов
Число особей от начала моделирования и фиксирующиеся через каждые 10 квантов
2. Листинг программы
Программа реализована на C# с использованием фреймворка XNA.
2.1. Класс животного
class AnimalFirst
{
public int maxHealth; //максимальное здоровье
public double nowHealth; //от 0 до 1 от максимального
public int vision; //в клетках
public double speed; //число квантов для 1 хода
public int numChild; //число потомков
public int age = 0; //возраст в квантах
public Vector2 coord; //координаты
public int cadr = 0; //текущий кадр спрайта
public bool isLove = true; //сыто ли животное
public int numQuantToLove;
public int vectorLove = 0;
private Random rnd;
private double needQuantToMove; //число квантов до следующего хода
private int needToLove;
private bool isPairing = false;
public void donePairing()
{
isLove = false;
nowHealth -= 0.5;
isPairing = false;
vectorLove = 0;
needToLove = numQuantToLove;
needQuantToMove = speed;
}
//определяет следующий шаг в направлении определенной клетки
private bool moveTo(int Y, int X, int N, Cell[,] cells);
//поведение особи
public int update(int N, double elapsed, Cell[,] cells, double quant, List<AnimalFirst> animals)
{
bool _isLove = false;
bool haveGrass = false;
nowHealth -= 0.2 / maxHealth;
age++;
if ((nowHealth < 0) || (age > speed*100 && !isPairing))
return -1;
if (isPairing && needToLove != 0)
{
needToLove--;
return 0;
}
if (nowHealth < 0.7) //поедание
{
needToLove = numQuantToLove;
isLove = false;
#region если на клетке с травой
if (cells[(int)coord.Y, (int)coord.X].isGrass)
{
cadr = 1;
haveGrass = true;
cells[(int)coord.Y, (int)coord.X].isGrass = false;
nowHealth += 10.0 / (double)maxHealth;
needQuantToMove = speed;
if (nowHealth > 1)
nowHealth = 1;
return 0;
}
#endregion
}
if (nowHealth >= 0.7) //спаривание
{
isLove = true;
#region если на соседней клетке с партнером
if (coord.X > 0 && cells[(int)coord.Y, (int)coord.X - 1].isAnimal)
{
List<AnimalFirst> aF = new List<AnimalFirst>();
Vector2 _coord = new Vector2(coord.X - 1, coord.Y);
aF = animals.FindAll(a => (a.coord == _coord));
if (aF.Count == 1 && aF[0].needToLove == 0 && aF[0].vectorLove == -vectorLove)
{
aF[0].donePairing();
this.donePairing();
return numChild;
}
else if (aF.Count == 1 && !aF[0].isPairing && aF[0].isLove)
{
isPairing = true;
aF[0].isPairing = true;
vectorLove = -1;
aF[0].vectorLove = 1;
return 0;
}
}
else if (coord.X < N - 1 && cells[(int)coord.Y, (int)coord.X + 1].isAnimal)
{
List<AnimalFirst> aF = new List<AnimalFirst>();
Vector2 _coord = new Vector2(coord.X + 1, coord.Y);
aF = animals.FindAll(a => (a.coord == _coord));
if (aF.Count == 1 && aF[0].needToLove == 0 && aF[0].vectorLove == -vectorLove)
{
aF[0].donePairing();
this.donePairing();
return numChild + 100;
}
else if (aF.Count == 1 && !aF[0].isPairing && aF[0].isLove)
{
isPairing = true;
aF[0].isPairing = true;
vectorLove = 1;
aF[0].vectorLove = -1;
return 0;
}
}
else if (coord.Y > 0 && cells[(int)coord.Y - 1, (int)coord.X].isAnimal)
{
List<AnimalFirst> aF = new List<AnimalFirst>();
Vector2 _coord = new Vector2(coord.X, coord.Y - 1);
aF = animals.FindAll(a => (a.coord == _coord));
if (aF.Count == 1 && aF[0].needToLove == 0 && aF[0].vectorLove == -vectorLove)
{
aF[0].donePairing();
this.donePairing();
return numChild + 200;
}
else if (aF.Count == 1 && !aF[0].isPairing && aF[0].isLove)
{
isPairing = true;
aF[0].isPairing = true;
vectorLove = -2;
aF[0].vectorLove = 2;
return 0;
}
}
else if (coord.Y < N - 1 && cells[(int)coord.Y + 1, (int)coord.X].isAnimal)
{
List<AnimalFirst> aF = new List<AnimalFirst>();
Vector2 _coord = new Vector2(coord.X, coord.Y + 1);
aF = animals.FindAll(a => (a.coord == _coord));
if (aF.Count == 1 && aF[0].needToLove == 0 && aF[0].vectorLove == -vectorLove)
{
aF[0].donePairing();
this.donePairing();
return numChild + 300;
}
else if (aF.Count == 1 && !aF[0].isPairing && aF[0].isLove)
{
isPairing = true;
aF[0].isPairing = true;
vectorLove = 2;
aF[0].vectorLove = -2;
return 0;
}
}
#endregion
}
if (needQuantToMove > 0)
{
needQuantToMove--;
}
if (needQuantToMove == 0)
{
needQuantToMove = speed;
cadr = 0;
if (nowHealth >= 0.7)
{
needToLove = numQuantToLove;
isLove = true;
vectorLove = 0;
isPairing = false;
#region поиск пары
for (int i = 1; (i < vision + 1) && !_isLove; i++)
{
for (int j = 0; (j < 4) && !_isLove; j++)
{
for (int k = 0; (k < 2 * i) && !_isLove; k++)
{
switch (j)
{
case 0:
if (((int)coord.Y - i) >= 0 && ((int)coord.Y - i) < N && ((int)coord.X - i + k) >= 0 && ((int)coord.X - i + k) < N)
if (cells[(int)coord.Y - i, (int)coord.X - i + k].isAnimal)
{
List<AnimalFirst> aF = new List<AnimalFirst>();
Vector2 _coord = new Vector2(coord.X - i + k, coord.Y - i);
aF = animals.FindAll(a => (a.coord == _coord && a.isLove == true));
if (aF.Count == 1)
{
_isLove = true;
this.moveTo((int)coord.Y - i, (int)coord.X - i + k, N, cells);
}
}
break;
case 1:
if (((int)coord.Y - i + k) >= 0 && ((int)coord.Y - i + k) < N && ((int)coord.X + i) >= 0 && ((int)coord.X + i) < N)
if (cells[(int)coord.Y - i + k, (int)coord.X + i].isAnimal)
{
List<AnimalFirst> aF = new List<AnimalFirst>();
Vector2 _coord = new Vector2(coord.X + i, coord.Y - i + k);
aF = animals.FindAll(a => (a.coord == _coord && a.isLove == true));
if (aF.Count == 1)
{
_isLove = true;
this.moveTo((int)coord.Y - i + k, (int)coord.X + i, N, cells);
}
}
break;
case 2:
if (((int)coord.Y + i) >= 0 && ((int)coord.Y + i) < N && ((int)coord.X + i - k) >= 0 && ((int)coord.X + i - k) < N)
if (cells[(int)coord.Y + i, (int)coord.X + i - k].isAnimal)
{
List<AnimalFirst> aF = new List<AnimalFirst>();
Vector2 _coord = new Vector2(coord.X + i - k, coord.Y + i);
aF = animals.FindAll(a => (a.coord == _coord && a.isLove == true));
if (aF.Count == 1)
{
_isLove = true;
this.moveTo((int)coord.Y + i, (int)coord.X + i - k, N, cells);
}
}
break;
case 3:
if (((int)coord.Y + i - k) >= 0 && ((int)coord.Y + i - k) < N && ((int)coord.X - i) >= 0 && ((int)coord.X - i) < N)
if (cells[(int)coord.Y + i - k, (int)coord.X - i].isAnimal)
{
List<AnimalFirst> aF = new List<AnimalFirst>();
Vector2 _coord = new Vector2(coord.X - i, coord.Y - i);
aF = animals.FindAll(a => (a.coord == _coord && a.isLove == true));
if (aF.Count == 1)
{
_isLove = true;
this.moveTo((int)coord.Y + i - k, (int)coord.X - i, N, cells);
}
}
break;
}
}
}
}
#endregion
#region случайный ход
if (!_isLove)
{
goRand(N, cells);
}
#endregion
return 0;
}
if (nowHealth < 0.7) //голод
{
needToLove = numQuantToLove;
isLove = false;
vectorLove = 0;
isPairing = false;
#region поиск травы
if (!haveGrass)
{
for (int i = 1; (i < vision + 1) && !haveGrass; i++)
{
for (int j = 0; (j < 4) && !haveGrass; j++)
{
for (int k = 0; (k < 2 * i) && !haveGrass; k++)
{
switch (j)
{
case 0:
if (((int)coord.Y - i) >= 0 && ((int)coord.Y - i) < N && ((int)coord.X - i + k) >= 0 && ((int)coord.X - i + k) < N)
if (cells[(int)coord.Y - i, (int)coord.X - i + k].isGrass)
{
haveGrass = true;
this.moveTo((int)coord.Y - i, (int)coord.X - i + k, N, cells);
}
break;
case 1:
if (((int)coord.Y - i + k) >= 0 && ((int)coord.Y - i + k) < N && ((int)coord.X + i) >= 0 && ((int)coord.X + i) < N)
if (cells[(int)coord.Y - i + k, (int)coord.X + i].isGrass)
{
haveGrass = true;
this.moveTo((int)coord.Y - i + k, (int)coord.X + i, N, cells);
}
break;
case 2:
if (((int)coord.Y + i) >= 0 && ((int)coord.Y + i) < N && ((int)coord.X + i - k) >= 0 && ((int)coord.X + i - k) < N)
if (cells[(int)coord.Y + i, (int)coord.X + i - k].isGrass)
{
haveGrass = true;
this.moveTo((int)coord.Y + i, (int)coord.X + i - k, N, cells);
}
break;
case 3:
if (((int)coord.Y + i - k) >= 0 && ((int)coord.Y + i - k) < N && ((int)coord.X - i) >= 0 && ((int)coord.X - i) < N)
if (cells[(int)coord.Y + i - k, (int)coord.X - i].isGrass)
{
haveGrass = true;
this.moveTo((int)coord.Y + i - k, (int)coord.X - i, N, cells);
}
break;
}
}
}
}
}
#endregion
#region случайный ход
if (!haveGrass)
{
goRand(N, cells);
}
#endregion
}
}
return 0;
}
//случайный ход
private void goRand(int N, Cell[,] cells);
//конструктор
public AnimalFirst(int seed,int X, int Y, int _maxHealth, double _nowHealth, double _speed, int _numChild, int _vision, int _needQuantToLove);
}