Код:
void GeneratePrim(MapCell **Massive) // создает лабиринт методом Прима
{
// очищаем массив атрибутов всех клеток
for (int c=0; c<Size; c++)
for (int v=0; v<Size; v++)
{ Massive[c][v].Attribute = Outside;
Massive[c][v].Left = false;
Massive[c][v].Up = false;
Massive[c][v].Right = false;
Massive[c][v].Down = false;
};
randomize(); // включение режима случайных чисел
int x = random(Size); // случайный выбор клетки в массиве
int y = random(Size);
Massive[x][y].Attribute = Inside; // установка в этой клетке атрибут “Внутренняя”
// Далее у всех соседей данной клетки выставляем атрибут “Граничная”
if ((x-1)>=0) Massive[x-1][y].Attribute = Border;
if ((x+1)<Size) Massive[x+1][y].Attribute = Border;
if ((y-1)>=0) Massive[x][y-1].Attribute = Border;
if ((y+1)<Size) Massive[x][y+1].Attribute = Border;
TPoint *mas; // выделяем память под список ячеек с параметром Border
mas = new TPoint[Size*Size];
int Bordcount; // количество клеток с атрибутом Border
do { // повторяем пока есть хотя бы одна клетка с атрибутом Border
Bordcount = 0; // очистка счетчика
// просматриваем массив ищем все клетки с атрибутом Border
for (int c=0; c<Size; c++)
for (int v=0; v<Size; v++)
if (Massive[c][v].Attribute == Border)
{mas[Bordcount].x = c; // если нашли такую клетку то записываем ее координаты
mas[Bordcount].y = v; // в буферный массив
Bordcount++; // увеличиваем счетчик
};
// выделим память под список соседей с атрибутом Inside
TPoint Ins[4]; // 4 элемента так как у клетки может быть только 4 соседа
int count = 0; // счетчик
// Выберем случайную клетку, атрибут которой равен Border, и присвоим ей Inside
int buf = random(Bordcount); // выбрали номер наугад
x = mas[buf].x; // получили координаты из массива
y = mas[buf].y;
Massive[x][y].Attribute = Inside; // изменили атрибут
// Изменим на Border атрибут всех соседних с текущей клеток, атрибут которых
// равен Outside
if ((x-1)>=0) // проверка не выходим ли мы за пределы массива
if (Massive[x-1][y].Attribute == Outside) Massive[x-1][y].Attribute = Border;
else if (Massive[x-1][y].Attribute == Inside)
{Ins[count].x = x-1; // сохраняем координаты соседней клетки
Ins[count].y = y;
count++;
};
if ((x+1)<Size) // проверка не выходим ли мы за пределы массива
if (Massive[x+1][y].Attribute == Outside) Massive[x+1][y].Attribute = Border;
else if (Massive[x+1][y].Attribute == Inside)
{Ins[count].x = x+1; // сохраняем координаты соседней клетки
Ins[count].y = y;
count++;
};
if ((y-1)>=0) // проверка не выходим ли мы за пределы массива
if (Massive[x][y-1].Attribute == Outside) Massive[x][y-1].Attribute = Border;
else if (Massive[x][y-1].Attribute == Inside)
{Ins[count].x = x; // сохраняем координаты соседней клетки
Ins[count].y = y-1;
count++;
};
if ((y+1)<Size) // проверка не выходим ли мы за пределы массива
if (Massive[x][y+1].Attribute == Outside) Massive[x][y+1].Attribute = Border;
else if (Massive[x][y+1].Attribute == Inside)
{Ins[count].x = x; // сохраняем координаты соседней клетки
Ins[count].y = y+1;
count++;
};
// теперь из полученного массива соседей выберем случайную и сломаем “стену”
// между текущей и ей
// это будет означать что из текущей клетки можно перейти в соседнюю
// X и Y до сих пор содержат текущие координаты в массиве лабиринта
buf = random(count); // выбрали случайную клетку из массива соседей
if ((Ins[buf].x > x) & (Ins[buf].y == y)) // определяем что сосед находиться правее…
{ Massive[Ins[buf].x][Ins[buf].y].Left = true;
Massive[x][y].Right = true;
} else
if ((Ins[buf].x < x) && (Ins[buf].y == y)) // сосед находиться левее
{ Massive[Ins[buf].x][Ins[buf].y].Right = true;
Massive[x][y].Left = true;
}else
if ((Ins[buf].x == x) && (Ins[buf].y > y)) // сосед находиться ниже
{ Massive[Ins[buf].x][Ins[buf].y].Up = true;
Massive[x][y].Down = true;
}else
if ((Ins[buf].x == x) && (Ins[buf].y < y)) // сосед находиться выше
{ Massive[Ins[buf].x][Ins[buf].y].Down = true;
Massive[x][y].Up = true;
};
} while (Bordcount > 0); // повторяем пока существуют клетки с атрибутом Border
delete [] mas; // очищаем буферы.
};