Как сделать?
…
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
Вроде, по сути одно и то же…