Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> Gra internetowa - hierarchia klas
KOMPsognat
post 3.02.2007, 13:20:54
Post #1





Grupa: Zarejestrowani
Postów: 20
Pomógł: 0
Dołączył: 23.10.2006

Ostrzeżenie: (0%)
-----


Witam!
Wiem, że jest już jeden temat o tym samym zagadnieniu, lecz dyskusja tam jest według mnie bez sensu.

Do rzeczy: piszę aktualnie dość zaawansowaną grę i chciałbym, żeby była jak najbardziej elastyczna. W grze jest kilka ras (każda ma inne ceny budynków, produkcję itp... ) oraz niektóre parametry są zależne od pory roku (jak na przykład produkcja). Wydaje się, że wystarczy zastosować dekorator, lecz sprawa jest trochę bardziej skomplikowana. Różne pory roku w mniejszym lub większym stopniu modyfikują parametry u różnych ras. Na chwilę obecną było mnóstwo różnych klas w stylu WinterCarthageBakery, SpringCarthageBakery... więc w finalnej wersji wyszłoby mi ponad 600 klas co jest niedopuszczalne i nieelastyczne. Kolejnym pomysłem było coś takiego:

Każda klasa budynku dla danej rasy dziedziczyłaby po jakiejś klasie abstrakcyjnej w której zaimplementowany byłby mechanizm wyboru odpowiedniej zmiennej z danymi (tzn. czy zimową czy może letnią tablicę z kosztami).

W ten sposób ograniczyłbym liczbę klas do ok. 150, lecz rozwiązanie znowu nie jest zbyt elastyczne.

Może macie jakiś propozycje, jak zbudować elastyczniejszy system? Może trzymać ceny w bazie danych i cache'ować tylko te dla danej pory roku? Czekam na wszystkie opinie na ten temat.

Ten post edytował KOMPsognat 10.02.2007, 19:34:20
Go to the top of the page
+Quote Post
NuLL
post 3.02.2007, 15:03:03
Post #2





Grupa: Zarejestrowani
Postów: 2 262
Pomógł: 21
Dołączył: 3.05.2004
Skąd: Sopot, Krakow, W-wa

Ostrzeżenie: (0%)
-----


Cytat
wyszłoby mi ponad 600 klas co jest niedopuszczalne i nieelastyczne
A dlaczego niedopuszczalne ?


--------------------
Javascript, Coffeescript, Node.js, Mongo, CouchDb, chmury, workery & inne bajery - zycie jest zbyt krotkie aby miec nudna prace :)
Go to the top of the page
+Quote Post
KOMPsognat
post 3.02.2007, 15:23:48
Post #3





Grupa: Zarejestrowani
Postów: 20
Pomógł: 0
Dołączył: 23.10.2006

Ostrzeżenie: (0%)
-----


Ech... złe słowo smile.gif Ale nieelastyczne jak najbardziej. Na jeden budynek przypadałoby wtedy 20 klas (nie licząc interfejsów), więc nie jest to najlepsze rozwiązanie.

Wydaje mi się, że to z bazą danych jest najlepszym rozwiązaniem, gdyż wtedy wszystko można by zmodyfikować z poziomu panelu admina, ale czekam na inne propozycje.

PS. Przy aktualnym systemie należy do tych 600 klas dolicz ok. 200 klas dla jednostek i 100 dla różnych bogów w świątyni... Wychodzi spora liczba samych danych, a modyfikacja tego to byłby koszmar.

Ten post edytował KOMPsognat 3.02.2007, 15:24:59
Go to the top of the page
+Quote Post
dr_bonzo
post 3.02.2007, 17:29:47
Post #4





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


Kilka przemyslen, moze cie gdzies doprowadza.
[przyjmuje do obliczen 4 pory roku, 3 klasy]

1. pora roku nie moze byc zapisana w klasie budynku, bo gdy zmieni sie pora roku ot bedziesz musial wymienic obiekt budynku (zniszczyc stary utworzyc nowy), czyli SpringCarthageBakery odpada.

2. jak bardzo sa podobne sa do siebie budynki? Wszystkie maja tylko atrybut Produkcja? czy roznia sie ? Produkcja Tego, Prod. Tamtego,inny budynek Tego nie produkuje?

3. jak bardzo roznia sie od siebie budynki roznych ras? To sa te same budydnki rozniace sie tylko wielkoscia produkcji? czy kazda rasa ma specyficzne budynki, o roznej produkcji?

4. jak bardzo rozne sa reguly modyfikujace produkcje? Dla danej pory roku i danej rasy modyfilkator dla wszystkich budynkow bedzie taki sam (4x3 klas) czy inny (4x3xilosc_rodzai_budynkow)?

5. przechowywanie modyfikatorow (dla pogody i rasy) w samym budynkow tez odpada: dodanie nowej rasy to wyedytowanie wszystkich klas budynkow

//
6. Wlasciwie wszytko zalezy od jednolitosci budynkow i jednolitosci wyznaczania modyfikatorow. Jesli budynki sa identyczne a modyfikatory wyrazaja sie "pojedynczym" prostym wzorem

i wtedy:
  1. <?php
  2. $modifier = $season->getProductionModifierFor( $player->race );
  3. $production = $building->getProduction( $modifier )
  4. ...
  5. function getProduction( $mod )
  6. {
  7. return $this->baseProduction * $mod
  8. }
  9.  
  10. // albo
  11.  
  12. return $mod->modifyProduction( $this->baseProduction )
  13. ?>


A jak to w samej bazie wyliczac? -- woooo, nie wiem


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
KOMPsognat
post 3.02.2007, 18:17:48
Post #5





Grupa: Zarejestrowani
Postów: 20
Pomógł: 0
Dołączył: 23.10.2006

Ostrzeżenie: (0%)
-----


Ad.1. Czemu odpada? Mam powiedzmy porę roku pobraną z bazy danych i zapisane w jakiejś zmiennej, rasę gracza i typ budynku. Z tego wszystkiego można skonstruować odpowiedni obiekt:
  1. <?php
  2. $class = $season.$tribe.$building;
  3. $object = new $class($level);
  4. ?>


Ad.2. Każdy budynek ma zapisaną w sobie cenę, produkcję na godzinę oraz kilka atrybutów specyficznych dla danego budynku. Wszystkie mechanizmy są dziedziczone po klasie abstrakcyjnej budynku.

Ad.3. Budynki różnią się produkcją i ceną. Specyficzne budynki po prostu nie mają nazwy klasy z przedrostkiem innej rasy niż tej u której występuje.

Ad.4. I tu jest pies pogrzebany. Modyfikacje mogą być różne. To zostanie podniesione, a to wręcz przeciwnie. W zimie u jednej rasy może być coś zwiększone a u innej zmniejszone.

Ad.5. Dodanie nowej rasy to nie modyfikowanie, lecz dodanie ok. 140 klas (na chwilę obecną).

Ad.6. Co do samej bazy danych. Na chwilę obecną widzę to tak: tabele w formacie "SezonRasa" i tam zapisane ceny i produkcja. Te dane byłyby cachowana przy każdej zmianie pory roku. W sumie działa to tak samo jak te setki klas w formacie SezonRasaBudynek, ale modyfikacje łatwiejsze.
Go to the top of the page
+Quote Post
dr_bonzo
post 3.02.2007, 19:45:05
Post #6





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


1-6.
Sorry -- myslalem za bardzo OOP i o aplikacji dzialajacej w czasie rzeczywistym a nie uruchamianej z kazdym requestem



Jak chcesz to z bazy czytac to raczej proscizna:
- w jednej tabeli masz budynki + ich podstawowa produkcje
- w drugiej dla kazdego budynku masz kilka rekordow z modyfikatorami dla (danej pory roku)X(danej rasy)

lub wrzuc do jednej tabeli z koncowymi wartosciami produkcji.


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
KOMPsognat
post 3.02.2007, 20:22:46
Post #7





Grupa: Zarejestrowani
Postów: 20
Pomógł: 0
Dołączył: 23.10.2006

Ostrzeżenie: (0%)
-----


Tak też od początku myślałem, ale wpadała mi do głowy jeszcze taka myśl. Brały by udział trzy klasy: budynek (np. Bakery), plemię (np. Carthage) oraz sezon (czyli np. Winter). I teraz widzę to tak:

1. Konstruktor budynku oczekuje nacji gracza
2. Następnie tworzy egzemplarz klasy nacji i pobiera z nich tylko interesującą tablicę (w tym wypadku Bakery) z modyfikatorami parametrów budynku
3. Podczas tworzenia klasy Carthage ta wywołuje konstruktor klasy Winter która zwraca modyfikatory dla danego budynku danej nacji.
4. Klasa Carthage zwraca już dane po "konfrontacji" z danymi z klasy Winter.
4. Gdy klasa Bakery otrzyma wszystkie dane to zwraca ostateczny koszt budynku.

Wymyśliłem to na szybko jadąc w tramwaju, ale może coś się z tego się urodzi coś sensownego. Bardzo prosiłbym o opinie na ten temat.

Aha. Nie przejmujcie się chwilowo modyfikacją parametrów tych poszczególnych klas... Jako tako również mam to obmyślane.

----------
Edit:
----------
Kolejne przemyślenia:

Całkiem przez przypadek wyszedł mi z tego co wyżej napisałem najzwyczajniejszy dekorator:
  1. <?php
  2. $object = new Winter(new Carthage(new Bakery($lvl)));
  3. ?>


1. Klasa Bakery zwracałaby podstawową cenę.
2. Klasa Carthage sprawdza jaki to budynek i wybiera odpowiednie modyfikatory:

  1. <?php
  2. //tablica
  3. $mods = array(
  4. 'Bakery' => array ('tutaj modyfikatory'),
  5. 'Następny budynek' => array ('modyfikatory'));
  6.  
  7.  
  8. //konstruktor klasy Bakery
  9. public function __construct($building) {
  10. return $this->mods[get_class($building)];
  11. }
  12. ?>


3. Na podobnej zasadzie działa klasa Winter, zwracając kolejną tablicę po modyfikacjach.

Ten post edytował KOMPsognat 4.02.2007, 08:25:03
Go to the top of the page
+Quote Post
dr_bonzo
post 4.02.2007, 12:47:20
Post #8





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


Dekorator to nie bedzie, bo w dekoratorze wszystkie klasy musza byc z tej samej hiearchi, czyli Winter musialby byc Budynkiem, tak samo jak i nacja/rasa.

http://www.dofactory.com/Patterns/Diagrams/decorator.gif


  1. <?php
  2. public function __construct($building) {
  3. return $this->mods[get_class($building)];
  4. }
  5. ?>

To nie przejdzie w takiej formie smile.gif Konstruktor niczego nie moze zwracac, wiem, pospiech itd.


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
KOMPsognat
post 4.02.2007, 14:08:55
Post #9





Grupa: Zarejestrowani
Postów: 20
Pomógł: 0
Dołączył: 23.10.2006

Ostrzeżenie: (0%)
-----


Ad.1. Równie dobrze można to nazwać WinterDecorator. Tak mi było szybciej smile.gif Ważne, że miało działać na podobnej zasadzie.

Ad.2. Ostatnio przyszło mi pracować na PHP3, więc jeszcze nie wróciłem do siebie smile.gif Trochę bez sensu byłoby użycie return w konstruktorze biggrin.gif

PS. Problem rozwiązany. Moje cholerne nawyki po niedawnej pracy w przestarzałej wersji php. Po cholerę samym kosztom wydzielać klasę rolleyes.gif Zrobię po prostu stałe z cenami i gotowe.

PS.2. Wystarczy to rozwiązać w taki sposób:
  1. <?php
  2. $building = new Bakery($season, $tribe, $lvl);
  3. ?>

a konstruktor będzie składał to w całość z wartości zapisanych w stałych.

Ten post edytował KOMPsognat 4.02.2007, 14:12:20
Go to the top of the page
+Quote Post
Secator
post 6.02.2007, 02:16:45
Post #10





Grupa: Zarejestrowani
Postów: 8
Pomógł: 0
Dołączył: 25.01.2007
Skąd: AGH

Ostrzeżenie: (0%)
-----


Swoją drogą w nie lepiej stosować czegoś w stylu:

funkcja pobierzcene( )
{
cena = cena_podstawowa* (1 + rasa1*2 + rasa2*2) + 666*zima +333*wiosna -100*lato
return cena
}

gdzie rasa1 = 1 jesli gracz jest rasą 1, zero jesli jest jakąs inną i podobnie z innymi parametrami...
(w tym wypadku przy cenie podstawowej 1000 cena w lecie dla rasy 1 wynosi np.
3*1000-100=2900)

Jest to chyba prostsze i do wykonania i do późniejszych modyfikacji i wystarczy wtedy mieć tyle klas ile jest różnych budynków bedacych rozszerzeniem klasy budynek zawierajacej wszystko to co każdy budynek posiada ;]
edit:: Ew. żeby budynek dziedziczył modyfikatory po klasie nacji zawierajacej parametr 'pora roku'??
Go to the top of the page
+Quote Post
KOMPsognat
post 6.02.2007, 19:19:11
Post #11





Grupa: Zarejestrowani
Postów: 20
Pomógł: 0
Dołączył: 23.10.2006

Ostrzeżenie: (0%)
-----


Napisałem, że modyfikatory są zróżnicowane. Nie ma zasady, że u rasy1 będzie zawsze 0.7 a u rasy2 1.3 . Modyfikator jest różny dla każdego budynku itp.

Co do rozwiązania problemu. Rozwiązałem to w taki sposób:

Struktura:
Kod
costs
|- rasa1.php
|- rasa2.php
|- ...


Kod poszczególnych plików:
  1. <?php
  2. $budynek1 = array(
  3.  'Winter' => array('Gold' => x, 'Wood' => x, '...'),
  4.  'Spring' => array('Gold' => x, 'Wood' => x, '...'),
  5.  '...' => '...'
  6.  );
  7.  
  8. $budynek2 = array(
  9.  'Winter' => array('Gold' => x, 'Wood' => x, '...'),
  10.  'Spring' => array('Gold' => x, 'Wood' => x, '...'),
  11.  '...' => '...'
  12.  );
  13. ?>


Oraz sama implementacja:
  1. <?php
  2. //...
  3. public function getCosts($lvl, $season, $tribe)
  4. {
  5. include_once ('./costs/'.$tribe.'.php');
  6. return $$this->building[$season]; //zmienna building przechowuje informacje jaki to budynek
  7. }
  8. //...
  9. print_r($building->getCosts(x, 'Winter', 'Romans');
  10. ?>
Go to the top of the page
+Quote Post
KG-
post 8.02.2007, 21:22:31
Post #12





Grupa: Zarejestrowani
Postów: 61
Pomógł: 0
Dołączył: 30.05.2006

Ostrzeżenie: (0%)
-----


No i to jest wg mnie najlepsze rozwiązanie, bawienie się w 600 klas z dziedziczeniem i dekoratorami, jeśli można coś zrobić dużo łatwiej na tablicach to zdecydowanie przerost formy nad treścią, w końcu gra docelowo będzie obsługiwana przez tysiące ludzi więc chodzi o to żeby kod działał jak najszybciej (i jednocześnie był łatwy w modyfikacji) smile.gif

Jedynie zamiast zmiennych $budynek1, $budynek2 itd zrobiłbym po prostu tablice budynków, chyba że to ma jakiś głębszy sens którego nie dostrzegam smile.gif
Go to the top of the page
+Quote Post
Secator
post 8.02.2007, 23:05:40
Post #13





Grupa: Zarejestrowani
Postów: 8
Pomógł: 0
Dołączył: 25.01.2007
Skąd: AGH

Ostrzeżenie: (0%)
-----


Cytat
Napisałem, że modyfikatory są zróżnicowane. Nie ma zasady, że u rasy1 będzie zawsze 0.7 a u rasy2 1.3 . Modyfikator jest różny dla każdego budynku itp.
Myśle ze trzymanie modyfikatorów jako zmiennych nie jest problemem... ale rób jak chcesz :] Sam wiesz lepiej co Ci jest potrzebne.

Swoja droga to wydaje mi sie że ta gra bedzie tak skomplikowana że gracze nie beda w stanie sie połapać biggrin.gif X budynków dla Y nacji z Z parametrami zależnych od Ź czynników... :] Masz już jakąs wersje beta do testów?? Chętnie bym po testował, może własnie coś wartego uwagi powstaje biggrin.gif

pozdro

Ten post edytował Secator 8.02.2007, 23:06:36
Go to the top of the page
+Quote Post
KOMPsognat
post 9.02.2007, 08:17:41
Post #14





Grupa: Zarejestrowani
Postów: 20
Pomógł: 0
Dołączył: 23.10.2006

Ostrzeżenie: (0%)
-----


Hehe... akurat w tym przecież nie ma nic trudnego (z punktu widzenia gracza). Każda rasa ma inne ceny budynków i ich produkcję. Trudności może przynieść obsługa pór roku, ale myślę, że gracze sobie poradzą. smile.gif

Co do bety: Chwilowo nie ma. Co do możliwości gry:
  • 5 nacji: Kartagina, Partia, Rzym, Egipt, Grecja
  • 4 pory roku
  • ok. 30 budynków: http://atofaq.yoyo.pl
  • 10 jednostek na każdą nację.
  • możliwość "zbierania" i handlowania niewolnikami.
  • losowe zdarzenia zależne od zadowolenia bóstw w świątynii
  • zaawansowany system bitewny: możliwość grupowania w oddziały, generałowie, dowódcy, formacje wojenne, typy ataku (szarża lub normalny), doświadczenie oddziałów...
  • hołd lenny (przydatna opcja dla osób, którym nie chce się farmić :] )


Ten post edytował KOMPsognat 9.02.2007, 17:48:54
Go to the top of the page
+Quote Post
bacca
post 9.02.2007, 23:57:39
Post #15





Grupa: Zarejestrowani
Postów: 4
Pomógł: 0
Dołączył: 11.06.2005

Ostrzeżenie: (10%)
X----


Miałem kiedyś taki problem. Jeśli mogę jakoś pomóc to spróbuję.

1. Olej zawieranie takich ilości powiązanych danych na twardo w kodzie. Zrób sobie klasę (lub kilka), która odczytuje swoje parametry dynamicznie na podstawie otrzymanych parametrów. Zrób sobie tabelę i z niej odczytuj wszelkie parametry budynków. W ten sposób znacznie ograniczysz liczbę klas.

2. Zrób sobie edytor parametrów do obsługi tejże tabeli. Tak, żebyś sobie dla danej rasy i pory roku i typu budynku edytowal parametry. W ten sposób łatwiej Ci będzie wypełnić tabelę danymi i korygować późniejszą rozgrywkę.

3. Wszelkie możliwe konfiguracje parametrów danego budynku serializuj i buforuj np. do pliku, żeby nie zarzynać bazy milionami odczytów.

4. Możesz się też zapoznać z wzorcem Prototype i technikami buforowania. To załatwi problem całkowicie.

Gdybym wyraził się niejasno spróbuję zilustrować pseudokodem.

  1. <?php
  2. class Budynek {
  3. private $nazwa;
  4. private $rasa;
  5. private $typ;
  6. private $cena;
  7. private $produkcja;
  8. // itd....
  9.  
  10. public function __construct($typ, $rasa, $pora_roku, $itd, $itp) {
  11. $result = $db->query('SELECT * FROM `budynki` WHERE `rasa` = $rasa AND `pora_roku` = $pora_roku itd.it
    p. '
    );
  12. foreach ($result as $prop) {
  13. $this->$propname = $prop;
  14. }
  15. }
  16. }
  17. ?>

U mnie wyglądało w dużym uproszczeniu mniej więcej tak. Na pocieszenie dodam, że problem da się rozwiązać w kilku do kilkunastu klasach. Powodzenia
Go to the top of the page
+Quote Post
KOMPsognat
post 10.02.2007, 08:00:00
Post #16





Grupa: Zarejestrowani
Postów: 20
Pomógł: 0
Dołączył: 23.10.2006

Ostrzeżenie: (0%)
-----


Chyba zostanę przy swoim pomyśle, gdyż nie będzie trzeba wykonywać zapytania SQL. Podane pliki z cenami będą generowane automatycznie z poziomu admina, więc modyfikacje będą w miarę wygodne.
Go to the top of the page
+Quote Post
bacca
post 11.02.2007, 11:09:35
Post #17





Grupa: Zarejestrowani
Postów: 4
Pomógł: 0
Dołączył: 11.06.2005

Ostrzeżenie: (10%)
X----


Przeczytaj jeszcze raz punkt 3. i 4. Naprawde da sie w ten sposób uzyskać całkiem wydajny sposób odczytywania tych danych.
Go to the top of the page
+Quote Post
KOMPsognat
post 11.02.2007, 12:33:17
Post #18





Grupa: Zarejestrowani
Postów: 20
Pomógł: 0
Dołączył: 23.10.2006

Ostrzeżenie: (0%)
-----


No to muszę przyznać, że Twój sposób drastycznie różni się od mojego... aaevil.gif
Poza tym wydaje mi się, że zapis w postaci tablicy będzie po prostu szybszy (choć testów nie przeprowadzałem). Modyfikacje tego z poziomu admina będą zapisywane w bardzo łatwy sposób - skasowanie i utworzenie nowych plików z cenami.

Trudne? Nie sądzę.
Elastyczne? Tak.
Szybkie? Tak.

Same zalety :]
Go to the top of the page
+Quote Post
Ace
post 11.02.2007, 17:28:51
Post #19





Grupa: Zarejestrowani
Postów: 216
Pomógł: 0
Dołączył: 9.08.2003
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


heh... Nie po to sa bazy danych, zeby zapisywac potrzebne rzeczy w plikach...

To moze zrob sobie zarzadzanie tego z poziomu bazy, a takie generowanie plikow php z dokladnymi informacjami potraktuj jako cache?

Ja osobiscie wykonalbym to na bazie danych. Latwo znalezc, latwo zmienic, latwo dodac.
Go to the top of the page
+Quote Post
KOMPsognat
post 11.02.2007, 19:44:15
Post #20





Grupa: Zarejestrowani
Postów: 20
Pomógł: 0
Dołączył: 23.10.2006

Ostrzeżenie: (0%)
-----


I łatwo zerżnąć komputer. Jeżeli mam wykonywać ok. 1000 zapytań na sekundę po same ceny to ja dziękuję...
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 25.04.2024 - 01:49