Model obiektowy UML - gra planszowa

0

Witam,
Mamy język JAVA.

Jakbyście zrealizowali następującą rzecz :
Będziemy tworzyć Planszę, która będzie miała jakieś pola. I teraz umówmy się, że mamy jak to w grze planszowej - zwykłe pola + pola szczególne.
Powiedzmy, że mamy za zadanie wylosować 10 pól na których postawimy potworka, ale jeszcze mamy 4 gatunki potworków. Tzn, że za każdym razem gdy losujemy jednego z dziesięciu potworków musimy jeszcze wylosować, którego spośród czterech potworków wylosujemy. Jak to proponujecie zrealizować ?

1

Pisałem kiedyś coś podobnego ;) Miałem klasę bazową dla "pola" i taka klasa miała metodę applyEffect(Player). Klasy dziedziczące implementowały odpowiednio tą metodę (np. powodując zablokowanie gracza na kilka kolejek albo pozwolenie mu na ponowne losowanie, albo przesuwając go na inne pole etc).
Samo losowanie pól jest raczej trywialne.
Główna pętla gry operuje oczywiście na referencjach do typu bazowego i korzysta z polimorfizmu do aplikowania efektów specjalnych na polach.

0

Dzięki wielkie, jednak zależy mi żeby to **dokładnie **skonkretyzować.

  1. Miałeś nadklasę Pole - czy to było abstrakcyjne ? Czy jakieś pola abstrakcyjne ?
  2. Rozumiem, że każde szczególne pole dziedziczy po klasie Pole, a jak ze zwykłymi polami ?
  3. A co z pionkiem ? Jak go połączyłeś z całą resztą ?
  4. Jak np. wykryłeś że stanąłeś właśnie na pewien typ pola, na którym jest coś co "zbiera" pionek i zachowuje na dalszą częśc gry ?
  5. Jak zrealizować to losowanie ? To nie jest takie trywialne właśnie - musimy wylosować Pole, któro jest niezajęte przez żaden przedmiot szczególny - następnie wylosować przedmiot, który postawimy, a następnie dalej - "gatunek" tego przedmiotu (jeden z kilku). I o ile losowanie liczb jset łatwe- to tutaj chcemy zrealizować coś trudniejszego, a mianowicie lsoowć jakby obiekty.

Wszystkie te pytaina, tak na prawdę dotyczą modelowania - jak to zrealizować elegancko obiektowo. Jedynie (5) jest bardziej techniczne, ale nie mniej ważne - tzn często mam problem, tego typu że trzeba wylosować jedną z możliwych postaci obiektu.

PS Proszę o szczegółowe dość odpowiedzi, bo cały czas jestem na etapie nauki.
Napisałem ze swojego konta, a tamto forumowicz123 to było "na szybko"

Pozdrawiam!

1
  1. Miałem klasę Tile która miała abstrakcyjną metodę applyEffects. To w zasadzie był interfejs, ale pisałem w C++ ;)
  2. Zwykłe pole to było SimpleTile które miało po prostu pustą metodę applyEffects
  3. Pionek to była klasa Player i w trakcie wykonywania ruchu robiłem field.applyEffects(player). Wykonywanie ruchu przez gracza:
bool Board::performPlayerMove(int playerId) {
	Player& activePlayer = players[playerId];
	activePlayer.useTurn();
	while (activePlayer.changedPosition()) {
		if (activePlayer.getPosition() + 1 >= numberOfTiles) {
			cout << "Gracz " << activePlayer.getId() << " przekroczyl linie mety i tym samym jest zwyciezca!\n";
			return true;
		} else {
			tiles[activePlayer.getPosition()]->applyEffect(activePlayer); //applying special effect depending on the field player is standing on
		}
	}
	return false;
}

useTurn() w playerze to jest rzucenie kostką i przesunięcie pionka (pionek sam zna swoją pozycję)
pętla jest tu potrzebna po to, że gracz może wskoczyć na pole które pozwala mu rzucać ponownie na przykład, więc może wykonywać wiele ruchów w jednej kolejce.

  1. Nie miałem takiej opcji, ale miałem na przykład opcje taką że zbierasz pole "zablokowany na X kolejek". Klasa player po prostu musi sobie przechowywać taką informację. U mnie był to licznik kolejek ile musisz czekać, a jak ty chcesz coś zbierać to musisz tam trzymać jakąś listę obiektów zebranych i tyle.
  2. Nadal nie rozumiem gdzie masz problem. Zrób sobie tablicę klas tych swoich obiektów, losuj indeks w tablicy i następnie twórz nowy obiekt:
tablica[indeks].newInstance();
0

Okey, wnet przeczytam dokładnie Twoje odpowiedzi.
6. Jak zrealizujesz model obiektowy (dziedziczenie + klasy abstrakcyjne) następującego problemu:
Na planszy zawsze losując teleport losujesz od razy pole, na którym pionek może znaleźć klucz do tego teleportu - tzn jak wspominałem - jest kilka rodzai teleportu - a więc klucz który wylosujemy otworzy tylko teleporty tego rodzaju - tzn teleport każdego rodzaju ma do siebie pasujące klucze również tego rodzaju:
powiedzmy: żółty, niebieski, czerwony teleport - odpowiednio pasują klucze - żółty, niebieski, czerwony. Co więcej każdego klucza można użyć dokładnie raz.

Jak to zrealizujesz ? Tak żeby orientować się, czy klucz który wziąłem pasuje do tego teleportu na którym stoję - czy czy nie został zużyty wcześniej. Mogę trzymać w teleporcie kolor teleportu, choćby intem, stringiem czy czymkolwiek, mogę mieć wartość bool czy był zużyty, ale może można jakoś obiektowo ? Bo na tym mi głównie zależy.

1

Oj no co to za problem? Zrób sobie enuma z kolorami. Następnie zrób sobie dwa pola specjalne -> pole z teleportem i pole z kluczem. Player niech ma w sobie kolekcje zebarnych kluczy (kolekcje enumów).
applyEffects teleportu sprawdzi czy teleport na którym stoimy (który jest charakteryzowany przez enuma którego ma przypisanego) może być otwarty przez któryś z kluczy playera, tzn jakieś if(player.getKlucze().contains(this.kolor))
applyEffects pola z kluczem dorzuci klucz do kolekcji

Ja bym sie tu zastanowił nad inną ciekawą rzeczą -> bo model o którym pisałem wyżej zakłada że nie istnieją pola wielokrotnie specjalne. Tzn nie da się utworzyć pola które jednocześnie ma klucz i jeszcze sprawia że stoisz 2 kolejki. Gdyby miała istnieć taka możliwość to należałoby zrobić taki trochę kompozyt i zamienić to całe dziedziczenie na delegacje ;)

0

Następnie zrób sobie dwa pola specjalne -> pole z teleportem i pole z kluczem

Muszę dopytać - co rozumiesz poprzez pola specjalne ? Jak miałoby to wyglądać ?

Player niech ma w sobie kolekcje zebarnych kluczy (kolekcje enumów).

Kolekcje wnet poznam, a czy na ten moment może to być po prostu tablica ?

I jeszcze kwestia dotycząca losowania. Bo mówisz, żeby założyć tablicę obiektów i losować index, ale:
Będzie to musiało chyba być: Object t[] = {Teleport zółtyT, Teleport czerownyT, Klucz żółtyK, Klucz czerwonyK, Miecz miecz, Tarcza tarcza, Pole puste}.
Ale jeszcze gdybyśmy chcieli to trochę bardziej na bogato, tzn zawsze w momencie wylosowania teleportu (żółtego np.) musimy wylosować pole na którym postawimy (żółty) klucz. Tzn, że to nie jest wcale takie łatwe, ale powiem jak to widzę, żeby była pełna jasność.

Ale o tym opowiem jednak potem - najpierw czy możesz wyjaśnić wątpliwości które przedstawiłem u góry posta ?

PS Planuję mieć klasę Plansza. W niej po prostu atrybut (pole) będące macierzą (tablicą dwuwymiarową) Klasy Pole (u Ciebie Tile).
Ok ?

0
  1. Pole specjalne - oczywiście chodziło mi tu o dwie klasy dziedziczące po Tile ;)
  2. Nie, tablica raczej nie. Do tablicy nie dodaje sie nowych elementów tak łatwo ani się ich nie usuwa łatwo. Lista nadaje się lepiej.
  3. No już nie przesadzaj z tym losowaniem. To sobie zrób klase InstalatorTeleportu którą losujesz z tej tablicy a która to zajmuje się utworzeniem dwóch obiektów - teleportu i klucza. Szukasz problemów tam gdzie ich nie ma...
0

Ok, dzięki za pomoc. W tym temacie tyle. Założyłem nowy i w nim jeszcze parę rzeczy rozstrzygniemy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1