Сейчас 16:18:26 Пятница, 29 ноября, 2024 год
[ x ] Главная ⇒ Форум ⇐ RSS Файлы Cтатьи Картинки В о й т и   или   з а р е г и с т р и р о в а т ь с я


[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Модератор форума: PUVer, SirNikolas, Ty3uK  
Рекурсивные функции
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
Блокировки:
По просьбе.

 

  • Страница 1 из 1
  • 1
Поиск:

Copyright © 2006 - 2024 Warcraft3FT.info При копировании материалов c сайта ставьте, пожалуйста, активную обратную ссылку на нас • Design by gReeB04ki ©
Хостинг от uCoz