Рекурсивные функции
|
|
FatalBlade | Дата: Четверг, 02 Февраля 2012, 20:46:22 | Сообщение # 1 |
10 уровень
Группа: Проверенные
Сообщений: 1523
Награды: 0
Репутация: 439
Блокировки:
| Мне как то раз сказали что рекурсивные функции работают быстрее любых циклов для любых целей. Правда ли это? Может я и не правильно понял что значит рекурсия, но по моему вот это подходит под описание:
Code function CheckRange takes unit u, unit un returns real if IsUnitInRange( un, u, 2000.0 ) then if IsUnitInRange( un, u, 1500.0 ) then if IsUnitInRange( un, u, 1000.0 ) then return 1.0 endif return 0.8 endif return 0.6 else return 0.4 endif endfunction Code set y = CheckRange( un, u )
Это кофицент награды золота за крипов. Чем дальше убитый вражеский юнит от вашего юнита, тем меньше кофицент. Тут правда есть конкретные значения, 1000, 1500, 2000.
Теперь вот вам отрывок кода, который выполняет то же самое, только по другому:
Code set dx = GetWidgetX(un) - GetWidgetX(u) set dy = GetWidgetY(un) - GetWidgetY(u) set d = SquareRoot( dx * dx + dy * dy ) if d < 1000 then set y = 1.00 elseif d <= 1500 and d > 1000 then set y = 0.80 elseif d <= 2000 and d > 1500 then set y = 0.60 elseif d > 2000 then set y = 0.40 endif
И вот мой вопрос - что работает быстрее? Что из них лучше для производительности?
|
|
|
|
Dreii | Дата: Четверг, 02 Февраля 2012, 20:54:55 | Сообщение # 2 |
10 уровень
Группа: Проверенные
Сообщений: 4991
Награды: 0
Репутация: 603
Блокировки:
| FatalBlade, имхо отдельная ф-ия вставленная в код карты, и вызывающаяся только когда это нужно лучше.Но это мое ИМХО. Сейчас трукодеры ответят. Жди_) Добавлено (02 Февраль 2012, 20:54:55) --------------------------------------------- Бтв, Quote (FatalBlade) set d = SquareRoot( dx * dx + dy * dy ) if d < 1000 then set y = 1.00 elseif d <= 1500 and d > 1000 then set y = 0.80 elseif d <= 2000 and d > 1500 then set y = 0.60 elseif d > 2000 then set y = 0.40 endif
Code set d = dx * dx + dy * dy if d < 1000000 then set y = 1. elseif d <= 2250000 and d > 1000000 then set y = .80 elseif d <= 4000000 and d > 2250000 then set y = .60 elseif d > 4000000 then set y = .40 endif
|
|
|
|
Ajaccio | Дата: Четверг, 02 Февраля 2012, 21:39:30 | Сообщение # 3 |
7 уровень
Группа: Проверенные
Сообщений: 299
Награды: 1
Репутация: 239
Блокировки:
| Рекурсия - это когда функция вызывает сама себя. Вот пример на данную тему:
Code function CheckRange takes unit lpUnitOne, unit lpUnitTwo, real fStartRange returns real if (IsUnitInRange(lpUnitOne, lpUnitTwo, fStartRange) and fStartRange > 0.0) then return 1.0 / fStartRange + CheckRange(lpUnitOne, lpUnitTwo, fStartRange - 1.0) endif return 0.0 endfunction
Допустим мы вызываем её так:
Code call CheckRange(<ЮНИТ №1>, <ЮНИТ №2>, 2000.0)
Тогда на расстоянии > 2000 единиц функция вернет 0.0, а на расстоянии около 0 единиц вернет примерно 4.0. Если нужно получить значение между 0 и 1, то делим результат на 4. Вообще рекурсиями злоупотреблять не стоит, ибо игра может оборвать поток с такой функцией.
XOR EAX, EAX MOV EAX, 00H ;; NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.
|
|
|
|
FatalBlade | Дата: Четверг, 02 Февраля 2012, 22:39:57 | Сообщение # 4 |
10 уровень
Группа: Проверенные
Сообщений: 1523
Награды: 0
Репутация: 439
Блокировки:
| А вообще, как лучше проверять расстояние между юнитами для быстроты?
Code IsUnitInRange( un, u, 2000.0 ) или Code set dx = GetWidgetX(un) - GetWidgetX(u) set dy = GetWidgetY(un) - GetWidgetY(u) set d = SquareRoot( dx * dx + dy * dy ) if d < 1000 then set y = 1.00 elseif d <= 1500 and d > 1000 then set y = 0.80 elseif d <= 2000 and d > 1500 then set y = 0.60 elseif d > 2000 then set y = 0.40 endif
|
|
|
|
lawson | Дата: Четверг, 02 Февраля 2012, 22:42:06 | Сообщение # 5 |
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:
| Quote (FatalBlade) как лучше проверять расстояние между юнитами для быстроты? Рекурсивная функция в жассе может заменить только цикл, теперь скажи зачем тебе циклом проверять расстояние между юнитами?
Nic nie wiem bo mam chuj. редактирую посты! ВСЕ!
|
|
|
|
FatalBlade | Дата: Четверг, 02 Февраля 2012, 22:52:29 | Сообщение # 6 |
10 уровень
Группа: Проверенные
Сообщений: 1523
Награды: 0
Репутация: 439
Блокировки:
| Quote (lawson) Рекурсивная функция в жассе может заменить только цикл, теперь скажи зачем тебе циклом проверять расстояние между юнитами? Так это не цикл в данном случае. Видимо значит я ошибся насчёт того что это рекурсия. Не в этом суть. Что быстрее:
Code call IsUnitInRange( un, u, 2000.0 ) или Code set dx = GetWidgetX(un) - GetWidgetX(u) set dy = GetWidgetY(un) - GetWidgetY(u) set d = SquareRoot( dx * dx + dy * dy ) if d < 2000 then endif
|
|
|
|
SirNikolas | Дата: Пятница, 03 Февраля 2012, 13:51:10 | Сообщение # 7 |
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
| По просьбе.
|
|
|
|