Nazgool 250 Опубликовано 7 Сентября 2011 Artos Мои результаты в тесте (пост #320 стр.16 "Справочника") говорят об обратном. Concat оказался быстрее. Не на много, но факт. Поделиться этим сообщением Ссылка на сообщение
Nazgool 250 Опубликовано 12 Сентября 2011 (изменено) Artos По первому вопросу боюсь что без перебора не получиться. В принципе есть идея чтобы не перебирать. Но это когда буду дома. По второму вопросу могу пока предложить string.format hex = string.format('%x', 65535) dec = string.format('%d', '0x'..hex) У меня есть доморощенная функция преобразования DЕС/НЕХ, но я сейчас с тела. Вечером сравню скорости и сообщу. Метод 'string.format('%d', '0x'..hex)' - не применим для игры, т.к. ожидается только численное значение и стринг не приемлем (=> фатал еррор) --/ Artos Изменено 12 Сентября 2011 пользователем Artos Поделиться этим сообщением Ссылка на сообщение
Nazgool 250 Опубликовано 12 Сентября 2011 (изменено) ....т.к. ожидается только численное значение и стринг не приемлем (=> фатал еррор) Я поленился на теле набирать, но ведь tonumber ещё не отменяли :-) dec = string.format('%d', tonumber('0x'..hex)) Или Сталкер и этого не понимает? К сожалению ... Метод 'tonumber' ожидает только десятичное представление числа символами строки. Любой не 'числовой' символ ('x') - воспринимается как буква и => 'nil'. --/ Artos P.S. Подзабыли про параметр '16' для метода ... :-) Изменено 12 Сентября 2011 пользователем Artos Поделиться этим сообщением Ссылка на сообщение
Nazgool 250 Опубликовано 12 Сентября 2011 (изменено) Можно без '0x' (на всякий случай уточню) в чистом lua hex = string.format('%x', 65535) dec = tonumber(hex,16) Спасибо. Проверил: в игре такой вариант работает. --/ Artos Изменено 12 Сентября 2011 пользователем Artos Поделиться этим сообщением Ссылка на сообщение
Nazgool 250 Опубликовано 12 Сентября 2011 По поводу определения типа таблиц. Набросок без итераторов. Проверку на пустую таблицу и скорость не делал. function GetTabStatus(tab) if #tab ~= 0 and not next(tab, #tab) then return 'index' -- индексирудмый массив else return 'hash' -- всё подряд end end Поделиться этим сообщением Ссылка на сообщение
Nazgool 250 Опубликовано 12 Сентября 2011 (изменено) Полагаю что это уже мелочи, учитывая сказанное мною слово "набросок". Тем не менее ты прав в плане сравнения с нулем. Проверку с nехt делать всё равно прийдется. Например если есть и индексы от 1 до ... и не натуральные индексы. Изменено 12 Сентября 2011 пользователем Gun12 Поделиться этим сообщением Ссылка на сообщение
Nazgool 250 Опубликовано 12 Сентября 2011 После if-а #t определит наличие/отсутствие ключей, начинающихся с 1 и до последнего целочисленного поступательно нарастающего. Если есть такие, то проверяем, есть ли ещё какие-либо записи (nехt). Если есть - значит хэш, если нет, то индексный массив. Прогоните код в SсiТЕ. Не пойму, чего вы хотите от iраirs? Всё происходит так как и положено. Какому-то индексу присвоили значение nil. Сборщик мусора удалил это поле. Осталось дырка в индексах. Вот он и тормознул на этом поле. Совершенно правильно работает. Поделиться этим сообщением Ссылка на сообщение
Nazgool 250 Опубликовано 12 Сентября 2011 Может я не так понял. Может вы имеете в виду таблицы с целочисленными индексами, но произвольными? Но ведь в условии были даны варианты таблиц именно индексируемые с 1 и по порядку.Все другие варианты рассматриваются как хэш-ы. С ними нельзя работать ни оператором #, ни table.concat. Также в условии стояла задача узнать тип таблицы. Я предложил вариант не только без пайрсов, но и без for i=1,#t. Условия выполнены. Что не так? Не пойму. Поделиться этим сообщением Ссылка на сообщение
Nazgool 250 Опубликовано 13 Сентября 2011 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а смотрю, есть ли за этим последним элементом списка ещё поля, характерные для хэша? Если нет (nil), то фактическая длина таблицы равна количеству полей, что означает одно - таблица является списком. Ну а если есть ещё поля, то это смешанная таблица, а по сути НЕ список. Добавлено через 48 мин.: В варианте с заниливанием внутри таблицы ([3]=nil) допустил неточность. Читать 'заниливанием извне', например t[3] = nil Поделиться этим сообщением Ссылка на сообщение
Nazgool 250 Опубликовано 13 Сентября 2011 (изменено) Иначе, как можно утверждать, что после последнего элемента массива идут элементы с хешем? А вдруг они в общей последовательности идут впереди? ...Однако, при переборе ассоциативного массива в общем случае нельзя делать допущения о порядке элементов. Изменено 13 Сентября 2011 пользователем Artos Поделиться этим сообщением Ссылка на сообщение
Nazgool 250 Опубликовано 14 Сентября 2011 Где я такое сказал?Как упомянул Аrtоs, некоторые заходят через двери - значит гость. А мне нравиться лазить через форточку - значит вор. Получай по чём попало. Я принял твои слова именно как совет ходить всё-таки через двери. Artos, Но ведь это только говорит об упорядоченности ключей. А что насчёт значений? Ведь в качестве значений может быть что угодно: числа, строки, таблицы, пользовательские объекты. Хоть и не ко мне обращался, но всё же каким-то боком касается. Цитата : Вопрос-1: Как оптимально определить тип таблицы 'список' ... и не полный перебор списка на поиск 'дыр' в индексах... Т.е. ...определение именно списка, а не иного типа массива. Где в условиях задачи указана необходимось проверки на тип значений таблицы? Необходимо было выяснить тип самой таблицы. Иначе я сразу бы сказал что без перебора никак. Поделиться этим сообщением Ссылка на сообщение
Nazgool 250 Опубликовано 14 Сентября 2011 (изменено) Поздно заметил, но всё же отвечу. Что же в итоге?...проверка: имеются элементы 'списка', 1-й индекс начинается с 1 и за 'списком' отсутствует хеш-элементКонечно ДА. Такой проверки достаточно. Именно это я пытался доказать всё это время. Изменено 14 Сентября 2011 пользователем Gun12 Поделиться этим сообщением Ссылка на сообщение
Nazgool 250 Опубликовано 14 Сентября 2011 (изменено) 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, и сохранение этой таблицы локально вроде не очень то нужно, но будем учиться делать правильно. Ну и в конце концов уменьши частоту апдейтов (если не помешает задуманному) Изменено 14 Сентября 2011 пользователем Gun12 Поделиться этим сообщением Ссылка на сообщение
Nazgool 250 Опубликовано 14 Сентября 2011 Artos Да не стал я так уж лезть в оптимизации. Хотел и Actor-a вынести, да плюнул. За это стоит только зацепиться и ... :-) Поделиться этим сообщением Ссылка на сообщение
Nazgool 250 Опубликовано 15 Сентября 2011 (изменено) 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 Изменено 15 Сентября 2011 пользователем Artos Поделиться этим сообщением Ссылка на сообщение
Nazgool 250 Опубликовано 16 Сентября 2011 (изменено) *Shoker*, panzyuza То, что вы спорите и "бьетесь", отстаивая своё мнение хорошо конечно. Сам любитель "подраться". Но в этом бою вы находитесь заведомо в проигрышной ситуации. Ваш оппонент обладает багажом разнообразных приемов и опытом их применения. Вам есть чем ответить? Может какой-нибудь туз в рукаве завалялся? Неизвестный приём? Не думаю. Так что нужно выбрать, либо готовиться к бою изучая приемы соперника, находить свои, либо броситься в драку и получить по всей программе. Изменено 16 Сентября 2011 пользователем Gun12 Поделиться этим сообщением Ссылка на сообщение
Nazgool 250 Опубликовано 16 Сентября 2011 (изменено) panzyuza Мне тоже это интересно. В логике встречается ещё не один подобный параметр, на который я не смог найти описания. Когда-то написал скрипт, разбирающий все секции логики на всевозможные параметры, которые могут использоваться в конкретной схеме. Писал на скорую руку, поэтому результат несколько сумбурный. Много мусора, но мне на тот момент было достаточно и в таком виде. Даже начал "причёсывать" и... бросил. Может кому-нибудь будет интересно и полезно? http://ifolder.ru/25789460 Изменено 16 Сентября 2011 пользователем Gun12 Поделиться этим сообщением Ссылка на сообщение
Nazgool 250 Опубликовано 16 Сентября 2011 panzyuza А ты уверен что все сравнения с math.random проходят? Поделиться этим сообщением Ссылка на сообщение
Nazgool 250 Опубликовано 16 Сентября 2011 (изменено) panzyuza Ну раз ты пока ещё не разобрался с random, то убери все сравнения с силой и жизнью. И измени : if posit:distance_to(db.actor:position())<math.random(1,40) then -- На if posit:distance_to(db.actor:position())<40 Изменено 16 Сентября 2011 пользователем Gun12 Поделиться этим сообщением Ссылка на сообщение
Nazgool 250 Опубликовано 16 Сентября 2011 (изменено) panzyuza Ну тогда уж проследи за тем, чтобы бюрер не был дохлее чем 30 (self.object.health>=30) Про monster_berserk уже и не помню. Давно Сталкером не занимался, бывшие знания улетучиваются. Изменено 16 Сентября 2011 пользователем Gun12 Поделиться этим сообщением Ссылка на сообщение