Перейти к контенту

Скриптование


Svoboда

Рекомендуемые сообщения

Artos

Мои результаты в тесте (пост #320 стр.16 "Справочника") говорят об обратном. Concat оказался быстрее. Не на много, но факт.

Поделиться этим сообщением


Ссылка на сообщение

Artos

По первому вопросу боюсь что без перебора не получиться.

В принципе есть идея чтобы не перебирать. Но это когда буду дома.

По второму вопросу могу пока предложить string.format

hex = string.format('%x', 65535)
dec = string.format('%d', '0x'..hex)

У меня есть доморощенная функция преобразования DЕС/НЕХ, но я сейчас с тела. Вечером сравню скорости и сообщу.

 

Метод 'string.format('%d', '0x'..hex)' - не применим для игры, т.к. ожидается только численное значение и стринг не приемлем (=> фатал еррор)

--/ Artos

Изменено пользователем Artos

Поделиться этим сообщением


Ссылка на сообщение
....т.к. ожидается только численное значение и стринг не приемлем (=> фатал еррор)

Я поленился на теле набирать, но ведь tonumber ещё не отменяли :-)

dec = string.format('%d', tonumber('0x'..hex))

Или Сталкер и этого не понимает?

К сожалению ... Метод 'tonumber' ожидает только десятичное представление числа символами строки.

Любой не 'числовой' символ ('x') - воспринимается как буква и => 'nil'.

--/ Artos

P.S. Подзабыли про параметр '16' для метода ... :-)

Изменено пользователем Artos

Поделиться этим сообщением


Ссылка на сообщение

Можно без '0x' (на всякий случай уточню) в чистом lua

hex = string.format('%x', 65535)
dec = tonumber(hex,16)

Спасибо. Проверил: в игре такой вариант работает.

--/ Artos

Изменено пользователем Artos

Поделиться этим сообщением


Ссылка на сообщение

По поводу определения типа таблиц.

Набросок без итераторов. Проверку на пустую таблицу и скорость не делал.

function GetTabStatus(tab)
    if #tab ~= 0 and not  next(tab, #tab) then
        return 'index' -- индексирудмый массив
    else
        return 'hash' -- всё подряд
    end
end

Поделиться этим сообщением


Ссылка на сообщение

Полагаю что это уже мелочи, учитывая сказанное мною слово "набросок".

Тем не менее ты прав в плане сравнения с нулем. Проверку с nехt делать всё равно прийдется. Например если есть и индексы от 1 до ... и не натуральные индексы.

Изменено пользователем Gun12

Поделиться этим сообщением


Ссылка на сообщение

После if-а #t определит наличие/отсутствие ключей, начинающихся с 1 и до последнего целочисленного поступательно нарастающего.

Если есть такие, то проверяем, есть ли ещё какие-либо записи (nехt). Если есть - значит хэш, если нет, то индексный массив.

Прогоните код в SсiТЕ.

Не пойму, чего вы хотите от iраirs?

Всё происходит так как и положено.

Какому-то индексу присвоили значение nil. Сборщик мусора удалил это поле. Осталось дырка в индексах. Вот он и тормознул на этом поле. Совершенно правильно работает.

Поделиться этим сообщением


Ссылка на сообщение

Может я не так понял. Может вы имеете в виду таблицы с целочисленными индексами, но произвольными? Но ведь в условии были даны варианты таблиц именно индексируемые с 1 и по порядку.Все другие варианты рассматриваются как хэш-ы. С ними нельзя работать ни оператором #, ни table.concat. Также в условии стояла задача узнать тип таблицы.

Я предложил вариант не только без пайрсов, но и без for i=1,#t.

Условия выполнены. Что не так? Не пойму.

Поделиться этим сообщением


Ссылка на сообщение

Artos

 

Что-то мы говорим на разных языках.

Попробую ещё раз.

Вопрос-1: Как оптимально определить тип таблицы 'список' (list), т.е. типа: {"a","b","c","d"} или {1,5,2,4,3}?

 

По типу построения между этими таблицами нет никакой разницы. На самом деле они же выглядят так :

{[1]='a', [2]='b', [3]='c', [4]='d'}
и
{[1]=1, [2]=5, [3]=2, [4]=4, [5]=3}

Т.е. оператор # определит ВСЕ! поля этих таблиц.

...определение именно списка, а не иного типа массива.

Если добавить в любой из списков поле, не соответствующее продолжению "списка", например {[1]='a', [2]='b', [3]='c', [4]='d', [7]='e'}, либо 'занилить' значение, после чего поле удалиться из списка {[1]='a', [2]='b', [3]=nil, [4]='d'}, то список перестанет быть таковым и станет хэшем на общих основаниях.

Теперь оператор # определит в первом случае из 6-ти фактических полей только 5 (от индекса 1 до индекса 5). Во втором случае только 2 (т.к. поле с индексом 3 исчезло, и следующий индекс после 2 будет индекс 4), вместо фактических 3-х.

!!! Для того, чтобы не нарушать строение таблицы как списка (который работает быстрее чем любой другой тип таблиц) нужно пользоваться специально созданными для этого функциями table.insert и table.remove, а не заниливанием и непонятно каким добавлением.

...и не полный перебор списка на поиск 'дыр' в индексах

Теперь о 'дырах' и собственно моем варианте без перебора.

Имеется 3 типа таблиц :

t1 = {a='p', k=6, [12]='s'} 
t2 = {'a', 'b', k=6}
t3 = {'a', 8, 'c'}

Хотя в таблице t2 и есть элеметы списка, но и она, и таблица t1 не являются списками. Это комбинированые хэш-таблицы.

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

Вот я и пошел таким путем.

if #tаb~=0

Определяю, есть ли в таблице элементы списка (индексов от 1 и до упора).

Если нет, то это уже не список. Ответ - хэш.

Если есть такие элементы, то последний из них по любому найдется.

И теперь проверяя nехt(tаb,#tаB) смотрю, есть ли за этим последним элементом списка ещё поля, характерные для хэша?

Если нет (nil), то фактическая длина таблицы равна количеству полей, что означает одно - таблица является списком.

Ну а если есть ещё поля, то это смешанная таблица, а по сути НЕ список.

 

Добавлено через 48 мин.:

В варианте с заниливанием внутри таблицы ([3]=nil) допустил неточность. Читать 'заниливанием извне', например t[3] = nil

Поделиться этим сообщением


Ссылка на сообщение
Иначе, как можно утверждать, что после последнего элемента массива идут элементы с хешем? А вдруг они в общей последовательности идут впереди? ...Однако, при переборе ассоциативного массива в общем случае нельзя делать допущения о порядке элементов.
Изменено пользователем Artos

Поделиться этим сообщением


Ссылка на сообщение
Где я такое сказал?
Как упомянул Аrtоs, некоторые заходят через двери - значит гость. А мне нравиться лазить через форточку - значит вор. Получай по чём попало.

Я принял твои слова именно как совет ходить всё-таки через двери.

Artos,

Но ведь это только говорит об упорядоченности ключей. А что насчёт значений? Ведь в качестве значений может быть что угодно: числа, строки, таблицы, пользовательские объекты.

Хоть и не ко мне обращался, но всё же каким-то боком касается. Цитата :

Вопрос-1: Как оптимально определить тип таблицы 'список' ... и не полный перебор списка на поиск 'дыр' в индексах... Т.е. ...определение именно списка, а не иного типа массива.

Где в условиях задачи указана необходимось проверки на тип значений таблицы? Необходимо было выяснить тип самой таблицы. Иначе я сразу бы сказал что без перебора никак.

Поделиться этим сообщением


Ссылка на сообщение

Поздно заметил, но всё же отвечу.

Что же в итоге?...проверка: имеются элементы 'списка', 1-й индекс начинается с 1 и за 'списком' отсутствует хеш-элемент
Конечно ДА. Такой проверки достаточно. Именно это я пытался доказать всё это время. Изменено пользователем Gun12

Поделиться этим сообщением


Ссылка на сообщение

panzyuza

Вынеси поиск имени локации в НЕТ-спавн. Нет смысла гонять его при каждом апдейте. Достаточно определить один раз при загрузке.

CurrentLevel = level.name()

Соответственно измени функцию :

function level_spec_ops()
    if db.actor:dont_has_info("my2") and CurrentLevel  == "zaton" then
        avs_info.zaton_spec_ops()
    end
end

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

Если же она, по задумке, будет "висеть" у тебя достаточно долго, то первой проверкой ставь CurrentLevel == "zaton".

(Ну не могу не заставить себя "украсть" какую-то миллисекундочку :-))

Ну и измени оставшуюся функцию :

function zaton_spec_ops()
    local actor = db.actor
    if actor:has_info("zat_bandit_vs_dolg") then
        avs_spawn_add.spawn_dolg_bandit_scene()
        actor:give_info_portion("my2")
    end
end

Хотя в твоём варианте было всего два обращения к глобальным данным db.actor, и сохранение этой таблицы локально вроде не очень то нужно, но будем учиться делать правильно.

Ну и в конце концов уменьши частоту апдейтов (если не помешает задуманному)

Изменено пользователем Gun12

Поделиться этим сообщением


Ссылка на сообщение

Artos

Да не стал я так уж лезть в оптимизации. Хотел и Actor-a вынести, да плюнул.

За это стоит только зацепиться и ... :-)

Поделиться этим сообщением


Ссылка на сообщение

Artos

Вот тут у тебя лишняя проверка and iFirstIdx == 1 :

 local iCnt = #tTbl --/ длина индексированной части таблицы
local bList = iCnt > 0 and iFirstIdx == 1 and not next(tTbl,iCnt)

Почему?

Про вычислении длины таблицы local iCnt = #tTbl на самом деле мы прицеливается сразу в 2-х зайцев.

Переменная iCnt может иметь (как бы логически) два значения (первый заяц) :

0 - в таблице не найдены поля списка.

не 0 - в таблице найдено поле (последовательность полей) списка.

Второй заяц :

Если 0, то в таблице нет поля с индексом 1

Если не 0, то поле (поля) найдены, значит в этих полях не может не быть поля с индексом 1.

 

В выражении bList = iCnt > 0 производим выстрел по этим зайцам.

 

Спасибо! Ты прав. Просто вначале подстраховался, а потом пересмотрев кучу вариаций с различными структурами таблиц и, удостоверивщись в обязательном наличии 1-го индекса для 'списков', забыл убрать подстраховку. Подправил. Хотя ... в таких функциях, которые дают данные для сэйвов - необременительные перестраховки порой не помешали бы.

--/ Artos

Изменено пользователем Artos

Поделиться этим сообщением


Ссылка на сообщение

*Shoker*, panzyuza

То, что вы спорите и "бьетесь", отстаивая своё мнение хорошо конечно. Сам любитель "подраться".

Но в этом бою вы находитесь заведомо в проигрышной ситуации.

Ваш оппонент обладает багажом разнообразных приемов и опытом их применения.

Вам есть чем ответить? Может какой-нибудь туз в рукаве завалялся?

Неизвестный приём?

Не думаю.

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

Изменено пользователем Gun12

Поделиться этим сообщением


Ссылка на сообщение

panzyuza

Мне тоже это интересно. В логике встречается ещё не один подобный параметр, на который я не смог найти описания.

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

Писал на скорую руку, поэтому результат несколько сумбурный. Много мусора, но мне на тот момент было достаточно и в таком виде.

Даже начал "причёсывать" и... бросил.

Может кому-нибудь будет интересно и полезно?

http://ifolder.ru/25789460

Изменено пользователем Gun12

Поделиться этим сообщением


Ссылка на сообщение

panzyuza

Ну раз ты пока ещё не разобрался с random, то убери все сравнения с силой и жизнью. И измени :

if posit:distance_to(db.actor:position())<math.random(1,40) then
-- На
if posit:distance_to(db.actor:position())<40

Изменено пользователем Gun12

Поделиться этим сообщением


Ссылка на сообщение

panzyuza

Ну тогда уж проследи за тем, чтобы бюрер не был дохлее чем 30 (self.object.health>=30)

Про monster_berserk уже и не помню. Давно Сталкером не занимался, бывшие знания улетучиваются.

Изменено пользователем Gun12

Поделиться этим сообщением


Ссылка на сообщение
  • Недавно просматривали   0 пользователей

    • Ни один зарегистрированный пользователь не просматривает эту страницу.
×
×
  • Создать...