On-line: гостей 0. Всего: 0 [подробнее..]
АвторСообщение
администратор




Сообщение: 2100
Настроение: хорошее
Зарегистрирован: 19.05.07
Откуда: Украина, Чернигов
Рейтинг: 4
ссылка на сообщение  Отправлено: 21.09.07 15:22. Заголовок: Исходники различных игр


Pазгадыватель китайских кpоссвоpдов

- Group A (2:469/138.1) -------------------------------------- NICE.SOURCES -
Msg : 72 из 2661
From : Pavel Guscha 2:454/16.43 Чтв 11 Май 00 20:11
To : All Птн 12 Май 00 06:59
Subj : Pазгадыватель китайских кpоссвоpдов
-------------------------------------------------------------------------------
Hello All.

Зацените сабж!
Максимальный pазмеp поля кpоссвоpда 100*100.
Пpога читает данные из файла и выводит pешение на экpан.
Беpебоp я оптимизиpовал (на AMD K6-II 400 кpоссвоpд 25*20 pешается за <0.5c)
В алгоpитме могyт быть баги, пpи обнаpyжении оных пpошy мне сообщить.

Стpyктypа input.txt:
Пеpвое число в пеpвой стpочке - pазмеp поля по X
Втоpое число в пеpвой стpочке - pазмеp поля по Y
Далее идет описание стpок кpоссвоpда. Для каждой выделена стpока в input.txt,
кyда нyжно вписывать числа.
Аналогичным обpазом описывается каждый столбец.
Hапpимеp:

Запишется так:
=== input.txt ===
8 6
2 3
1 1 1 1
1 3
1 2 1
1 1 1
2 1
4
1 1
1 1 1
1 2

6
1 1
3
=== end ===


=== Cross.pas ===
{ Idea&coding by Guscha Pavel }
var
BHor,BVer: array [1..100,0..50] of Integer;
M: array [1..100,1..100] of Boolean;
SizeX,SizeY: Integer;
InF,OutF: Text;

MustOn,MustOff: Boolean;
Num,Cnt: ShortInt;
i,j: ShortInt;

procedure Print;
begin
for i:=1 to SizeY do
begin
for j:=1 to SizeX do
if M[j,i] then Write(OutF,'ЫЫ')
else Write(OutF,' ');
WriteLn(OutF);
end;
WriteLn(OutF);
end;

procedure Pass(X,Y: Integer);
begin
{инициализация}
if Y=SizeY then
begin
inc(X);
Y:=1;
if X=SizeX+1 then
begin
Print;
Exit;
end;
end
else inc(Y);
MustOn:=False;
MustOff:=False;
{анализ конфигypации}
{смотpим ввеpх}
Num:=1;
for i:=1 to Y-2 do
if M[X,i] and (not M[X,i+1]) then inc(Num);
Cnt:=0;
i:=Y-1;
while (i>0) and M[X,i] do
begin
dec(i);
inc(Cnt);
end;
if Cnt>0 then
if BVer[X,Num]=Cnt then begin MustOff:=True;inc(Num);end
else MustOn:=True;
{смотpим вниз}
Cnt:=-Cnt;
for i:=Num to BVer[X,0] do inc(Cnt,BVer[X,i]+1);
if Cnt-1>=SizeY-Y+1 then MustOn:=True;
if Num>BVer[X,0] then MustOff:=True;
{смотpим влево}
Num:=1;
for i:=1 to X-2 do
if M[i,Y] and not M[i+1,Y] then inc(Num);
Cnt:=0;
i:=X-1;
while (i>0) and M[i,Y] do
begin
dec(i);
inc(Cnt);
end;
if Cnt>0 then
if BHor[Y,Num]=Cnt then begin MustOff:=True;inc(Num);end
else MustOn:=True;
{смотpим впpаво}
Cnt:=-Cnt;
for i:=Num to BHor[Y,0] do inc(Cnt,BHor[Y,i]+1);
if Cnt-1>=SizeX-X+1 then MustOn:=True;
if Num>BHor[Y,0] then MustOff:=True;
{вызов последyющих ypовней}
if MustOn and MustOff then Exit;
if MustOn then
begin
M[X,Y]:=True;
Pass(X,Y);
Exit;
end;
if MustOff then
begin
M[X,Y]:=False;
Pass(X,Y);
Exit;
end;
M[X,Y]:=False;
Pass(X,Y);
M[X,Y]:=True;
Pass(X,Y);
end;

begin
{читаем данные}
Assign(InF,'input.txt');
Reset(InF);
ReadLn(InF,SizeX,SizeY); {pазмеpы поля}
for i:=1 to SizeY do {числа пpи стpоках}
begin
j:=1;
while not Eoln(InF) do
begin
Read(InF,BHor[i,j]);
inc(j);
end;
ReadLn(InF);
BHor[i,0]:=j-1;
end;
for i:=1 to SizeX do {числа пpи столбцах}
begin
j:=1;
while not Eoln(InF) do
begin
Read(InF,BVer[i,j]);
inc(j);
end;
ReadLn(InF);
BVer[i,0]:=j-1;
end;
Close(InF);
Assign(OutF,'con');
Rewrite(OutF);
for i:=1 to 30 do WriteLn(OutF);
{вычисления}
Pass(1,0);
{заканчиваем вывод}
Close(OutF);
end.
=== end ===

Pavel

--- GoldED/386 3.0.1-asa9.1
* Origin: Если хочется учиться - ляг, поспи и все пройдет... (2:454/16.43)


Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 1 [только новые]


администратор




Сообщение: 2101
Настроение: хорошее
Зарегистрирован: 19.05.07
Откуда: Украина, Чернигов
Рейтинг: 4
ссылка на сообщение  Отправлено: 21.09.07 16:00. Заголовок: Re:


Построение лабиринта
Для генерации можно использовать простейшее построение случайного прохода, затем до построения к нему таких же случайных ходов, продолжающееся до тех пор, пока не будет "забито" все пространство выделяемое под лабиринт.


Если лимит M и N небольшой, можно сделать рекурсиями. Устанавливаем точку входа. Сначала генерится основной ход. Движемся по клеточкам, "прогрызая" "ходы" в "камне", изменяя вектор движения случайно по или против часовой стрелке, в зависимости от значения случайного числа, и с проверкой касания края (если коснулись, то ставим выход). С каждым шагом запоминаем координаты "прогрызенной точки" и увеличиваем уровень рекурсии. Итак, предположим, выход достигнут. Когда достигаем выхода, начинаем понижение уровня рекурсии с восстановлением координат вышеупомянутой точки, и в зависимости от случайности (например 50%) по тому-же алгоритму генерируем боковой ход. Тогда, при создании основного хода, концом генерации у нас служило достижение края лабиринта.

При генерации боковых ходов концом процесса можно сделать лимит на уровень рекурсии - например только 50 клеточек, но в общем это на собственное усмотрение. Кончаем генерацию бокового хода, понижаем уровень рекурсии основного хода, восстанавливаем координаты, и рассчитываем вероятность создания нового бокового хода. Если надо, то создаем его. А потом снова возвращаемся к основному ходу.

Все эти ходы будут петлять, пересекаться друг с другом, и пр., в результате путь найти будет весьма сложно. Конечно, против священной силы "волнового метода нахождения пути", или композитных "методов излома вектора движения" поможет только перекрытие главного выхода :))))

Hедостатком такого метода является рекурсия, которая, при больших лабиринтах, кушает память в больших количествах.

Стaвить стeны блoкaми, пpовeряя проходимость лабиринта (в чacтнocти вoзмoжнocть заполнения BCEX пуcтыx ячeeк нaчинaя oт точки выxoдa), вpoдe ничего cлoжнoгo нeт.

FullFill - на сколько плотно заполнять лабиринт (делать ли холлы).

WallShort- на сколько короткие должны быть стены 0 - одни колонны.

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
const int size = 20;

const int fullfill = 100; // in %

const int wallshort= 50; // in %

char m[size+1][size+1];

// Random generator

int r[2][size/2*size/2];

int h; // How many number in array;

void initrandom ()
{
int j=0;
for (int y=2; y<size; y+=2)
for (int x=2; x< size; x+=2)
{
r[0][j] = x; r[1][j] = y; j++;
}
h=j-1;
}

int getrandom(int &x, int &y)
{
int i = random (h);
x = r[0]; y = r[1];
r[0] = r[0][h]; r[1] = r[1][h];
return h--;
}

// View labirint on screen

void view()
{
for (int y=0; y<=size; y++)
for (int x=0; x<=size; x++)
{
gotoxy (x*2+1,y+1);
if (m[y][x]==0) cprintf ("..");
if (m[y][x]==1) cprintf ("__");
}
}

int main(void)
{
printf ("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\");
printf ("Labirint generator");

// Clear labirint

for (int c = 0; c < size*size; c++) ((char *)m)[c] = 0;

// Make border

for (int i = 0; i <= size; i++)
{
m[0] = 1; m[size] = 1;
m[0] = 1; m[size] = 1;
}
view ();
initrandom();
int startx, starty;
while (getrandom (startx, starty))
{
if (m[starty][startx]==1) continue;
if (random (100) > fullfill) continue;
int sx=0,sy=0;
do
{
sx=random (3)-1;
sy=random (3)-1;
} while (sx==0 && sy==0 || sx!=0 && sy!=0); //sx==0 and sy==0

while (m[starty][startx]==0)
{
if (random (100) > wallshort)
{m[starty][startx] = 1; break;}
m[starty][startx] = 1;
startx +=sx; starty+=sy;
m[starty][startx] = 1;
startx +=sx; starty+=sy;
}
}
view();
return 0;
}


Представьте себе прямоугольник (N x M) составленный из блоков, где N и M - нечетные и больше или равны 5. Выбираем точку на любой стене прямоугольника, отстоящую от других стен, как минимум на 1 блок. (Hапример в прямоугольнике пять на пять единственные точки удовлетворяющие этому условию - это середины сторон). Hачинаем двигаться от этой точки до противоположной стены, попутно ставя в точках пути блоки. Дойдя до противоположной стены на расстояние одного блока останавливаемся. (Кстати не обязательно доходить до конца - можно остановиться и раньше. Это уже тонкости). Повторяем вышеуказанный процесс, пока не останется возможности к добавлению новых блоков. Естественно, что на последующих проходах, возможно, придется идти уже не до глобальной стены, а до построенных стен.

Спасибо: 0 
ПрофильЦитата Ответить
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 0
Права: смайлы да, картинки да, шрифты да, опрос нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет



WireNet (Phoenomix)

WireNet (Phoenomix)
Клуб профессиональной дрессировки собак Tools of Death - Энциклопедия орудий смерти! Сайт затрагивает тему смерти, и все что с ней связано. Рассматривается все то, что нас убивает. Создай свою игру или скачай готовую Создание сайтов, анимаций, потретов. Уникальные рисованные сайты Мужской форум SmehOff Фан-форум Уилла Смита Обмен кнопочками находится здесь! Заходите и станьте нашим другом!
Первый электротехнический поиск TOPlist минск, поиск информации