Ich habe das nächste Problem.
Ein Gegenstand kann viele Zustände haben:
NORMAL = 0000000
DRY = 0000001
HOT = 0000010
BURNING = 0000100
WET = 0001000
COLD = 0010000
FROZEN = 0100000
POISONED= 1000000
Ein Gegenstand kann einige Zustände gleichzeitig haben, aber nicht alle
- Es ist unmöglich, gleichzeitig trocken und nass zu sein.
- Wenn Sie einen NASS-Gegenstand KALTEN, wird er zu GEFROREN.
- Wenn Sie ein WET-Element HEISSEN, wird es zu NORMAL
- Ein Gegenstand kann BRENNEN und GIFT sein
Usw.
Ich habe versucht, binäre Flags auf Zustände zu setzen und AND zu verwenden, um verschiedene Zustände zu kombinieren, bevor ich prüfe, ob dies möglich ist oder nicht, oder um in einen anderen Status zu wechseln.
Gibt es einen konkreten Ansatz, um dieses Problem effizient zu lösen, ohne einen endlosen Schalter zu haben, der jeden Zustand mit jedem neuen Zustand überprüft?
Es ist relativ einfach, zwei verschiedene Zustände zu überprüfen, aber wenn es einen dritten Zustand gibt, ist dies nicht trivial.
c++
rpg
design-patterns
binary
vgonisanz
quelle
quelle
Antworten:
Wenn ich Flags verwenden muss, mache ich normalerweise etwas in diese Richtung.
Dies macht die Verwendung für Dinge wie apply_cold () sehr einfach und Sie können offensichtlich in Ihrem Zustand Bedingungen wie trocken und nass bauen.
quelle
Zwei Beobachtungen:
COLD
undHOT
sind Übergänge in der Art, wie Sie sie erwähnen, keine Zustände.Die Kombination dieser Beobachtungen würde zu ungefähr folgendem Ergebnis führen:
quelle
Indem Sie Ihre Zustände als Bitmaske darstellen, wie Sie sie schreiben, können Sie einfach Ihre Beschreibungen der Einschränkungen in Code übersetzen:
Sie könnten das in eine einwickeln
makeStateConsistent()
das Sie aufrufen können, bevor Sie die Statusbits testen, um sicherzustellen, dass der Status sinnvoll ist.Eine Einschränkung dieses Ansatzes besteht jedoch darin, dass die Reihenfolge der Statusänderungen nicht berücksichtigt werden kann. Wenn Sie beispielsweise für heiße Gegenstände, die nass werden, ein anderes Ergebnis erzielen möchten als für nasse Gegenstände, die heiß werden, können Sie dies nicht so tun: Die
makeStateConsistent()
Methode sieht nur ein heißes und nasses Objekt ohne Informationen darüber, wie es muss so sein.Statt dessen, was Sie tun können , ist das Einzelteil Zustand privaten (zumindest vom Konzept her ) und manipulieren , um sie durch eine Reihe von Methoden wie
coolItem()
,heatItem()
,wetItem()
,dryItem()
und so weiter. Auf diese Weise können die Zustandsänderungsmethoden selbst zusätzliche Änderungen vornehmen. DieheatItem()
Methode könnte beispielsweise folgendermaßen aussehen:Natürlich möchten Sie vielleicht auch noch eine haben
makeStateConsistent()
Methode als Backup haben, falls Sie einen Fehler in Ihren Statusänderungsmethoden haben.In einigen Fällen können Sie Ihren Code möglicherweise auch vereinfachen, indem Sie unnötige Zustände beseitigen. Benötigen Sie zum Beispiel wirklich einen separaten
FROZEN
Zustand, oder würde es ausreichen, nur kalte und nasse Gegenstände als gefroren zu behandeln?quelle