Entwickler-Ecke

Algorithmen, Optimierung und Assembler - OOP Ansatz für bestimmte Karten aus Stapel ziehen


Flamefire - Do 30.09.10 13:04
Titel: OOP Ansatz für bestimmte Karten aus Stapel ziehen
Folgende Situation:
Eine Klasse TDeck hat Karten. Jetzt will ich daraus eine Karte ziehen, die bestimmten Bedingungen genügt. Dafür habe ich 2 weitere Klassen: TRequest (Enthällt die Bedingungen) und THand (die soll die Karte dann kriegen)
Eine beliebige zufällige Karte ziehen ist einfach: Zufallszahl z=0..Kartenzahl-1 und dann die Karte an Index z nehmen.
Mit den Bedingungen wird das schwerer. Idee war, aus den verbleibenden Karten einen neuen Stapel zu erstellen (Als Methode von TDeck mit einem Parameter der TRequest Klasse und einer TRequest.MatchCondition(TCard) Methode) und aus dem Stapel dann eine Karte zu ziehen, die aus dem UrsprungsStapel entfernen und dann den erstellten Stapel zu löschen.
Das erscheint mir aber recht umständlich und unperformant.

Hat da jemand noch eine bessere Idee?


glotzer - Do 30.09.10 18:24

jede karte als TKarte verwenden. verwaltung mit TObjectList, bei bedarf daraus löschen/einfügen


Martok - Do 30.09.10 19:34

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
Idee war, aus den verbleibenden Karten einen neuen Stapel zu erstellen (Als Methode von TDeck mit einem Parameter der TRequest Klasse und einer TRequest.MatchCondition(TCard) Methode) und aus dem Stapel dann eine Karte zu ziehen, die aus dem UrsprungsStapel entfernen und dann den erstellten Stapel zu löschen.

So würde ich es in JS machen und so habe ich es auch schon in Delphi gebaut, z.B. bei der Maperstellung für diverser Spiele die du ja kennst: Kandidaten in eine Liste schreiben, Liste mischen, die ersten n Elemente auswählen.


JS
1:
2:
3:
var card = deck.match(new Request(color_spades,is_face_card)).shuffle().subset(1)[0];
deck.remove(card);
card.showToUser()


Wenn man das wirklich so massive ver-OOP-en will wird wohl nicht viel anderes übrig bleiben. Man kann das vermutlich noch so optimieren, dass man in Delphi kein echtes Temporär-Deck baut, sondern eine Methode hat die eben dies Intern tut, á la TDeck.GetCard(Request:TRequest). Diese könnte dann Intern lediglich ein Array führen der Indizes, die die Kriterien erfüllen.


Pseudocode
1:
2:
3:
4:
5:
6:
7:
8:
möglich = leeres Array
für jede Karte
  wenn Karte erfüllt Kriterien dann
    möglich += Kartenindex
wenn möglich enthält Elemente dann
  return Karten[wähle zufällig aus möglich]
sonst
  return "keine karte gefunden"

Moment. Das ist einfacher als der Originalvorschlag und damit genau das was du gefragt hast :P


Tryer - Do 30.09.10 19:40

Wie sieht denn so ein Request beispielsweise aus?

Vielleicht machen durchgehend gepflegte Indextabellen für jeden Request Sinn?
Die Karten wären in jeder treffenden Tabelle eingetragen und das Entnehmen der Karte meldet an TDeck und darüber an alle anderen Tabellen das die Karte raus ist. Wenn nicht zuviel Karten im Deck sind könnte das ganze über Sets laufen wo sich auch leicht Schnittmengen bilden lassen.

Grüsse, Dirk


Flamefire - Do 30.09.10 22:48

Request ist sowas wie: Karte mit Wert >=5 und ungleich 7

Ich denke die Methode mit dem internen Array macht noch am meisten Sinn. Ich probiers damit ;)


Kha - Do 30.09.10 23:00

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
Request ist sowas wie: Karte mit Wert >=5 und ungleich 7
Warum denn kein TPredicate<TCard> dafür :) ?


Flamefire - Do 30.09.10 23:08

Weil nicht alle Werte feststehen. Z.b. Suche 2 Karten mit bestimmten Eigenschaften, die ungleich sind

Im Prinzip wird es ja sowas ähnliches. Nur Optimiert ;)