RU 📌 Pinned

Как сделать?

Dark[Ol(U23)leneri] #34 18.04.2010 22:57 6408 comments 2433534 views

evp,
Спасибо!
Вета,
Я правильно понял, определены только сами комнаты, и их надо рандомом разместить в коридорах, которые тоже надо рандомно создать?
И ещё, обычные предметы должны быть в одном экземпляре?

Только сейчас заметил.

Вета:

Игрок появляется опять же рандомно в одной из этих комнат.

Я в своем примере это условие не предусмотрел. Появляться надо именно в коридоре (любом). Если вы поймете мою логику, то без проблем подстроите программу под ваше условие. Если же с этим возникнут трудности - спрашивайте. Тут много кто сможет помочь с этим.

evp, спасибо, попробую разобраться :)

Я перечитал свой код и должен сказать, что dynamic в конкретном случае не оправдан. Он был бы нужен, если бы мы не просто входили в дверь, а еще и совершали некоторые другие действия в зависимости от того в какую дверь мы вошли. Например, он может понадобиться при генерации предметов в комнате в момент входа. В нашем же, простом, случае можно обойтись без него. Если его убрать, может быть код станет легче для понимания.

1. Формируем списки всех еще не посещенных комнат и дверей, в которые мы еще не входили:

!Стартовая локация 
n = 0 
:next_destination 
    $destination[] = 'room<<n>>' 
    $door[] = "NULL" 
    n += 1 
if n < 40: jump 'next_destination'

2. Локацию door слегка изменяем (логика ее работы остается прежней):

x = ARGS[0] 
$name = $ARGS[1] 
act 'Открыть <<$name>> дверь': 
    if $door[x] = 'NULL': 
        n = RAND(0, ARRSIZE('$destination') - 1) 
        $door[x] = $destination[n] 
        KILLVAR '$destination', n 
    end 
    gt $door[x] 
end

3. Входим в двери:

gs 'door', 0, 'западную' 
gs 'door', 1, 'северную' 
gs 'door', 2, 'восточную'

интересно, зачем нужен коридор и какая разница в какую именно дверь мы выходим?
не проще ли сделать всего одну комнату с (да хоть с десятью) дверями, выход в которые всё равно gs curloc в, которой рандомно определяется тип комнаты, её внешний вид, мебель и наполнение предметами? чего городить то огород на пустом месте, там всё до безумного проще, чем кажется на первый взгляд )))

Перечитайте условия задания еще раз.
[*]

Вета:

Есть дом с 30-35 комнатами, которые описаны заранее

[*]

Вета:

Комната генерится, когда игрок в нее заходит и до конца игры, естественно, остается в таком состоянии.

[*] От себя добавлю, что повторный вход в одну и ту же дверь должен приводить в одну и ту же комнату, а не каждый раз в случайную.

И, конечно, я могу эмулировать дом со всеми случайно генерируемыми коридорами и комнатами (заодно и со случайными предметами квестовыми и не квестовыми) в коде всего однойлокации так, что игрок не догадается, что локация одна. Но ведь это не входит в условия и не является целью, т.к. практически не нужно. И уж, конечно, не “безумно проще”.

Ждем от вас безумно простой реализации задуманного в виде кода, а не абстрактных суждений.

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

!Стартовая локация 
!Формируем список комнат
n = 0 
:next_destination 
    $destination[] = 'room<<n>>'  
    n += 1 
if n < 40: jump 'next_destination'

!Формируем список соответствия дверей комнатам
x = 0 
:next_door 
    n = RAND(0, ARRSIZE('$destination') - 1) 
    $door[] = $destination[n] 
    KILLVAR '$destination', n
    x += 1  
if x < 40: jump 'next_door'

Входим в двери:

act 'Войти в восточную дверь': gt $door[1]
act 'Войти в западную дверь': gt $door[0]
act 'Войти в северную дверь': gt $door[2]

C точки зрения игрока нет никакой разницы между первым и вторым вариантом реализации.

Хотя… небольшая разница все-таки есть. В первом варианте игрок может сохраниться перед входом в дверь, а если ему не понравилась комната за этой дверью, то после загрузки сейва он с большой долей вероятности (зависит от числа уже открытых дверей) попадет уже в другую комнату, т.к. соответствие между дверью и комнатой назначается в момент входа, т.е. после сохранения. Во втором варианте двери ассоциируются с комнатами при старте игры. Таким образом при втором варианте реализации за каждой дверью будет всегда одна определённая комната и изменить это можно только начав новую игру.

Трям, господа. Можете глянуть этот код? Попытался создать генерируемые коридоры, как требуется Вета, но что-то где-то с arrsize ошибся. В $rooms_hall иногда остаются необработанные элементы.

Spoiler
killvar
usehtml = 1
!Цикл для создания массива комнат
n=0
r=0
h=0
t=0
x=0
z=0
y=0
:next_room
    $rooms[] = 'Дверь в комнату'  &!решить, что с этим делать
    $rooms_hall[] = "NULL" &!В каком коридоре вход
    n += 1
if n < 30: jump 'next_room'
:next_hall
	$halls[] = 'Коридор'
	r=RAND(1,3) &!Количество комнат на коридор
	h=RAND(1,4-r) &!Переходы в другие коридоры
    :one_more_room
    t = rand(0,ARRSIZE('$rooms')-1) &!Номер комнаты, которая добавляется
    $rooms_hall[t] = ARRSIZE('$halls')-1 &!Номер текущего элемента в массиве как номер связанного с комнатой коридора
    KILLVAR '$rooms',t &!Удаляет текущую комнату из временного списка
    r -= 1
	if r>1: jump 'one_more_room'
	:one_more_hallway
	$hallway[]=ARRSIZE('$halls')
	h -= 1
	if h>1: jump 'one_more_hallway'
if ARRSIZE('$rooms')>1: jump 'next_hall'
cla
*clr
x=rand(1,arrsize('$halls'))
'arrsize halls <<arrsize("$halls")>>'
'arrsize rooms <<arrsize("$rooms")>>'
'arrsize rooms_hall <<arrsize("$rooms_hall")>>'
'arrsize hallway <<arrsize("$hallway")>>'
'Коридор <<x>>'
if arrpos('$rooms_hall',x) = -1: 'Все двери в этом коридоре заперты'
else:
	z=0
	:room_again
	'Дверь в комнату <<z>> в коридоре <<$rooms_hall[z]>>'
	if $rooms_hall[z]=x:'Открыта дверь в комнату <<z>>'
	z+=1
	if z<ARRSIZE('$rooms_hall'): jump 'room_again'
end
y=0
:hall_again
if $hallway[y]=x:'<a HREF="EXEC:gt ''start''">Коридор, ведёт куда-то</a> '
y+=1
if y<ARRSIZE('$hallway'): jump 'hall_again'

Как создать выбор из нескольких картинок?

zeek17,

if ARRSIZE('$rooms')>1: jump 'next_hall'

Если этой строчкой вы хотите сказать: генерировать новый коридор, если есть еще “неприсвоенные” коридорам комнаты, то тут ошибка. На самом деле вы говорите: генерировать новый коридор до тех пор, пока количество неохваченных комнат будет не менее 2-х. ARRSIZE возвращает нам длину массива, выраженную в количестве элементов в штуках. Выражение ARRSIZE(’$rooms’)>1 будет истинным при количестве элементов от 2-х и более. Если хотите организовать проверку на не пустой массив, следует писать

if ARRSIZE('$rooms')>0: jump 'next_hall'

Или, если помнить, что ложь в QSP равна нулю, а истина - любому другому числу, то можно упростить:

if ARRSIZE('$rooms'): jump 'next_hall'

Кроме того, вызывает подозрения этот участок:

:one_more_room 
        t = rand(0,ARRSIZE('$rooms')-1) &!Номер комнаты, которая добавляется 
        $rooms_hall[t] = ARRSIZE('$halls')-1 &!Номер текущего элемента в массиве как номер связанного с комнатой коридора 
        KILLVAR '$rooms',t &!Удаляет текущую комнату из временного списка 
        r -= 1 
    if r>1: jump 'one_more_room'

Здесь вы пытаетесь добавить в коридор комнаты в количестве r. Но вы нигде не проверяете, есть ли у вас r комнат. Подумайте, что будет, если r выпадет равным 3, а у вас в массиве $rooms осталось всего два элемента.

Избежать попадания впросак можно, к примеру, так:

!r=RAND(1,3) &!Количество комнат на коридор
r = iif (ARRSIZE('$rooms') > 2, RAND(1,3), RAND(1, ARRSIZE('$rooms'))) &!Количество комнат на коридор
h=RAND(1,4-r) &!Переходы в другие коридоры

WeReT, конкретней. Ничего не понятно из вопроса.

evp,, снова спасиб!
А if r>1 and ARRSIZE(’$rooms’): jump ‘one_more_room’ нормально сработает??
Не пробовали запустить мой код? Там где-то половина комнат вместо коридора NULL показывает. Хочу понять, где ошибся.

WeReT:

Re: Как сделать?

Как создать выбор из нескольких картинок?

photo_random=rand(1,99)
‘img src=“images/pic_<<photo_random>>.gif”’

zeek17:

if r>1 and ARRSIZE(’$rooms’): jump ‘one_more_room’

А если r = 1, то можно комнату не добавлять?

if r and ARRSIZE('$rooms'): jump 'one_more_room'

Но, вообщем-то, я же в предыдущем сообщении показал как эту проблему победить в самом зародыше, т.е. избежать генерации невалидного r в принципе.

zeek17:

Там где-то половина комнат вместо коридора NULL показывает

$rooms_hall[t] = ARRSIZE('$halls') - 1 
!Номер текущего элемента в массиве как номер связанного с комнатой коридора

В этом контексте $rooms_hall[t] не имеет практического смысла. Потому что t не указывает на номер комнаты. Подумайте почему. Подсказка: проследите за тем как изменяются размерымассивов $rooms_hall и $rooms с течением времени.

evp,
….вот оно что. Спасибо.
И последний вопрос на сегодня. Первый цикл изменил так:

n=0
:next_room
    $rooms[] = '<<n>>'
    $rooms_hall[] = 'null'
    n += 1
if n < 20: jump 'next_room'

Почему этот код делает что от него нужно:

t = rand(1,ARRSIZE('$rooms'))-1
k = $rooms[t]
$rooms_hall[k] = ARRSIZE('$halls')-1

А вот это выдаёт чушь:

t = rand(1,ARRSIZE('$rooms'))-1
$rooms_hall[$rooms[t]] = ARRSIZE('$halls')-1

Вроде, по сути одно и то же…

Log in or Register to post comments.