Ich versuche ein Gefühl dafür zu bekommen, wie man objektorientiert gestaltet und denkt, und möchte ein Feedback von der Community zu diesem Thema erhalten. Das Folgende ist ein Beispiel für ein Schachspiel, das ich auf OO-Weise entwerfen möchte. Dies ist ein sehr umfassendes Design, und ich konzentriere mich in dieser Phase nur darauf, herauszufinden, wer für welche Nachrichten verantwortlich ist und wie die Objekte miteinander interagieren, um das Spiel zu simulieren. Bitte weisen Sie darauf hin, ob es Elemente mit schlechtem Design gibt (hohe Kopplung, schlechte Kohäsion usw.) und wie Sie diese verbessern können.
Das Schachspiel hat die folgenden Klassen
- Tafel
- Spieler
- Stück
- Quadrat
- Schachspiel
Das Board besteht aus Quadraten, sodass das Board für die Erstellung und Verwaltung von Square-Objekten verantwortlich gemacht werden kann. Jedes Stück befindet sich auch auf einem Quadrat, sodass jedes Stück auch einen Verweis auf das Quadrat hat, auf dem es sich befindet. (Macht das Sinn?). Jedes Stück ist dann dafür verantwortlich, sich von einem Feld zum anderen zu bewegen. Die Spielerklasse enthält Verweise auf alle Teile, die er besitzt, und ist auch für deren Erstellung verantwortlich (Sollte der Spieler Teile erstellen?). Der Spieler hat eine Methode takeTurn, die wiederum eine Methode movePiece aufruft, die zur Stückklasse gehört, die die Position der Figur von ihrer aktuellen Position an eine andere Position ändert. Jetzt bin ich verwirrt darüber, wofür genau die Board-Klasse verantwortlich sein muss. Ich nahm an, dass es notwendig war, um den aktuellen Status des Spiels zu bestimmen und zu wissen, wann das Spiel vorbei ist. Aber wenn ein Stück es ändert ' s Ort wie soll das Board aktualisiert werden? Sollte es eine separate Anordnung von Quadraten beibehalten, auf denen Teile vorhanden sind und die aktualisiert werden, wenn sich Teile bewegen?
Außerdem erstellt ChessGame zunächst die Brett- und Spielerobjekte, die wiederum Quadrate bzw. Steine erstellen und die Simulation starten. Kurz gesagt, so könnte der Code in ChessGame aussehen
Player p1 =new Player();
Player p2 = new Player();
Board b = new Board();
while(b.isGameOver())
{
p1.takeTurn(); // calls movePiece on the Piece object
p2.takeTurn();
}
Ich bin mir nicht sicher, wie der Status des Boards aktualisiert wird. Sollte das Stück einen Verweis auf die Tafel haben? Wo soll die Verantwortung liegen? Wer hat welche Referenzen? Bitte helfen Sie mir bei Ihren Eingaben und weisen Sie auf Probleme bei diesem Entwurf hin. Ich konzentriere mich bewusst nicht auf Algorithmen oder weitere Details des Spiels, da ich mich nur für den Designaspekt interessiere. Ich hoffe, diese Community kann wertvolle Erkenntnisse liefern.
takeTurn()
wenn der Zug von p1 das Spiel beendet. Weniger pingeliger Kommentar: Ich finde es natürlicher, die Spieler anzurufenwhite
undblack
.canMove()
Funktion verwendet. Und wenn der Umzug abgeschlossen ist, aktualisieren alle anderen Teile ihre eigene innere Kopie des Bretts. Ich weiß, dass es nicht optimal ist, aber es war zu dieser Zeit interessant, C ++ zu lernen. Später sagte mir ein Freund eines Nicht-Schachspielers, dass erclasses
für jedes Feld statt für jede Figur haben würde. Und dieser Kommentar kam mir sehr interessant vor.Antworten:
Ich habe gerade eine vollständige C # -Implementierung eines Schachbretts, von Figuren, Regeln usw. geschrieben. Hier ist ungefähr, wie ich es modelliert habe (die tatsächliche Implementierung wurde entfernt, da ich nicht den ganzen Spaß aus Ihrer Codierung herausholen möchte ):
Die Grundidee ist, dass Game / Board / etc einfach den Status des Spiels speichert. Sie können sie manipulieren, um beispielsweise eine Position einzurichten, wenn Sie dies möchten. Ich habe eine Klasse, die meine IGameRules-Schnittstelle implementiert, die verantwortlich ist für:
Wenn Sie die Regeln von den Spiel- / Brettklassen trennen, können Sie Varianten auch relativ einfach implementieren. Alle Methoden der Regelschnittstelle verwenden ein
Game
Objekt, das sie überprüfen können, um festzustellen, welche Bewegungen gültig sind.Beachten Sie, dass ich keine Spielerinformationen auf speichere
Game
. Ich habe eine separate KlasseTable
, die für das Speichern von Spielmetadaten zuständig ist, z. B. wer gespielt hat, wann das Spiel stattgefunden hat usw.BEARBEITEN: Beachten Sie, dass der Zweck dieser Antwort nicht darin besteht, Ihnen einen Vorlagencode zu geben, den Sie ausfüllen können. In meinem Code sind tatsächlich ein bisschen mehr Informationen zu jedem Element, mehr Methoden usw. gespeichert. Der Zweck besteht darin, Sie zum Thema zu führen Ziel, das Sie erreichen wollen.
quelle
Move
ist eine Klasse, mit der Sie den gesamtenGame
Delgieren an einen Implementierer vonIGameRules
oder erzwingen Sie Regeln außerhalb des Objekts? Letzteres scheint unangemessen, da das Spiel seinen eigenen Zustand nicht schützen kann, nicht wahr?Hier ist meine Idee für ein ziemlich einfaches Schachspiel:
quelle
Ich habe kürzlich ein Schachprogramm in PHP erstellt ( Website hier klicken , Quelle hier klicken ) und es objektorientiert gemacht. Hier sind die Klassen, die ich verwendet habe.
generate_legal_moves()
Code hier eingegeben . Diese Methode erhält eine Karte, die an der Reihe ist, und einige Variablen, um den Detaillierungsgrad der Ausgabe festzulegen, und generiert alle rechtlichen Schritte für diese Position. Es wird eine Liste von ChessMoves zurückgegeben.int
s.Ich versuche gerade, diesen Code in eine Schach-KI umzuwandeln, daher muss er SCHNELL sein. Ich habe die
generate_legal_moves()
Funktion von 1500 ms auf 8 ms optimiert und arbeite noch daran. Die Lehren, die ich daraus gezogen habe, sind ...int
Möglichkeit primitive Typen . Aus diesem GrundChessSquare
speichert Rank and File alsint
, anstatt auch eine alphanumerische Zahlstring
mit lesbarer Schachquadratnotation wie "a4" zu speichern .Ich weiß, dass das alt ist, aber hoffentlich hilft es jemandem. Viel Glück!
quelle