|
3D-программирование Вопросы, касающиеся программирования 3D мира |
15.12.2007, 23:57
|
#1
|
Разработчик
Регистрация: 09.12.2007
Сообщений: 376
Написано 83 полезных сообщений (для 122 пользователей)
|
Перебор нескольких списков за цикл
Делаю ботов, решил предусмотреть командную игру, т.е. действие для каждого юнита (бота): определить близжайшего врага, переключиться в режим (например уничтожение), управление юнитом игрока, прочие обработка выстрелов, частиц, динамики и прочие функции вызывающиеся в цикле.
Чтобы не перебирать список юнитов для определения врага каждого юнита, а так же не разбираться со связанными списками, решил просто разбить все юниты на четыре списка (нейтралы и три врага).
Подскажите, как мне сделать перебор четырех списков в одном цикле, и возможно ли такое? Создавать 4 одинаковых цикла не хочется, изменения потом вносить неудобно.
Например:
For all.Unit1=Each Unit1
...
Next
И добавить в цикл перебор Unit2, Unit3, Unit4.
Или может быть другой вариант?
|
(Offline)
|
|
16.12.2007, 01:11
|
#2
|
Дэвелопер
Регистрация: 07.09.2005
Сообщений: 1,519
Написано 66 полезных сообщений (для 164 пользователей)
|
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. Набирал в окне браузера, возможны опечатки.
|
(Offline)
|
|
16.12.2007, 02:04
|
#3
|
Разработчик
Регистрация: 09.12.2007
Сообщений: 376
Написано 83 полезных сообщений (для 122 пользователей)
|
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 раза одну ф-цию писать из-за этого?
|
(Offline)
|
|
16.12.2007, 09:04
|
#4
|
|
Re: Перебор нескольких списков за цикл
FrankH
зачем ? сведи все к одному типу
а проверяй враг или не враг по Unit\Nation
|
|
|
Сообщение было полезно следующим пользователям:
|
|
16.12.2007, 09:09
|
#5
|
Дэвелопер
Регистрация: 19.03.2006
Сообщений: 1,241
Написано 10 полезных сообщений (для 17 пользователей)
|
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
Недолжны они буть одинаковые!!!
А чтобы такой траблы небыло юзай функции!
|
(Offline)
|
|
16.12.2007, 11:58
|
#6
|
Разработчик
Регистрация: 09.12.2007
Сообщений: 376
Написано 83 полезных сообщений (для 122 пользователей)
|
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..
Обьясни пожалуйста подробнее, как?
|
(Offline)
|
|
16.12.2007, 14:05
|
#7
|
Дэвелопер
Регистрация: 07.09.2005
Сообщений: 1,519
Написано 66 полезных сообщений (для 164 пользователей)
|
Re: Перебор нескольких списков за цикл
у меня тот же принцип, но получается что для 4х сторон нужно писать 4 практически одинаковых цикла?
|
Да, получается. Только для четырех сторон конфликта- не 4, а 16 "практически одинаковых циклов". Пожалуйста, не майся ерундой.
Или что там ХолиДел говорил о кодогенераторе? ))
если все в одном списке, то каждый бот ищет цель среди всех, а достаточно искать только среди половины.
|
Сколько у тебя ботов? Много ли времени займёт, если каждый юнит раз в полсекунды прогонит цикл по всем юнитам и вычленит ветвлением врагов? Проверь на очевидном примере.
Оптимизация- она в другом. )
|
(Offline)
|
|
16.12.2007, 14:31
|
#8
|
☭
Регистрация: 26.09.2006
Сообщений: 6,035
Написано 1,474 полезных сообщений (для 2,707 пользователей)
|
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
все ето писалось в браузере, так что за многочисленные ошибки извиняйте.
|
(Offline)
|
|
16.12.2007, 15:24
|
#9
|
Разработчик
Регистрация: 09.12.2007
Сообщений: 376
Написано 83 полезных сообщений (для 122 пользователей)
|
Re: Перебор нескольких списков за цикл
HolyDel, да, так впринципе и выходит, но у меня 3 воюющих стороны и одна сторона нейтральна до нападения на нее, итого 4.
Всем спасибо за советы, буду пробовать!
|
(Offline)
|
|
14.02.2008, 02:57
|
#10
|
Оператор ЭВМ
Регистрация: 14.09.2007
Сообщений: 27
Написано 2 полезных сообщений (для 5 пользователей)
|
Ответ: Re: Перебор нескольких списков за цикл
Сообщение от jimon
FrankH
зачем ? сведи все к одному типу
а проверяй враг или не враг по Unit\Nation
|
есть идея создать в игре только один тип, отвечающий за всех. Сам игрок, друзья, враги, еще кто нибудь (и пульки тоже) - это один тип обьектов, разделенный по классу.
Преимущества очевидны - в цикле игры будет только один обработчик.
внутри обработчика должно быть примерно так:
...
unitClass%=Unit\Class
select unitClass
Case MainPlayer
...
Case Bot
...
Case Bullet
...
...
...
Последний раз редактировалось dimond, 14.02.2008 в 06:09.
|
(Offline)
|
|
14.02.2008, 03:08
|
#11
|
ПроЭктировщик
Регистрация: 23.09.2007
Сообщений: 126
Написано 11 полезных сообщений (для 16 пользователей)
|
Ответ: Перебор нескольких списков за цикл
Я думаю что идея хорошая.
Когда я свой мапер (Мой редактор мира) писал я определитель делал.сделано на (45%)
создавал класс и в переменой хронил текст каторый определял например свет звук
Так легче загрузить и сохранить проэкт!
|
(Offline)
|
|
14.02.2008, 11:54
|
#12
|
scientist.alien
Регистрация: 12.02.2007
Сообщений: 2,098
Написано 1,030 полезных сообщений (для 2,593 пользователей)
|
Ответ: Перебор нескольких списков за цикл
Перебор 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 раз.
__________________
Public service announcement: вы можете заблокировать отображение сообщений определённого пользователя, добавив его ник в список игнорируемых.
Tau lab. We LOVE you. We MADE you.
|
(Offline)
|
|
14.02.2008, 12:09
|
#13
|
☭
Регистрация: 26.09.2006
Сообщений: 6,035
Написано 1,474 полезных сообщений (для 2,707 пользователей)
|
Ответ: Перебор нескольких списков за цикл
да ну©
а если мне очень хочеться чтобы Unit2 как то реагировал на Unit4?
|
(Offline)
|
|
14.02.2008, 13:39
|
#14
|
|
Ответ: Перебор нескольких списков за цикл
Ize'g0re
уууу
перебор самого списка занимает жутко мало времени,
если мы будем писать
For u1.Unit1=Each Unit1
Next
то если там меньше чем сто тысяч юнитов то время не очень много займет
нужно прямое обновление вниз по списку ... нафиг такой изврат
говорю же надо нпсу просто приписать Nation% и Group%
я думаю два ифа для 50 ботов ето не критично
в любом случае если хитро не оптимайзить то от O(N^2) никуда не денешся
|
|
|
14.02.2008, 13:52
|
#15
|
.
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений (для 6,863 пользователей)
|
Ответ: Перебор нескольких списков за цикл
jimon, хм, по идее, можно делать сектора, которые будут прямо давать понимать, что с далёёёким объектом не будет перебора. И обновлять постепенно класс с линкми на объекты в секторах, (от и до полный перебор за 2 секунды к примеру, но не каждые 2 перебирать всех и распределять, а в течении 2 секунд по чучуть), таким образом будет всё разбито, и можно уже делать перебор исходя из секторов, а далее исходя из Nation
|
(Offline)
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 13:32.
|