RU 📌 Pinned

Как сделать?

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

ну вот для примера мой сокращенный код

Spoiler

act ‘Далее’:
act ‘Далее’:
act ‘Далее’:
act ‘Далее’:
act “Далее”:
и еще все больше и больше
act “Уйти” :
cla
*clr
gs curloc
end
end
act “Уйти” :
cla
*clr
gs curloc
end
end
act “Уйти” :
cla
*clr
gs curloc
end
end
act “Уйти” :
cla
*clr
gs curloc
end
end

неужели с переменными и условиями он не превратится в монстра в котором легко завязнуть?
или я действительно чего то не понимаю? можешь привести пример для 3-4 первых “уровней”

Aleks Versus Moderator 07.03.2016 20:34 (9 years ago)

saks,
если ты сначала продумаешь, что хочешь сделать, то не завязнешь. Вот наипростейший пример.
К тому же мне лично твой код кажется монстром. Тысяча повторяющихся “уйти” - зачем?

Вопрос, как сделать так, чтобы предмет “Очистить журнал” был последним, а предмет “Экипировка” первым?

Spoiler
IF $selobj = 'Неизвестная ягода': MSG 'Это можно есть? Ага, можно.'

IF $selobj = 'Экипировка':
 IF Двуручник = 1:
  ADDOBJ 'Стальная секира'
  ADDOBJ 'Легкий доспех из шкур'
END
 IF ВоинЩит = 1:
  ADDOBJ 'Стальной меч'
  ADDOBJ 'Дубовый кулачный щит'
  ADDOBJ 'Средняя стальная колчуга'
END
 IF Вор = 1:
  ADDOBJ 'Парные: Железные кинжали'
  ADDOBJ 'Темная накидка из лошадиной шкуры'
END
 IF Охотник = 1:
  ADDOBJ 'Железный кинжал'
  ADDOBJ 'Лук из тиса'
  ADDOBJ 'Железные стрелы(количество <<стрелы_кол>>)'
END
 IF Волшебник = 1:
  ADDOBJ 'Железный кинжал'
  ADDOBJ 'Посох из дуба (100 Маг Эн)'
  ADDOBJ 'Балахон священно служителя (+5 маг Урон)'
END
 DELOBJ 'Экипировка'
 ADDOBJ 'Обратно'
END

IF $selobj = 'Обратно':
ADDOBJ 'Экипировка'
DELOBJ 'Обратно'
DELOBJ 'Железный кинжал'
DELOBJ 'Посох из дуба (100 Маг Эн)'
DELOBJ 'Балахон священно служителя (+5 маг Урон)'
DELOBJ 'Железные стрелы(количество <<стрелы_кол>>)'
DELOBJ 'Лук из тиса'
DELOBJ 'Темная накидка из лошадиной шкуры'
DELOBJ 'Железный кинжал(левый)'
DELOBJ 'Железный кинжал(правый)'
DELOBJ 'Средняя стальная колчуга'
DELOBJ 'Дубовый кулачный щит'
DELOBJ 'Стальной меч'
DELOBJ 'Легкий доспех из шкур'
DELOBJ 'Стальная секира'
ADDOBJ 'Очистить журнал'
END

IF $selobj = 'Очистить журнал':
	CLR
END

UNSEL
Aleks Versus Moderator 09.03.2016 06:28 (9 years ago)

Oliver,
Чтобы сделать предмет первым:

addobj 'Экипировка','',1

чтобы сделать предмет последним:

addobj 'Очистить журнал','',countobj+1

если не ошибасюсь, так.

Друзья, нужно решить непростую для меня задачку.
Есть дом с 30-35 комнатами, которые описаны заранее и рандомно генерятся в разных частях дома в начале игры. Комнаты все немного разные. В этих комнатах опять же в начале игры рандомно генерятся квестовые и не очень предметы. Например, у нас 8 квестовых предметов и 15 обычных, которые обязательно должны присутствовать.
Вопрос: как это это скодить, а то мне лавры монструма покоя не дают :)

Трям. Есть пара вопросов.
Изначально я сделал локи од описание кораблей (ships) и снарядов (ammo) соответственно:

if $ARGS[0]='2'
	set sh_name = 'Баркас '
	set sh_desc = 'Большая лодка, на которую устанавливают малые пушки. Широко применяется по всему миру для пиратских или контрабандных вылазок. '
	set sh_hull = 200
	set sh_speed = 14
	set sh_cargo = 200
	set sh_crew = 20
	set sh_guns = 8
	set sh_gunsmaxcal = 12
	set sh_price = 2500
end
if $ARGS[0]='cannonball':
	set hulldamage = 10
	set saildamage = 5
	set crewdamage = 0.25
	set ammoweight = 3
	price = 2
end

Предполагалось (до этого я пока не дошёл) тип корабля и загруженных снарядов определять где-нибудь в статах:

my_ship = 2
ammo_loaded = 'cannonball'

И проводить вычисления во время боя как-то так:

gs 'ships','<<my_ship>>'
gs 'ammo', '<<ammo_loaded>>'
total_hulldamage = sh_guns*hulldamage
total_saildamage = sh_guns*saildamage 
total_crewdamage = sh_guns*crewdamage

А потом до меня как-то допёрло, что это не совсем массивы… И всё это надо переделать.
Собственно, вопросы. В вычислениях выше есть какие-нибудь ошибки? Два GS подряд друг друга не перебьют? Как можно выдернуть из массива на другой локе требуемое значение, желательно не загружая всю локу? Пока у меня только мысль через GS загружать обе локи, как предполагалось.

Ошибок нет. Зато присутствует некоторая “избыточность” кода.
[*] Вы являетесь последователем Секты Священного Оператора SET.

[*] В локацию ships нет необходимости передавать строковый аргумент. Уместно было бы

if ARGS[0]= 2

и

my_ship = 2
gs 'ships', my_ship

[*] Аналогично, вызов локации ammo логично делать так:

ammo_loaded = 'cannonball'
gs 'ammo', ammo_loaded

[*] Кроме того:

Документация QSP:

◾ Названия строковых переменных должны начинаться с символа ‘$’.

Следовательно, переменную ammo_loaded желательно переименовать в $ammo_loaded.
Также, переменные sh_name и sh_desc переименовать в $sh_name и $sh_desc.

Итого. Ответ на 1-й и 2-й вопросы - “нет”.
Третий вопрос.
У вас не то, чтобы “не совсем массивы”, а совсем не массивы. Если хотите массивы, то вот вам:

Spoiler
!Локация ships
$sh_name[1] = 'Имя1' 
$sh_desc[1] = 'Описание1' 
sh_hull[1] = 200 
sh_speed[1] = 14 
sh_cargo[1] = 200 
sh_crew[1] = 20 
sh_guns[1] = 8 
sh_gunsmaxcal[1] = 12 
sh_price[1] = 2500

$sh_name[2] = 'Баркас ' 
$sh_desc[2] = 'Большая лодка, на которую устанавливают малые пушки. Широко применяется по всему миру для пиратских или контрабандных вылазок. ' 
sh_hull[2] = 200 
sh_speed[2] = 14 
sh_cargo[2] = 200 
sh_crew[2] = 20 
sh_guns[2] = 8 
sh_gunsmaxcal[2] = 12 
sh_price[2] = 2500
!и так далее...
Spoiler
!Локация ammo
$ammo_name[1] = 'cannonball' 
hulldamage[1] = 10 
saildamage[1] = 5 
crewdamage[1] = 0.25 
ammoweight[1] = 3 
price[1] = 2

$ammo_name[2] = 'knuppel' 
hulldamage[2] = 5 
saildamage[2] = 10
crewdamage[2] = 0.25 
ammoweight[2] = 3 
price[2] = 2
!и так далее...
Spoiler
my_ship = 2
my_ammo = 1
total_hulldamage = sh_guns[my_ship] * hulldamage[my_ammo]
total_saildamage = sh_guns[my_ship] * saildamage[my_ammo]
total_crewdamage = sh_guns[my_ship] * crewdamage[my_ammo]

Локации shipsи ammoследует прочитать до первого использования. Например, на стартовой локации

Spoiler
gs 'ships' 
gs 'ammo'

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

Spoiler
!Локация ships
$sh_name['Name1'] = 'Имя1' 
$sh_desc['Name1'] = 'Описание1' 
sh_hull['Name1'] = 200 
sh_speed['Name1'] = 14 
sh_cargo['Name1'] = 200 
sh_crew['Name1'] = 20 
sh_guns['Name1'] = 8 
sh_gunsmaxcal['Name1'] = 12 
sh_price['Name1'] = 2500

$sh_name['Баркас'] = 'Баркас ' 
$sh_desc['Баркас'] = 'Большая лодка, на которую устанавливают малые пушки. Широко применяется по всему миру для пиратских или контрабандных вылазок. ' 
sh_hull['Баркас'] = 200 
sh_speed['Баркас'] = 14 
sh_cargo['Баркас'] = 200 
sh_crew['Баркас'] = 20 
sh_guns['Баркас'] = 8 
sh_gunsmaxcal['Баркас'] = 12 
sh_price['Баркас'] = 2500
!и так далее...

!Локация ammo
$ammo_name['cannonball'] = 'Ядро' 
hulldamage['cannonball'] = 10 
saildamage['cannonball'] = 5 
crewdamage['cannonball'] = 0.25 
ammoweight['cannonball'] = 3 
price['cannonball'] = 2

$ammo_name['knuppel'] = 'книппель' 
hulldamage['knuppel'] = 5 
saildamage['knuppel'] = 10
crewdamage['knuppel'] = 0.25 
ammoweight['knuppel'] = 3 
price['knuppel'] = 2
!и так далее...

!Пример использования
total_hulldamage = sh_guns['Баркас'] * hulldamage['knuppel']
total_saildamage = sh_guns['Баркас'] * saildamage['knuppel']
total_crewdamage = sh_guns['Баркас'] * crewdamage['knuppel']

Вета:

Друзья, нужно решить непростую для меня задачку.
Есть дом с 30-35 комнатами, которые описаны заранее и рандомно генерятся в разных частях дома в начале игры. Комнаты все немного разные. В этих комнатах опять же в начале игры рандомно генерятся квестовые и не очень предметы. Например, у нас 8 квестовых предметов и 15 обычных, которые обязательно должны присутствовать.
Вопрос: как это это скодить, а то мне лавры монструма покоя не дают :)

предметы
там где регенятся комнаты
ложка =rand (1,30)
вилка =rand (1,30)
и так далее

в комнате 1
if ложка=1: act “взятьложку”
if вилка=1: act “взятьвилку”
и так далее
в комнате 2
if ложка=2: act “взятьложку”
if вилка=2: act “взятьвилку”
и т.д
и копипастой рассовать это во все комнаты
по идее можно массивами, но я в них не шарю
минус что в 1 комнате может оказаться 2 и больше предмета

Здесь проблема с формулировкой вопроса. Непонятно, что именно нужно сделать. Надо ли написать код генерации комнат, а затем генерацию предметов? Или комнаты уже есть? Если их нет, то как переходить между 35 комнатами (план дома, что ли самому придумать)?

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

evp:

Здесь проблема с формулировкой вопроса. Непонятно, что именно нужно сделать. Надо ли написать код генерации комнат, а затем генерацию предметов? Или комнаты уже есть? Если их нет, то как переходить между 35 комнатами (план дома, что ли самому придумать)?

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

Суть такая - есть дом, где свойства коридоров генерируется рандомно (это я сделала, тут проще). В одном коридоре может быть рандомно от 1 до 3 комнат. Комната генерится, когда игрок в нее заходит и до конца игры, естественно, остается в таком состоянии. Игрок появляется опять же рандомно в одной из этих комнат. Все комнаты прописаны, просто они появляются рандомно в разных коридорах, где странствует игрок. В комнатах есть объекты - шкафы, секретеры, столы, кровати и т.п… (это в описаниях комнат). Внутри этих объектов опять же генерятся рандомно предметы. Там может как не быть совсем предметов, так быть предмет. Обязательное условие, чтобы в комнатах рандомно сгенерировались 8 квестовых предметов и 15 стандартных.

Монструм - вот http://www.playground.ru/games/monstrum/, в принципе это не сильно важно.

evp:

Если их нет, то как переходить между 35 комнатами (план дома, что ли самому придумать)

та они пустые случайные комнаты, вышел в дверь - пришёл в случайно сгенерированную комнату, рандомны её мебелировка и назначение, например из туалета в котором стоит плятяной шкаф, тумбочка с тремя выдвижными ящиками и сейф в туалет, где под матрасом код от сейфа из предыдущего туалета, но когда и в какой комнате он тебе встретится снова скажет рандом на 35 случайных чисел, дверь в комнате одна - выход = переход, и блуждаешь по комнатам в поисках сначала собрать код от сейфа, потом найти сейф, там взять ключ и идти искать выход, короче бесполезная генерация кода, типа чтоб было, там всего то локации три на всю игру выйдет

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

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

!Локация Коридор 1
gs 'door', 0
gs 'door', 1
gs 'door', 2

В игре это должно выглядеть как список из трех действий: [] Войти в дверь № 0
[
] Войти в дверь № 1
[*] Войти в дверь № 2

Реализация
Чтоб программа так работала сделаем следующее.

Создадим локацию door, в которой запишем:

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

Как видно, этот код, формирует действие для открытия двери под номером, переданным в качестве аргумента. Причем проверяется значение элемента некоего массива $door под этим же номером на соответствие строке ‘NULL’. [*] Если это так, то считается, что дверь еще не открывалась. Это влечет за собой выбор случайного элемента из другого массива $destination, значение которого присваивается нашему элементу массива $door. При этом выбранный элемент $destination удаляется для предотвращения его использования в будущем.

[*] Если это не так, значит дверь уже открывалась, следовательно наш элемент массива door уже содержит, забегая вперед скажу, строку с командой для перехода в нужную комнату.
При выборе этого действия выполняется строка кода, содержащаяся в элементе массива $door.

Теперь нам надо заполнить эти массивы. Ну… это я так рассказываю с конца, а в самой игре их надо заполнить еще при старте. Я не знаю как называются локации с комнатами, поэтому назову их без затей room0…room39. Вы уже сами легко адаптируете код под ваши названия. Итак:[*] массив $destination

$destination[] = "gt 'room0'"
$destination[] = "gt 'room1'"
!...
$destination[] = "gt 'room39'"

[*] массив $door

$door[] = "NULL"
$door[] = "NULL"
!...еще 37 раз
$door[] = "NULL"

Некрасиво? Заполним в цикле оба массива:

n = 0
:next_destination
	$destination[] = "gt 'room<<n>>'"
	$door[] = "NULL"
	n += 1
if n < 40: jump 'next_destination'

По мере открытия дверей, содержимое массива $destination будет постепенно и случайным образом “перетекать” в массив $door, а сам массив $destination соответственно будет “худеть”. Так будет происходить до тех пор, пока все элементы $door не изменят своего значения с ‘NULL’ на строки с кодом перехода в случайные комнаты. То есть, пока не будут открыты все двери. Сам массив $destination при открытии последней двери будет уничтожен.

Disclaimer:

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

evp,, спасибо за помощь с массивами!
Что делает код dynamic $door[x]?

evp, спасибо. я очень плохо дружу с массивами, поэтому буду в ближайшее время пробовать разбираться в написанном :)
“В игре это должно выглядеть как список из трех действий:
Войти в дверь № 0
Войти в дверь № 1
Войти в дверь № 2”

А не может выглядеть, например:
- войти в западную дверь
- войти в восточную дверь
?

Все можно. Я же сказал, что код можно легко адаптировать. Например, так:

gs 'door', 0, 'западную'
gs 'door', 1, 'северную'
gs 'door', 2, 'восточную'
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
	dynamic $door[x]
end

zeek17, в переменной $door[x] хранится текст. Скажем, такой: gt ‘room1’. Оператор dynamic предполагает, что это не просто текст, а программный код. И, соответственно, его выполняет. В данном случае выполнение оператора dynamic $door[x] приведет к переходу на локацию room1.

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

Log in or Register to post comments.