Алгоритм створення лабіринту: відмінності між версіями

[неперевірена версія][неперевірена версія]
Вилучено вміст Додано вміст
Рядок 384:
==Приклад коду мовою С==
Нижче наведен приклад алгоритму пошуку в глибину для створення лабіринту мовою С.
<source lang="ca65c">
//Код написан JacekЯцеком WieczorekВічореком
 
#include <stdio.h>
Рядок 394:
typedef struct
{
int x, y; //Позиція вузла - маломала витрата пам'яті, але сприяє швидшему генеруванню
void *parent; //Покажчик на батьківський вузол
char c; //Символ для відображення
Рядок 434:
Node *link( Node *n )
{
//Connects node to random neighbor (if possible) and returns
//Підключає вузол до випадкового сусіда (якщо можливо) і повертає
//address of next node that should be visited
//адресу наступного вузла, який слід відвідати
 
int x, y;
char dir;
Node *dest;
//Nothing can be done if null pointer is given - return
//Нічого не можна зробити, якщо задано нульовий покажчик - вихід
if ( n == NULL ) return NULL;
//While there are directions still unexplored
//Поки є напрямки досі невизначені
while ( n->dirs )
{
//Randomly pick one direction
//Довільно вибирається один напрямок
dir = ( 1 << ( rand( ) % 4 ) );
//If it has already been explored - try again
//Якщо вона вже була досліджена - спробуйте ще раз
if ( ~n->dirs & dir ) continue;
//Mark direction as explored
//Позначити напрямок як досліджений
n->dirs &= ~dir;
//Depending on chosen direction
//Залежно від обраного напрямку
switch ( dir )
{
//Check if it's possible to go right
//Перевірте, чи можна йти праворуч
case 1:
if ( n->x + 2 < width )
Рядок 468 ⟶ 469:
break;
//Check if it's possible to go down
//Перевірте, чи можна спуститися
case 2:
if ( n->y + 2 < height )
Рядок 478 ⟶ 479:
break;
//Check if it's possible to go left
//Перевірте, чи можна йти ліворуч
case 4:
if ( n->x - 2 >= 0 )
Рядок 488 ⟶ 489:
break;
//Check if it's possible to go up
//Перевірте, чи можна піднятися
case 8:
if ( n->y - 2 >= 0 )
Рядок 499 ⟶ 500:
}
//Get destination node into pointer (makes things a tiny bit faster)
//Отримати вузол призначення через покажчик (що робить речі трохи швидшими)
dest = nodes + x + y * width;
//Make sure that destination node is not a wall
//Переконайтеся, що вузол призначення не є стіною
if ( dest->c == ' ' )
{
//If destination is a linked node already - abort
//Якщо призначення вже є зв'язаним вузлом - перервати
if ( dest->parent != NULL ) continue;
//Otherwise, adopt node
//В іншому випадку прийняти вузол
dest->parent = n;
//Remove wall between nodes
//Видалення стінки між вузлами
nodes[n->x + ( x - n->x ) / 2 + ( n->y + ( y - n->y ) / 2 ) * width].c = ' ';
//Return address of the child node
//Повернення адреси дочірнього вузла
return dest;
}
}
//If nothing more can be done here - return parent's address
//Якщо нічого більше тут не можна зробити - поверніть батьківську адресу
return n->parent;
}
Рядок 527 ⟶ 528:
int i, j;
 
//Outputs maze to terminal - nothing special
//Вихідні дані лабіринта до терміналу - нічого особливого
for ( i = 0; i < height; i++ )
{
Рядок 542 ⟶ 543:
Node *start, *last;
 
//Check argument count
//Перевірити кількість аргументів
if ( argc < 3 )
{
Рядок 549 ⟶ 550:
}
//Read maze dimensions from command line arguments
//Читання розмірів лабіринта з аргументів командного рядка
if ( sscanf( argv[1], "%d", &width ) + sscanf( argv[2], "%d", &height ) < 2 )
{
Рядок 556 ⟶ 557:
}
 
//Allow only odd dimensions
//Дозволити лише непарні розміри
if ( !( width % 2 ) || !( height % 2 ) )
{
Рядок 563 ⟶ 564:
}
//Do not allow negative dimensions
//Не допускати від'ємних розмірів
if ( width <= 0 || height <= 0 )
{
Рядок 570 ⟶ 571:
}
 
//Seed random generator
//Насінний випадковий генератор
srand( time( NULL ) );
//Initialize maze
//Ініціалізувати лабіринт
if ( init( ) )
{
Рядок 580 ⟶ 581:
}
//Setup start node
//Встановити початковий вузол
start = nodes + 1 + width;
start->parent = start;
last = start;
//Connect nodes until start node is reached and can't be left
//Підключаємо вузли до тих пір, поки не буде досягнутий початковий вузол і
//не буде покинутим
while ( ( last = link( last ) ) != start );
draw( );