Динамически генерируемый лабиринт на INSTEAD

Рабочий пример динамически генерируемого лабиринта. В примере можно перемещаться в 6 направлениях, стороны света плюс вверх-вниз. При нажатии на ссылку пути генерируется новая комната с такими же путями, можно вернуться в предыдущую комнату. Она сохраняется. Побочный эффект — чем больше бродишь, тем больше сейв.

Код под спойлером
-- $Name:Нанотест$
-- $Version:0.01$
-- $Name(ru):Нанотест$
instead_version "1.8.0"

require "xact"			-- подключаем модуль xact
require "hideinv"		-- подключаем модуль hideinv
require "para"			-- догадайтесь, что мы подключили в этот раз ;)
require "dash"			-- подключаем dash
require "quotes"		-- подключаем quotes

game.codepage="UTF-8";

game.act = 'Не получается.';
game.inv = 'Хм, странная штука.';
game.use = 'Не сработает.';

global {
x = 0;
y = 0;
z = 0;
roomname = 'room0_0_0';
myrooms = {};
};

function myconstructor()
	local v = {};
	v.nam = roomname;
--в dsc выводится номер текущей комнаты, но также можно генерировать сюда любое описание.
	v.dsc = roomname;
        v.disp = 'Название';
	v.way = {vroom('Север', north), vroom('Восток', east), vroom('Юг', south), vroom('Запад', west), vroom('Вверх', up), vroom('Вниз', down)};
	v.exit = function(s, t)
		if t == north then
			y = y + 1;
			roomname = 'room'..x..'_'..y..'_'..z;
			if myrooms[roomname] then
				p 'Все гут';
			else
				myrooms[roomname] = new('myconstructor()');
			end;
			walk(myrooms[roomname]);
		elseif t == east then
			x = x + 1;
			roomname = 'room'..x..'_'..y..'_'..z;
			if myrooms[roomname] then
				p 'Все гут';
			else
				myrooms[roomname] = new('myconstructor()');
			end;
			walk(myrooms[roomname]);
		elseif t == south then
			y = y - 1;
			roomname = 'room'..x..'_'..y..'_'..z;
			if myrooms[roomname] then
				p 'Все гут';
			else
				myrooms[roomname] = new('myconstructor()');
			end;
			walk(myrooms[roomname]);
		elseif t == west then
			x = x - 1;
			roomname = 'room'..x..'_'..y..'_'..z;
			if myrooms[roomname] then
				p 'Все гут';
			else
				myrooms[roomname] = new('myconstructor()');
			end;
			walk(myrooms[roomname]);
		elseif t == up then
			z = z + 1;
			roomname = 'room'..x..'_'..y..'_'..z;
			if myrooms[roomname] then
				p 'Все гут';
			else
				myrooms[roomname] = new('myconstructor()');
			end;
			walk(myrooms[roomname]);
		elseif t == down then
			z = z - 1;
			roomname = 'room'..x..'_'..y..'_'..z;
			if myrooms[roomname] then
				p 'Все гут';
			else
				myrooms[roomname] = new('myconstructor()');
			end;
			walk(myrooms[roomname]);
		end;
	end;
	return room(v);
end;

---Начало---------------------------------------------------------------------------------------------------------------

main = room {
	forcedsc = true;
	nam = 'Начало';
	enter = function()
		myrooms['room0_0_0'] = new('myconstructor()');
		start = myrooms['room0_0_0'];
		take 'stone';
	end;
--	pic = 'gfx/01.jpg';
	dsc = '';
	way = {vroom('Играть', 'start')};
};

--пачка комнат-заглушек, т.к. vroom надо ссылаться на реальную комнату.

north = room {
	nam = 'Заглушка';
};

east = room {
	nam = 'Заглушка';
};

south = room {
	nam = 'Заглушка';
};

west = room {
	nam = 'Заглушка';
};

up = room {
	nam = 'Заглушка';
};

down = room {
	nam = 'Заглушка';
};


Дальнейшие планы: генерация контента при помощи рандома в enter генерируемой комнаты. Отключение путей при необходимости и прочее. В общем это что-то генерируемого открытого мира без ограничений. Можно написать что-нибудь рогаликопобное. Я пока думаю над стратегией в фентезийном стиле. В общем покажу что-нибудь через полгодика. Может раньше.

13 комментариев

techniX
Отлично!
Предлагаю немного улучшенный вариант: pastebin.com/jV6G27Tk
Irremann
Вынос логики в функции рулит!
DoubleDragon
Друзья, давайте при публикации решений для конкретной платформы дописывать в названии топика имя платформы. В данном случае стоит писать «Динамически генерируемый лабиринт в Instead». Окей?
Peter
Теги для этого же есть. В тегах стоит.
DoubleDragon
На почту теги не приходят:

«Пользователь Irremann опубликовал в блоге «Разработка» новый топик — Динамически генерируемый лабиринт
С уважением, администрация сайта ifHub.ru»


Да и в списке топиков мелкие теги никто не читает.
Volt
На хабре для этого есть специальный тег «никто не читает теги» :)
DoubleDragon
Спасибо большое. Так гораздо понятнее.
Diz100rM
Опыта у меня маловато (мягко сказано) и я не очень понимаю как будут генерироватся новые комнаты! Ну тоесть у нас есть комната 'room0_0_0', и мы идем например на юг скажем меняем Y то получится комната 'room0_1_0'!
Отсюда вопрос, как будет создаватся комната 'room0_1_0'!
Простите за неопытность в коддинге
Irremann
Смотри, тут есть функция myconstructor(), которая создает комнату, в exit которой записано обращение к функции new, которая обращается опять к myconstructor() и создает еще одну аналогичную комнату. Комнаты записываются в массив myrooms[].

Какое-либо описание, добавление объектов и прочее можно вписывать в enter. В общем тут ничего сложного, особенно после того как мне все объяснил Петр, но если кажется сложным, то возможно стоит для начала создать более классическую игру =).
Diz100rM
Теперь все понял =) Доступно обьяснили!
Во 1 не увидел в начале то что все это находится в функции myconstructor()
Во 2 перечитав код, понял весь принцип работы =)

Я думаю выйдет неплохой рпг квест, с подземельями, монстрами, и рандомно разбросанными элексирами и вещами! (Лично мнение, не осуждайте) :)
Irremann
Я стратегию пока делаю, с подземельем, монстрами и ресурсами. Может быть РПГ-элементы.
Diz100rM
Ну чтож ждем, ждем)
А пока пойду исправлять корявый код в своей игре! Думаю через недельку уже выложу =)