forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   3D-программирование (http://forum.boolean.name/forumdisplay.php?f=12)
-   -   Перебор нескольких списков за цикл (http://forum.boolean.name/showthread.php?t=5315)

FrankH 15.12.2007 23:57

Перебор нескольких списков за цикл
 
Делаю ботов, решил предусмотреть командную игру, т.е. действие для каждого юнита (бота): определить близжайшего врага, переключиться в режим (например уничтожение), управление юнитом игрока, прочие обработка выстрелов, частиц, динамики и прочие функции вызывающиеся в цикле.
Чтобы не перебирать список юнитов для определения врага каждого юнита, а так же не разбираться со связанными списками, решил просто разбить все юниты на четыре списка (нейтралы и три врага).
Подскажите, как мне сделать перебор четырех списков в одном цикле, и возможно ли такое? Создавать 4 одинаковых цикла не хочется, изменения потом вносить неудобно.
Например:
For all.Unit1=Each Unit1
...
Next
И добавить в цикл перебор Unit2, Unit3, Unit4.
Или может быть другой вариант?:dontknow:

Diplomat 16.12.2007 01:11

Re: Перебор нескольких списков за цикл
 
Рекомендую следовать такой логике:
Код:

FOR Friend.Units=EACH Units

 ;...Тут управляем всеми юнитами: своими и чужими...

 ;Боевой ИИ (вызывается не постоянно, а изредка,
 ;или даже вообще- только по необходимости. Тут показан простой пример.)
 IF Friend\AIDelay<MILLISECS() THEN
 Friend\AIDelay=MILLISECS()+MaxAIDelay

  ;Проверяем всех юнитов, вычленяя из списка врагов (или друзей и прочих нужных)
  For Enemy.Units=EACH Units
  IF Enemy\Nation<>Friend\Nation THEN

    ;...Тут проверяем, видит ли наш юнит врага, и задаём ему
    ;корректные задачи в соответствии с результатом...

  ENDIF
  NEXT

  END IF

NEXT

P.S. Набирал в окне браузера, возможны опечатки.

FrankH 16.12.2007 02:04

Re: Перебор нескольких списков за цикл
 
Diplomat, у меня тот же принцип, но получается что для 4х сторон нужно писать 4 практически одинаковых цикла?
Кстати походу появилась еще одна ошибка:
If side=0 u.Unit_neutral=New Unit_neutral
If side=1 u.Unit_humans=New Unit_humans
If side=2 u.Unit_ххх=New Unit_ххх
If side=3 u.Unit_bandits=New Unit_bandits
...
пишет на второй строке "вариейбл тайп мисматч.." опять же надо 4 раза одну ф-цию писать из-за этого?

jimon 16.12.2007 09:04

Re: Перебор нескольких списков за цикл
 
FrankH
зачем ? сведи все к одному типу
а проверяй враг или не враг по Unit\Nation

ЛысыЙ_Чук-Иванчук 16.12.2007 09:09

Re: Перебор нескольких списков за цикл
 
Цитата:

Сообщение от FrankH
Diplomat, у меня тот же принцип, но получается что для 4х сторон нужно писать 4 практически одинаковых цикла?
Кстати походу появилась еще одна ошибка:
If side=0 u.Unit_neutral=New Unit_neutral
If side=1 u.Unit_humans=New Unit_humans
If side=2 u.Unit_ххх=New Unit_ххх
If side=3 u.Unit_bandits=New Unit_bandits
...
пишет на второй строке "вариейбл тайп мисматч.." опять же надо 4 раза одну ф-цию писать из-за этого?

Ошибка вот в чем-
If side=0 u.Unit_neutral=New Unit_neutral
If side=1 u.Unit_humans=New Unit_humans
If side=2 u.Unit_ххх=New Unit_ххх
If side=3 u.Unit_bandits=New Unit_bandits


Недолжны они буть одинаковые!!!
А чтобы такой траблы небыло юзай функции!;)

FrankH 16.12.2007 11:58

Re: Перебор нескольких списков за цикл
 
jimon, если все в одном списке, то каждый бот ищет цель среди всех, а достаточно искать только среди половины.
ЛысыЙ_Чук-Иванчук, я понял это так, точнее видать не понял:
If side=0 a.Unit_neutral=New Unit_neutral unit_processing(side,a\mesh)
If side=1 b.Unit_humans=New Unit_humans unit_processing(side,b\mesh)
If side=2 c.Unit_ххх=New Unit_ххх unit_processing(side,c\mesh)
If side=3 d.Unit_bandits=New Unit_bandits unit_processing(side,d\mesh)
...
function unit_processing(side,obj)
if side=0 а.Unit_neutral=Object.Unit_neutral(EntityName(obj) )
end function
опять же нужен перебор по side и разные a,b..
Обьясни пожалуйста подробнее, как?

Diplomat 16.12.2007 14:05

Re: Перебор нескольких списков за цикл
 
Цитата:

у меня тот же принцип, но получается что для 4х сторон нужно писать 4 практически одинаковых цикла?
Да, получается. Только для четырех сторон конфликта- не 4, а 16 "практически одинаковых циклов". Пожалуйста, не майся ерундой.
Или что там ХолиДел говорил о кодогенераторе? ))
Цитата:

если все в одном списке, то каждый бот ищет цель среди всех, а достаточно искать только среди половины.
Сколько у тебя ботов? Много ли времени займёт, если каждый юнит раз в полсекунды прогонит цикл по всем юнитам и вычленит ветвлением врагов? Проверь на очевидном примере.
Оптимизация- она в другом. )

HolyDel 16.12.2007 14:31

Re: Перебор нескольких списков за цикл
 
ети четыре стороны абсолюьно разные?
вообще господа, можно отделаться и двумя циклами.
смотрим на дипломатов код и думаем.
определенно в nation дожно хранится то, кто етот юнит
N_ORC, N_HUMAN, N_ELF, N_DVORNIC_IVAN_MIHAYLOVICH.
далее перебираем
for u1.units=each u1.units
for u2.units=each u2.units
if u1\nation<>u2\nation ;юниты одной команды друг на друга никак не влияют
select u1.nation
case N_ORC
select u2.nation
case N_HUMAN
смотир что орк должен сделать с человеком
case N_ELF
... с ельфом
case N_DVORNIC_IVAN_MIHAYLOVICH
... с дворником иван - михайлычом
case N_HUMAN
... и так далее
case N_ELF
case N_DVORNIC_IVAN_MIHAYLOVICH
... если кому то пофигу, против кого он, то можно и не перебирать, например дворник должен завидев врага кричать: "А я Иван Михайлыч! и с вами не играю!"/ поетому сортировку врога можно и не делать.
endf
next
next

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

FrankH 16.12.2007 15:24

Re: Перебор нескольких списков за цикл
 
HolyDel, да, так впринципе и выходит, но у меня 3 воюющих стороны и одна сторона нейтральна до нападения на нее, итого 4.
Всем спасибо за советы, буду пробовать! :)

dimond 14.02.2008 02:57

Ответ: Re: Перебор нескольких списков за цикл
 
Цитата:

Сообщение от jimon (Сообщение 69870)
FrankH
зачем ? сведи все к одному типу
а проверяй враг или не враг по Unit\Nation

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

...
unitClass%=Unit\Class
select unitClass
        Case MainPlayer
                ...
        Case Bot
                ...
        Case Bullet
                ...
        ...
...


-=SCiP=- 14.02.2008 03:08

Ответ: Перебор нескольких списков за цикл
 
Я думаю что идея хорошая.
Когда я свой мапер (Мой редактор мира) писал я определитель делал.сделано на (45%)
создавал класс и в переменой хронил текст каторый определял например свет звук
Так легче загрузить и сохранить проэкт!

Taugeshtu 14.02.2008 11:54

Ответ: Перебор нескольких списков за цикл
 
Перебор 4-х списков за раз:
Код:

u2.Unit2=First Unit2
u3.Unit3=First Unit3
u4.Unit4=First Unit4

For u1.Unit1=Each Unit1
    ;some logics here]
    ;...
   
    temporary.Unit2=Last Unit2
    If u2<>temporary Then
        u2=After Unit2
        Else
            ; [1]
        EndIf
   
    temporary.Unit3=Last Unit3
    If u3<>temporary Then
        u3=After Unit3
        Else
            ; [1]
        EndIf
   
    temporary.Unit4=Last Unit4
    If u4<>temporary Then
        u4=After Unit4
        Else
            ; [1]
        EndIf
Next

[1] - сюда нужно поставить ограничитель на количество проходов за цикл. Если его не будет, возмоюжна ситуация, когда в одном списке 3 юнита, в другом - 30, и последний из первого списка юнит будет обсчитываться 28 раз.

HolyDel 14.02.2008 12:09

Ответ: Перебор нескольких списков за цикл
 
да ну©
а если мне очень хочеться чтобы Unit2 как то реагировал на Unit4?

jimon 14.02.2008 13:39

Ответ: Перебор нескольких списков за цикл
 
Ize'g0re
уууу

перебор самого списка занимает жутко мало времени,
если мы будем писать
For u1.Unit1=Each Unit1
Next
то если там меньше чем сто тысяч юнитов то время не очень много займет

нужно прямое обновление вниз по списку ... нафиг такой изврат

говорю же надо нпсу просто приписать Nation% и Group%
я думаю два ифа для 50 ботов ето не критично
в любом случае если хитро не оптимайзить то от O(N^2) никуда не денешся

moka 14.02.2008 13:52

Ответ: Перебор нескольких списков за цикл
 
jimon, хм, по идее, можно делать сектора, которые будут прямо давать понимать, что с далёёёким объектом не будет перебора. И обновлять постепенно класс с линкми на объекты в секторах, (от и до полный перебор за 2 секунды к примеру, но не каждые 2 перебирать всех и распределять, а в течении 2 секунд по чучуть), таким образом будет всё разбито, и можно уже делать перебор исходя из секторов, а далее исходя из Nation :)

HolyDel 14.02.2008 13:58

Ответ: Перебор нескольких списков за цикл
 
а можно все писать на ассемблере.
только не нужно...

все равно все время сжирает Рендер.


Часовой пояс GMT +4, время: 19:19.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot