Trochę tła, koduję grę ewolucyjną z przyjacielem w C ++, używając ENTT dla systemu encji. Stworzenia chodzą po mapie 2D, jedzą zielenie lub inne stworzenia, rozmnażają się, a ich cechy mutują.
Dodatkowo wydajność jest w porządku (60 klatek na sekundę bez problemu), gdy gra jest uruchomiona w czasie rzeczywistym, ale chcę móc ją znacznie przyspieszyć, aby nie musieć czekać 4 godziny, aby zobaczyć znaczące zmiany. Więc chcę uzyskać to tak szybko, jak to możliwe.
Staram się znaleźć skuteczną metodę dla stworzeń, aby znaleźć swoje pożywienie. Każde stworzenie powinno szukać najlepszego jedzenia, które jest im wystarczająco blisko.
Jeśli chce jeść, stworzenie przedstawione na środku ma rozejrzeć się w promieniu 149,64 (odległość widzenia) i ocenić, które jedzenie powinien realizować na podstawie żywienia, odległości i rodzaju (mięso lub roślina) .
Funkcja odpowiedzialna za odnalezienie każdego stworzenia, które je pożywienie, pochłania około 70% czasu pracy. Upraszczając sposób, w jaki jest obecnie napisany, wygląda mniej więcej tak:
for (creature : all_creatures)
{
for (food : all_entities_with_food_value)
{
// if the food is within the creatures view and it's
// the best food found yet, it becomes the best food
}
// set the best food as the target for creature
// make the creature chase it (change its state)
}
Ta funkcja jest uruchamiana co tyknięcie dla każdego stworzenia szukającego pożywienia, dopóki stworzenie nie znajdzie jedzenia i nie zmieni stanu. Jest także uruchamiany za każdym razem, gdy nowe jedzenie odradza się dla stworzeń, które już gonią za danym jedzeniem, aby upewnić się, że wszyscy sięgają po najlepsze dostępne dla nich jedzenie.
Jestem otwarty na pomysły, jak usprawnić ten proces. Chciałbym zmniejszyć złożoność z , ale nie wiem, czy to w ogóle możliwe.
Jednym ze sposobów, które już poprawiłem, jest posortowanie all_entities_with_food_value
grupy, aby gdy stworzenie przechodziło przez jedzenie zbyt duże, aby je zjeść, zatrzymywało się na nim. Wszelkie inne ulepszenia są mile widziane!
EDYCJA: Dziękuję wszystkim za odpowiedzi! Zaimplementowałem różne rzeczy z różnych odpowiedzi:
Po pierwsze i po prostu to zrobiłem, aby funkcja winy działała tylko raz na pięć tyknięć, dzięki czemu gra była 4x szybsza, nie zmieniając widocznie niczego w grze.
Następnie zapisałem w systemie wyszukiwania żywności tablicę z jedzeniem spawnowanym w tym samym tiksie, w którym działa. W ten sposób muszę tylko porównać jedzenie, które ściga stworzenie z nowymi, które się pojawiły.
Wreszcie, po badaniach nad podziałem przestrzeni i rozważeniem BVH i quadtree, poszedłem z tym drugim, ponieważ uważam, że jest to znacznie prostsze i lepiej dostosowane do mojego przypadku. Wdrażam to dość szybko i znacznie poprawia wydajność, wyszukiwanie żywności prawie nie zajmuje czasu!
Teraz renderowanie spowalnia mnie, ale to problem na kolejny dzień. Dziękuję wam wszystkim!
if (food.x>creature.x+149.64 or food.x<creature.x-149.64) continue;
powinno być łatwiejsze niż wdrożenie „skomplikowanej” struktury pamięci, JEŚLI jest wystarczająco wydajna. (Powiązane: Może nam pomóc, jeśli opublikujesz trochę więcej kodu w wewnętrznej pętli)