Расчет числа однотипных предметов в инвентаре

Добавлен , опубликован
Алгоритмы, Наработки и Способности
Способ реализации:
Jass
Тип:
Алгоритм
Самая быстрая функция расчета числа однотипных предметов в шестислотном инвентаре.
работа через (GetItemTypeId(UnitItemInSlot(u, slot ))== typeId))
Ошибок нет, написано под перенасыщением мозга кровью для толстых алгоритмов дабы снизить затраты ресурсов машины.
Слабым не изучать
Возможен всплеск неконтролируемой агрессии.
function CountItemInInventory takes unit u, integer a returns integer
  if GetItemTypeId(UnitItemInSlot(u,0))==a then
    if GetItemTypeId(UnitItemInSlot(u,1))==a then
      if GetItemTypeId(UnitItemInSlot(u,2))==a then
        if GetItemTypeId(UnitItemInSlot(u,3))==a then
          if GetItemTypeId(UnitItemInSlot(u,4))==a then
            if GetItemTypeId(UnitItemInSlot(u,5))==a then
              return 6
            endif
            return 5
          elseif GetItemTypeId(UnitItemInSlot(u,5))==a then
            return 5
          endif
          return 4
        elseif GetItemTypeId(UnitItemInSlot(u,4))==a then
          if GetItemTypeId(UnitItemInSlot(u,5))==a then
            return 5
          endif
          return 4
        elseif GetItemTypeId(UnitItemInSlot(u,5))==a then
          return 4
        endif
        return 3
      elseif GetItemTypeId(UnitItemInSlot(u,3))==a then
        if GetItemTypeId(UnitItemInSlot(u,4))==a then
          if GetItemTypeId(UnitItemInSlot(u,5))==a then
            return 5
          endif
          return 4
        elseif GetItemTypeId(UnitItemInSlot(u,5))==a then
          return 4
        endif
        return 3
      elseif GetItemTypeId(UnitItemInSlot(u,4))==a then
        if GetItemTypeId(UnitItemInSlot(u,5))==a then
          return 4
        endif
        return 3
      elseif GetItemTypeId(UnitItemInSlot(u,5))==a then
        return 3
      endif
      return 2
    elseif GetItemTypeId(UnitItemInSlot(u,2))==a then
      if GetItemTypeId(UnitItemInSlot(u,3))==a then
        if GetItemTypeId(UnitItemInSlot(u,4))==a then
          if GetItemTypeId(UnitItemInSlot(u,5))==a then
            return 5
          endif
          return 4
        elseif GetItemTypeId(UnitItemInSlot(u,5))==a then
          return 4
        endif
        return 3
      elseif GetItemTypeId(UnitItemInSlot(u,4))==a then
        if GetItemTypeId(UnitItemInSlot(u,5))==a then
          return 4
        endif
        return 3
      elseif GetItemTypeId(UnitItemInSlot(u,5))==a then
        return 3
      endif
      return 2
    elseif GetItemTypeId(UnitItemInSlot(u,3))==a then
      if GetItemTypeId(UnitItemInSlot(u,4))==a then
        if GetItemTypeId(UnitItemInSlot(u,5))==a then
          return 4
        endif
        return 3
      elseif GetItemTypeId(UnitItemInSlot(u,5))==a then
        return 3
      endif
      return 2
    elseif GetItemTypeId(UnitItemInSlot(u,4))==a then
      if GetItemTypeId(UnitItemInSlot(u,5))==a then
        return 3
      endif
      return 2
    elseif GetItemTypeId(UnitItemInSlot(u,5))==a then
      return 2
    endif
    return 1
  elseif GetItemTypeId(UnitItemInSlot(u,1))==a then
    if GetItemTypeId(UnitItemInSlot(u,2))==a then
      if GetItemTypeId(UnitItemInSlot(u,3))==a then
        if GetItemTypeId(UnitItemInSlot(u,4))==a then
          if GetItemTypeId(UnitItemInSlot(u,5))==a then
            return 5
          endif
          return 4
        elseif GetItemTypeId(UnitItemInSlot(u,5))==a then
          return 4
        endif
        return 3
      elseif GetItemTypeId(UnitItemInSlot(u,4))==a then
        if GetItemTypeId(UnitItemInSlot(u,5))==a then
          return 4
        endif
        return 3
      elseif GetItemTypeId(UnitItemInSlot(u,5))==a then
        return 3
      endif
      return 2
    elseif GetItemTypeId(UnitItemInSlot(u,3))==a then
      if GetItemTypeId(UnitItemInSlot(u,4))==a then
        if GetItemTypeId(UnitItemInSlot(u,5))==a then
          return 4
        endif
        return 3
      elseif GetItemTypeId(UnitItemInSlot(u,5))==a then
        return 3
      endif
      return 2
    elseif GetItemTypeId(UnitItemInSlot(u,4))==a then
      if GetItemTypeId(UnitItemInSlot(u,5))==a then
        return 3
      endif
      return 2
    elseif GetItemTypeId(UnitItemInSlot(u,5))==a then
      return 2
    endif
    return 1
  elseif GetItemTypeId(UnitItemInSlot(u,2))==a then
    if GetItemTypeId(UnitItemInSlot(u,3))==a then
      if GetItemTypeId(UnitItemInSlot(u,4))==a then
        if GetItemTypeId(UnitItemInSlot(u,5))==a then
          return 4
        endif
        return 3
      elseif GetItemTypeId(UnitItemInSlot(u,5))==a then
        return 3
      endif
      return 2
    elseif GetItemTypeId(UnitItemInSlot(u,4))==a then
      if GetItemTypeId(UnitItemInSlot(u,5))==a then
        return 3
      endif
      return 2
    elseif GetItemTypeId(UnitItemInSlot(u,5))==a then
      return 2
    endif
    return 1
  elseif GetItemTypeId(UnitItemInSlot(u,3))==a then
    if GetItemTypeId(UnitItemInSlot(u,4))==a then
      if GetItemTypeId(UnitItemInSlot(u,5))==a then
        return 3
      endif
      return 2
    elseif GetItemTypeId(UnitItemInSlot(u,5))==a then
      return 2
    endif
    return 1
  elseif GetItemTypeId(UnitItemInSlot(u,4))==a then
    if GetItemTypeId(UnitItemInSlot(u,5))==a then
      return 2
    endif
    return 1
  elseif GetItemTypeId(UnitItemInSlot(u,5))==a then
    return 1
  endif
  return 0
endfunction
Результаты теста функции на скорость (Warcraft 1.24e):
Тела участников:
Function with loop
...
  local integer b = 0
  local integer c = 0
  loop
    if GetItemTypeId(UnitItemInSlot(u,b))==a then
      set c = c + 1
    endif
    set b = b + 1
    exitwhen b > 5
  endloop
  return c
...
Function without loop
...
  local integer c
  if GetItemTypeId(UnitItemInSlot(u,0))==a then
    set c = 1
  else
    set c = 0
  endif
  if GetItemTypeId(UnitItemInSlot(u,1))==a then
    set c = c + 1
  endif
  if GetItemTypeId(UnitItemInSlot(u,2))==a then
    set c = c + 1
  endif
  if GetItemTypeId(UnitItemInSlot(u,3))==a then
    set c = c + 1
  endif
  if GetItemTypeId(UnitItemInSlot(u,4))==a then
    set c = c + 1
  endif
  if GetItemTypeId(UnitItemInSlot(u,5))==a then
    set c = c + 1
  endif
  return c
...
my func
Выше код же
Таблица результатов
ФункцияМин. средняя скорость, секМакс. средняя скорость, секСоотношение
with loop 0.0000 64 0.0000 67 1
without loop 0.0000 56 0.0000 58 0.88
my func 0.0000 54 0.0000 57 0.85
Время, необходимое для записи результата - 0.0000 033
Тест выполнялся с тремя одинаковыми предметами в первых трех слотах, остальные слоты были пусты
тест-код

   integer LounchCount = 0

function testfunc takes nothing returns nothing
   local integer w
   local real o
   
   set LounchCount = LounchCount + 1
   
   if LounchCount < 20 then

     set w = StopWatchCreate()
       call CountItemInInventory0(gg_unit_Hblm_0000, 'rat6')
     set o = StopWatchMark(w)
     call StopWatchDestroy(w)
     
     call BJDebugMsg( "test_myfunc " + I2S(CountItemInInventory0(gg_unit_Hblm_0000, 'rat6')))

   elseif LounchCount > 19 and LounchCount < 40 then

     set w = StopWatchCreate()
       call CountItemInInventory1(gg_unit_Hblm_0000, 'rat6')
     set o = StopWatchMark(w)
     call StopWatchDestroy(w)
     
     call BJDebugMsg( "test_withloop " + I2S(CountItemInInventory1(gg_unit_Hblm_0000, 'rat6')))
     
   else
     
     set w = StopWatchCreate()
       call CountItemInInventory2(gg_unit_Hblm_0000, 'rat6')
     set o = StopWatchMark(w)
     call StopWatchDestroy(w)
     
     call BJDebugMsg( "test_withoutloop " + I2S(CountItemInInventory2(gg_unit_Hblm_0000, 'rat6')))
     
     if LounchCount > 59 then
       set LounchCount = 0
     endif
     
   endif
   
   call DisplayTimedTextToPlayer( Player(0), 0., 0., 45., R2SW(o,10,10))

   set w = StopWatchCreate()
   set o = StopWatchMark(w)
   call StopWatchDestroy(w)
   call DisplayTimedTextToPlayer( Player(0), 0., 0., 45., "difference " + R2SW(o,10,10))

endfunction

//===========================================================================
function InitTrig_batest2 takes nothing returns nothing
  local trigger t = CreateTrigger()
  call TriggerRegisterPlayerChatEvent(t,Player(0),"a",true)
  call TriggerAddAction(t,function testfunc)
  set t = null
  
  call DoNotSaveReplay()
  
endfunction
`
ОЖИДАНИЕ РЕКЛАМЫ...
3
17
12 лет назад
3
+1, полезно.
2
20
12 лет назад
2
как насчет 6 локалок под каждый слот вместо того чтобы каждый раз обращаться к инву?
0
15
12 лет назад
0
Дану, глупости! Вы уже совсем зацыклились над "оптимизацией"...
Сейчас 2012 год, время когда у 70% людей компы - Больше 2 ядер!
4 года назад, может и былобы полезно, но не сейчас!
Да и еще одно, Миллионые доли секунд, роли не играют!
2
15
11 лет назад
2
Q w e r t y:
как насчет 6 локалок под каждый слот вместо того чтобы каждый раз обращаться к инву?
6 обращений выходит же, с локальками было бы не меньше. Читай внимательно код
Xipxop:
Дану, глупости! Вы уже совсем зацыклились над "оптимизацией"...
Сейчас 2012 год, время когда у 70% людей компы - Больше 2 ядер!
4 года назад, может и былобы полезно, но не сейчас!
Да и еще одно, Миллионые доли секунд, роли не играют!
о смысле написания я писал, внимательным питушком будь
просто Юрок:
+1, полезно.
полезно это процентам 4-рем из всего контингента, кто задумается о специфике написания функции и попробует воспроизвести подобное где это действительно будет уместно
Этот комментарий удален
Чтобы оставить комментарий, пожалуйста, войдите на сайт.