RU 📌 Pinned

Как сделать?

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

evp,
Код верный, я и не спорил. Но есть принципиальная разница. Если после исчерпания лимита разговоров хотя бы раз в сутки жать на действие Поговорить, (time - lasttime) будет сбрасываться и снова равно 0. То есть в теории новый разговор может и вовсе никогда не начаться. Я об этом и писал. В моем варианте новые разговоры будут ровно через сутки после исчерпания лимита в любом случае.

Как поставлена задача, так я и написал. Напомню условия:

aplesin:

как сделать так чтоб если я например 5й раз нажимаю действие “поговорить” второй перс сказал чтоб я отвалил

Строго говоря, проверку на время я от себя додумал, ибо об этом не просили. С моей точки зрения диалог “Привет - Отвали” - тоже является разговором и с формальной точки зрения я сделал все правильно. То, как вы себе представляете ситуацию - исключительно ваше частное мнение. Если вы хотите ответить на вопрос, вы не должны заниматься гаданием в попытке угадать чьи-то желания. Какой вопрос - такой ответ.

Если бы я позволял себе додумывать, то дал бы вообще такой ответ:

if  время - время_последнего_разговора >= 24*60: счетчик_разговоров = 0
if счетчик_разговоров < 5:
    act "Поговорить": 
        счетчик_разговоров += 1
        время_последнего_разговора = время 
        !разговор
    end
end

evp,

evp:

То есть, вы утверждаете, что у меня логическая ошибка? Докажите.

aplesin, вас это тоже касается.

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

А вот этот код,кстати более понятен и логичен лично для меня!

evp:

if время - время_последнего_разговора >= 24*60: счетчик_разговоров = 0
if счетчик_разговоров < 5:
act “Поговорить”:
счетчик_разговоров += 1
время_последнего_разговора = время
!разговор
end
end

aplesin:

нажимал действие “поговорить” и ничего не происходило,а на пятый раз только начинался разговор

Такого быть просто не может. Вы, вероятно, ошиблись при копировании. А скорее всего не поняли, что “!разговор” это всего лишь комментарий, вместо которого вы должны вставить свои команды диалога. Разумеется в чистом виде этот код ничего не выводит. Посмотрите на сообщение 4774. Все работает как ожидалось.

Второй вариант в корне отличается от того, что вы просили. (Правильно заданный вопрос - половина ответа.) После 5 разговоров, действие “Поговорить”, просто не будет показываться. Кстати, по уму надо делать не так, а вот так:

if  время - время_последнего_разговора >= 24*60: счетчик_разговоров = 0 
if счетчик_разговоров < 5: 
    act "Поговорить": 
        счетчик_разговоров += 1 
        время_последнего_разговора = время 
        !разговор
        if счетчик_разговоров > 4: delact $selact
    end 
end

Друзья, добрый день.
Делаю симулятор выживания. Вопрос про оператор GOSUB и аналоги. Прочитал ветку про него, а так же все из учебника и справочника на нашем форуме. Может что-то пропустил, но вопрос ключевой. По GOSUB я перехожу в некую заданную локацию. А какой для него (GOSUB) парный оператор возврата? В Бейсике и подобных языках, если я перехожу по GOSUB, то откуда бы я не перешел первый встретившийся оператор RETURN возвращает меня именно в то место, откуда я перешел.

Допустим у меня есть ЛОКАЦИЯ1, ЛОКАЦИЯ2 и СЛУЖЕБНАЯ_ЛОКАЦИЯ. При определенных условиях мне нужен переход в СЛУЖЕБНАЯ_ЛОКАЦИЯ, но такой, чтоб каким-либо оператором (про него я и спрашиваю) я из этой СЛУЖЕБНАЯ_ЛОКАЦИЯ возвращался обратно, независимо от того откуда пришел. Хоть с ЛОКАЦИЯ1 хоть ЛОКАЦИЯ2. Вобщем, существует ли в QSP связка операторов перехода между локациями** (а не внутри одной локации), подобная GOSUB\RETURN в Бейсике и подобных языках?

Aleks Versus Moderator 08.11.2016 14:21 (9 years ago)

Wol4ik,
надо понимать, как работают операторы. Очень туго с семантикой у QSP, нет чёткого словаря, поэтому можно легко запутаться.
GOTO - это переход на локацию. Т.е. плеер прыгает на указанную локацию, выполняет на ней весь код и всё.
GOSUB - типа вызов подпрограммы (как в бейсике). Любая локация может быть использована как подпрограмма. Когда заканчивается код вызванной подпрограммы, плеер переходит к следующей строке после gosub. Проверяется просто.

!#начало
a=1
*pl a
gosub 'счёт'
*pl a

!#счёт
a = a+1

Отличие gosub от goto не только в этом. При goto очищается окно основного описания и окно действий, тогда как по gosub просто происходит добавление туда и туда.

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

Aleks Versus, большое спасибо за ответ и пояснения. Попробую проэкспериментировать.

Помогите! Не могу понять сколько эндов надо добавить, насчитал что нужно 5 вроде, но сколько бы не добавлял, все равно выдает ошибку

Spoiler
IF энергия > 0:
	IF Ловкость < 4:
		ACT "Залезть на дерево":
		*PL "Высоко залезть не удалось, надо попробовать еще раз"
		*PL "Ловкость + 1, Сила + 1"
		Ловкость = Ловкость + 1
		Сила = Сила + 1
		Энергия = Энергия - 1
	ELSEIF Ловкость = 4 and Город_найд = 0:
		msg "Вдали виднеются какие-то строения, стоит разведать"
		Город_найд = 1
	!КОНЕЦ РАЗВЕДКИ
	ELSE:
		!ОБЫЧНАЯ ТРЕНИРОВКА!
		ACT "Подтягиваться":
		*PL "Несколько подтягиваний на удобной нижней ветке"
		*PL "Сила + 1"
		Сила + 1
		Энергия - 1
		ACT "Лазить по дереву":
		*PL "карабкаться по дереву не так легко как кажется"
		*PL "Ловкость + 1"
		Ловкость + 1
		Энергия - 1
ELSEIF энергия = 0:
msg "Надо отдохнуть"
END
END
END
END
END
Aleks Versus Moderator 16.11.2016 14:06 (9 years ago)

Twinkie,
ты не там лепишь end’ы. Если понимаешь, зачем они нужны, то становится проще. end’ом закрывается многострочная форма оператора.

act 'действие':
   !операторы
end
if условие:
   ! операторы
elseif условие2:
   ! операторы 2
else
   ! операторы 3
end

Если действие лежит внутри условия, то и закрываться оно должно внутри условия:

if условие:
   act 'действие':
      !операторы
   end
elseif условие2:
   ! операторы 2
else
   ! операторы 3
end

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

Spoiler
IF энергия > 0: 
	IF Ловкость < 4: 
		ACT "Залезть на дерево": 
			*PL "Высоко залезть не удалось, надо попробовать еще раз" 
			*PL "Ловкость + 1, Сила + 1" 
			Ловкость = Ловкость + 1 
			Сила = Сила + 1 
			Энергия = Энергия - 1
		! здесь не закрыто действие	
		end
	ELSEIF Ловкость = 4 and Город_найд = 0: 
		msg "Вдали виднеются какие-то строения, стоит разведать" 
		Город_найд = 1 
		!КОНЕЦ РАЗВЕДКИ 
	! двоеточие после else не ставится
	ELSE
	!ОБЫЧНАЯ ТРЕНИРОВКА! 
		ACT "Подтягиваться": 
			*PL "Несколько подтягиваний на удобной нижней ветке" 
			*PL "Сила + 1" 
			Сила + 1 
			Энергия - 1
		! закрываем действие
		end
		ACT "Лазить по дереву": 
			*PL "карабкаться по дереву не так легко как кажется" 
			*PL "Ловкость + 1" 
			Ловкость + 1 
			Энергия - 1
		! закрываем действие
		end
	! закрываем условие
	end
ELSEIF энергия = 0: 
	msg "Надо отдохнуть" 
END

А, ещё. Там где инкременты типа ловкость +1 надо писать либо ловкость+=1, либо ловкость=ловкость+1

Aleks Versus:

ты не там лепишь end’ы

Ясно, спасибо. я неправильно понял уроки, что на сайте есть. там было:

Spoiler
IF Ключ = 0:
  'На полу вы видите небольшой ключ.'
  ACT 'Взять ключ':
    Ключ = 1
    ADDOBJ 'Ключ'
    PL 'Вы взяли ключ.'
    GOTO $CURLOC
 [b] END
END[/b]

Вот и подумал что энды надо лепить в конце.
А вот так можно писать?

Spoiler
if условие: 
   act 'действие': goto "куда-то"
elseif условие2:
   act 'действие': goto "туда-то"
end 
ИЛИ вот так например
if условие: 
   act 'действие': goto "куда-то"
      !операторы 
   end 
elseif условие_2: goto "туда-то"
   ! операторы 2 
end

Кстати, а почему после else нельзя двоеточие ставить это же тоже условие, только типа “если ничто другое не подходит”?
Двоеточие ставится только если пишется конкретное условие, так выходит? у элсе же нет никаких прописанных условий

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

И еще вопрос, почему в учебнике по аэро qsp написано по вот так:

Spoiler
ACT 'Заглянуть в тумбочку':
' В тумбочке лежит <<заначка>> руб.'
CLA
IF заначка > 0:
ACT 'Взять денег':
a = input 'Сколько взять?'
IF a > заначка:
msg 'Первый закон подлости: нельзя взять из тумбочки больше денег, чем туда было положено!'
GT curloc
else
деньги = деньги + a
заначка = заначка - a
GT curloc
END
END
END
ACT 'Закрыть тумбочку':
GT curloc
END
END

Почему там энды в конце?

Фигня какая то получается. если добавить GT $CURLOC очищается все, включая основное окно и сообщение *PL “Высоко залезть не удалось, надо попробовать еще раз” естественно не выводится. если поставить XGT $CURLOC повторяется инфа из основного окна описания.
Вынести часть кода в отдельную локацию и поставить GS туда? не хотелось бы… или есть еще варианты?
GS не то. видимо только через GT делать, если других вариантов нет.

Edited at 16.11.2016 17:00 (9 years ago)
Aleks Versus Moderator 17.11.2016 07:21 (9 years ago)

Twinkie,
по последнему вопросу. Конечно же всё очищается. В справке так и написано: переход по goto очищает окно основного описания и список действий. Есть переход xgoto, который не очищает список действий и основное описание, но с ним, если ты плохо представляешь себе, порядок выполнения кода, у тебя тоже возникнут глюки: одни и те же надписи начнут выводиться дважды.

Twinkie:

А вот так можно писать?

в первом случае всё будет работать. Так можно. Во втором есть ошибки

act 'действие': goto "куда-то" 
      !операторы 
   end

плеер подумает, что ты написал однострочный act и отнесёт end к оператору условия. Это значит, что весь остальной код будет работать неправильно. Если путаешься в ендах для действий и условий, действия можно закрывать командой end act. Пример:

act 'поднять яблоко':
   яблоко+=1
   *pl 'Вы подняли яблоко'
end act

этот кусок:

elseif условие_2: goto "туда-то" 
   ! операторы 2 
end

то же самое. Плеер решит, что elseif однострочный оператор, а последний end обзовёт ошибкой.

Twinkie:

Кстати, а почему после else нельзя двоеточие ставить это же тоже условие, только типа “если ничто другое не подходит”?

такой синтаксис.

Aleks Versus:

в первом случае всё будет работать. Так можно. Во втором есть ошибки

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

Aleks Versus:

Если путаешься в ендах для действий и условий, действия можно закрывать командой end act. Пример:

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

Spoiler

1 локация

IF энергия > 0:
	!РАЗВЕДКА!
	IF Ловкость < 4:
		ACT "Залезть на дерево":
		$thisact = selact
		GT "Дерево"
		END
	ELSEIF Ловкость = 4 and Город_найд = 0:
		msg "Идея забраться повыше не была напрасной - с такой высоты удалось рассмотреть какие-то строения вдали"
		Город_найд = 1
	!КОНЕЦ РАЗВЕДКИ!
	ELSE
		!ОБЫЧНАЯ ТРЕНИРОВКА!
		ACT "Подтягиваться":
			$thisact = selact
			GT "Дерево"
		END
		ACT "Лазить по дереву":
			$thisact = selact
			GT "Дерево"
		END
	END
!Кончилась энергия
ELSEIF энергия = 0:
msg "Надо отдохнуть"
END

2 локация

IF опис_дерево = 0:
*PL "Одно из самых высоких деревьев в округе, и с довольно удобным расположением веток."
END

IF $thisact = "Залезть на дерево":
	*PL "Высоко залезть не удалось, надо попробовать еще раз."
	*PL "Ловкость + 1, Сила + 1"
	*PL "Сила: <<Сила>>, Ловкость: <<Ловкость>>"
	Ловкость = Ловкость + 1
	Сила = Сила + 1
	Энергия = Энергия - 1
END

IF $thisact = "Подтягиваться":
	*PL "Несколько подтягиваний на удобной нижней ветке."
	*PL "Сила + 1"
	*PL "Сила: <<Сила>>"
	Сила = Сила + 1
	Энергия = Энергия - 1
END

IF $thisact = "Лазить по дереву":
	*PL "Карабкаться по дереву не так легко как кажется."
	*PL "Ловкость + 1"
	*PL "Ловкость: <<Ловкость>>"
	Ловкость = Ловкость + 1
	Энергия = Энергия - 1
END

IF энергия > 0:
        ACT "Повторить":
	опис_дерево = 1	
	XGT $CURLOC
	END
END
ACT "Назад":
опис_дерево = 0	
GT "у дома"
END

Но возник вопрос, у меня образовалось 3 куска с абсолютно одинаковым кодом, отличаются только ACTы:

Spoiler
ACT "Залезть на дерево":
$thisact = selact
GT "Дерево"
END

ACT "Подтягиваться":
$thisact = selact
GT "Дерево"
END

ACT "Лазить по дереву":
$thisact = selact
GT "Дерево"
END

Возможно ли их как то объединить, упростить код? но что бы кнопки по прежднему было 3, однако переход то все равно один и тот же…

Edited at 17.11.2016 11:30 (9 years ago)
Aleks Versus Moderator 17.11.2016 14:40 (9 years ago)

Twinkie,
ну вообще-то это самая простая запись. Единственное, ты можешь сократить запись перехода:

ACT "Залезть на дерево": GT "Дерево", $selact
ACT "Подтягиваться": GT "Дерево", $selact
ACT "Лазить по дереву": GT "Дерево", $selact

! а на локации "Дерево"
$thisact = $args[0]

В $args[0] на локации будет то значение, которое ты прописал для команды перехода через запятую:

ACT “Залезть на дерево”: GT “Дерево”, $selact

Видишь да? после запятой стоит название выделенного действия, а значит на локации Дерево $args[0] будет возвращать именно это название. Если через запятую перечислить ещё какие-то значения, они соответственно на локацииДерево запишутся в args[1] arsg[2] … args[8].

Aleks Versus,
Эх, вот по массиву arsg я в справке вообще ни черта не понял, смотрел как на китайскую грамоту. и динамики не трогал пока.
С arsg у меня нет понимания, какие 9 параметров он хранит, как, и когда он это делает и т.д…. в общем, боюсь при использовании arsg я банально запутаюсь. за информацию спасибо, но уж лучше тогда оставлю как есть, а то потом на трезвую голову не разберусь.
P.S. Начинаю понимать суть анекдота:
Сын - пап, а почему Солнце
каждый день всходит на востоке, а заходит на Западе?
Отец - Солнце…
С - Да
П - Всходит на востоке…
С - Да
П - Заходит на западе…
СС - Да, папа
ПС - Каждый день?!
С - Да…
П - И давно так?
С - Ну, я не знаю… Всегда…
ПС - Знаешь что, Сынок? Работает - не трогай!!!

Edited at 17.11.2016 15:42 (9 years ago)

Log in or Register to post comments.