Laden...

OOP Schachprogramm: Herangehemsweise/Klassendesign

Erstellt von lousek vor 14 Jahren Letzter Beitrag vor 13 Jahren 10.493 Views
L
lousek Themenstarter:in
10 Beiträge seit 2009
vor 14 Jahren
OOP Schachprogramm: Herangehemsweise/Klassendesign

Hallo Forum.

Als Schularbeit muss ich ein Schach in C# programmieren (konnte das Projekt selbst wählen).

Ich weiss, dass es viele andere Beispiele im Internet bereits gibt und habe auch schon ausgiebig gesucht, aber irgendwie habe ich noch viele Knoten im Gedankenstrom.

Das Schach wird später nur Mensch gegen Mensch gespielt, also nichts mit KI.

Mit OOP hatte ich schon zu tun in JAVA, jedoch eigentlich ohne GUI.

Ich habe es mir irgendwie so vorgestellt:

class Spiel:
Spieler spieler1
Spieler spieler2
Spielbrett spielbrett

class Spieler:
String name
Color farbe

class Spielbrett: (evt. Spielbrett : Panel?)
Spielfeld[] spielfelder

class Spielfeld: (evt. Spielfeld : Button / pictureBox / UserControl?)
Spielfigur spielfigur
Color farbe
int X
int Y

abstract class Spielfigur:
Spieler spieler

class Bauer : Spielfigur:
Spieler spieler

class Turm : Spielfigur:
Spieler spieler

usw.

Aber wo muss ich die Züge definieren?
Macht das Sinn:

abstract class Zug:
int anfangX
int anfangY
int zielX
int zielY
abstract static public moeglicherZug(int anfangX, int anfangY, int zielX, int zielY);

class NormalerZug : Zug:
int anfangX
int ...
...

class Rochade : Zug:
...

class EnPassant : Zug:
...

Und dann ein Array mit allen möglichen Zügen für das ganze Spielbrett.
Beim ziehen wird dann mit moeglicherZug(...) geschaut, ob der übergebene Zug in den möglichen Spielzügen enthalten ist ... ?

Mir ist auch der "Zusammenhang" mit dem GUI resp. den Events noch nicht ganz klar.

Eigentlich müsste das Spielbrett ja gezeichnet werden, resp. die 64 Spielfelder im Array spielfelder.

Wenn ich jetzt auf eines dieser Spielfelder klicke wird ja ein Event (Click) aufgerufen.
Wie kann ich eine allgemeiner Event definieren, bei dem ich aber dennoch zwischen dem Spielfeld auf das geklickt wurde unterscheiden kann?

Versuch mit Buttons:

private void spielfeld_Click(object sender, EventArgs e)
{
    MessageBox.Show("Clicked: " + sender.ToString() + " ¦ " + e.ToString());
}

Die Spielfelder heissen spielfeld1, spielfeld2, spielfeld3, usw.
Bei allen habe ich (per GUI :S) diesen Event ausgewählt bei Click.
In der MessageBox steht für den Sender nachher aber nicht etwa spielfeld1 oder spielfeld49 sondern immer nur spielfeld (resp. chess6.spielfeld) ... wie weiss ich, auf welches Feld ich geklickt habe?

Naja .. Fragen über Fragen, ich hoffe, ihr könnt mir helfen 😉

Greetz, Lousek

4.207 Beiträge seit 2003
vor 14 Jahren

Ich versuch's mal zu erklären, wie ich da dran gehen würde. Das ist nicht der einzig mögliche Weg, und es mag schnellere / einfachere geben, aber um einen halbwegs sauberen Ansatz zu haben, würde ich wie folgt vorgehen:

Du brauchst:

Eine Datenstruktur für das Spiel: Hier würde ich mir vorstellen, dass es ein Spielbrett gibt, das seine Größe kennt, auf dem Figuren platziert werden (nur im Speicher, also erst mal alles ohne UI). Eine Figur kennt ihre Position, das Brett kennt alle Figuren, die noch auf ihm platziert sind.

Eine Engine: Diese kennt alle Regeln, wie zB ein Bauer darf nur 1 Feld vorwärts, ggf diagnoal schlagen; Turm darf beliebig weit horiziontal und vertikal ... ich würde mir vorstellen, dass man zB eine Funktion hat, die eine Figur und ein Ausgangsfeld erhält, und dann alle möglichen Zielfelder zurückgibt, und / oder eine Funktion, die eine Figur und ein Ausgangs- sowie ein Zielfeld erhält, und bestimmt, ob dies ein gültiger Zug wäre.

Darüber kommt eine Schicht, die Situationen erkennt, so was wie Schach, Schach matt, Gardé, etc ...

Darüber kommt als Schicht eine Spiellogik, die steuert, wer aktiv ist: Weiß oder schwarz, ggf Zeitmessung, solche Sachen.

Und ganz darüber kommt dann die UI. Das kann eine Windows-Anwendung sein, eine Konsolenanwendung, eine Webanwendung, whatever...

Wichtig ist, dass jede Schicht immer nur auf die darunterliegende zugreift, nie umgekehrt. Sprich, die UI gibt nur Befehle nach unten und erhält direkte Ergebnisse, aber es wird nie die UI direkt von einer anderen Schicht aufgerufen. Falls das doch notwendig sein sollte, müssen Events angeboten werden, an die sich die UI ihrerseits subscribed.

Viele Grüße,

Golo

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

185 Beiträge seit 2005
vor 14 Jahren

hallo,

wie du dir vorstellen kannst, ist es nicht ganz einfach, dir da eine antworz zu geben, da man das problem ja auf verschiedene arten lösen kann - das ist wohl auch der sinn der aufgabe: sich damit beschäftigen + eine lösung finden.

Ich würde hier jedoch mal so vorgehen, dass das Spielfeld ein z.B. Array mit 8x8 Felder ist - mit Werten einer Enum "Figur". Die Spiellogik sollte auf diesem Array operieren, NICHT mit dem Gui.

Als Gui würde ich auch keinen enzelnen Felder (Buttons?) verwenden, sondern eine Spielfläche zeichnen, als Bild, und beim Mausklick aufgrund der Koordinaten berechnen, auf welches Feld geklickt wurde. Dieses dann noch umrechnen, welchem Arrayfeld es entspricht sollte einfach sein und schon weißt du, auf welche Figur geklickt wurde.

Was ist überhaupt Aufgabe des Spiels?
Sollen mögliche, gültige Züge angezeigt werden?

Dann würde ich so vorgehen, dass man 1. eine Methode definiert, um 1 Figur um 1 Feld in jede Richtung zu bewegen. Danach für jede Figur die möglichen Zugfolgen usw.

fg
hannes

4.207 Beiträge seit 2003
vor 14 Jahren

Wenn Du einen ganz abgedrehten, aber auch kompakten und eleganten Ansatz haben willst: Du könntest Schach als Domain Specific Language implementieren 😉.

Oslo und M lassen grüßen 😉

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

1.346 Beiträge seit 2008
vor 14 Jahren

@HannesB

Für eine Figur eignet sich meiner Ansicht nach eine Klasse besser. Woher willst du wissen( ohne solche dummen sachen wie Enum.SchwarzKönig) zu welcher Farbe er gehört? Woher willst du wissen, an welcher Position er sich befindet?

Gruß pdelvo

1.696 Beiträge seit 2006
vor 14 Jahren

Hallo,

eigentlich ist das [Hinweis] Wie poste ich richtig? Punkt 4, baer du kannst gern hier nachgucken: http://www.codeproject.com/KB/game/SrcChess.aspx

Ich bin verantwortlich für das, was ich sage, nicht für das, was du verstehst.

**:::

L
lousek Themenstarter:in
10 Beiträge seit 2009
vor 14 Jahren

@GoloRoden:

Das mit den Schichten verstehe ich, aber wie realisiert man sowas (Stichwörter)?
Wie werden die verschiedenen Schichten erstellt / abgetrennt?

4.207 Beiträge seit 2003
vor 14 Jahren

Im Extremfall:

Jede Schicht in ein eigenes Projekt und damit in eine eigene DLL.

Und immer schön jede Schicht so entwickeln, dass sie Abhängigkeiten nur nach unten hat.

Was für Dich noch interessant sein dürfte: Stichwort "Microkernel", siehe auch http://www.des-eisbaeren-blog.de/post/2009/03/13/Microkernel-im-Eigenbau.aspx

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

L
lousek Themenstarter:in
10 Beiträge seit 2009
vor 14 Jahren

Naja ... vieleicht habe ich es doch nicht so verstanden 😉

Meinst du mit diesen Schichten etwas wie das hier?
http://code-inside.de/blog/2008/07/09/howto-3-tier-3-schichten-architektur/

4.207 Beiträge seit 2003
vor 14 Jahren

Ja, das geht in die Richtung.

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

L
lousek Themenstarter:in
10 Beiträge seit 2009
vor 14 Jahren

Sorry wenn ich schwer von Begriff bin, aber ich sehe irgendwie nicht, WIE ich das realisieren soll :S

5.942 Beiträge seit 2005
vor 14 Jahren

Hallo lousek

Eine Schicht besteht aus mehreren Typen, die schlussendlich eine öffentliche Schnittstelle ergeben.
Diese Schnittstelle darf nur von der oben liegenden Schicht benutzt werden und so weiter.

So hast du weniger Abhängigkeiten, kannst Schichten austauschen, etc..

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

5.942 Beiträge seit 2005
vor 14 Jahren

Hallo lousek

Sorry wenn ich schwer von Begriff bin, aber ich sehe irgendwie nicht, WIE ich das realisieren soll :S

Vielleicht hast du dir zuviel vorgenommen.

Die Vorschläge von Golo sind sicherlich auch zu anspruchsvoll für den Anfang.
Bitte lies den Hinweis von vbprogger durch. Wenn du dann konkrete Fragen hast, helfen wir dir gerne.

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

L
lousek Themenstarter:in
10 Beiträge seit 2009
vor 14 Jahren

Ich glaube, im Moment ist mir das mit diesen Schichten noch zu viel (bin eigentlich Systemadmin und nicht Entwickler ... muss das in der Schule machen).

Was mir wohl auch noch nicht ganz klar ist:
Bei einer Ablauf-Orientierter Programmiersprache wird ja eigentlich Zeile für Zeile abgearbeitet.
Kann man sagen, dass die Objekt-Orientierte Programmierung (so wie ich sie gerade brauche) auf Ereignisse reagiert (z.B. Maus-Klick)?

Wie ist mein Ansatz mit den Klassen, den ich am Anfang geschrieben habe, sprich was kann ich besser machen?

Also muss ich eigentlich nur auf die Klick-Events von den Buttons / Spielfeldern reagieren und dort drin schauen, ob der Zug möglich ist oder nicht und ihn dann ggf. ausführen? Auf die Events müsste ich in der Klasse Spielbrett, da dieses alle Spielfelder kennt?

Gruss
Lousek

2.187 Beiträge seit 2005
vor 14 Jahren

Hallo lousek,

Die Events sind nur ein Hilfsmittel der Objektorientierung.
Grob gesagt geht es bei Objektorientierung darum
A) Dinge der Realenwelt direkt im Programm abzubilden (z.B. ist ein Auto in einem Rennspiel ein Objekt, genau wie in der realen Welt).
B) Informationen zu Kapseln (also z.B. das Auto-Objekt kann dir sagen, ob es los fahren kann (auto.KannFahren()), was das Auto jetzt alles prüfen muss um true zurück zu geben ist "außen" völlig egal, es ist weg gekapselt).

Übertragen auf das Schachspiel:
A) Objekte ermitteln (z.B. scharzer Spiler1, weißer Spiler, Schachbrett, schwarzer Bauer 1, weiße Dame 1, etc.)
B) Ermitteln was die Einzelnen Objekte kapseln (z.B. Schabrett weiß Laenge und Breite, schwarzer Bauer 1 weiß seine Position und dass er immer nur einen Schritt nach vorn machen darf, etc.)

Das ist jetzt nur ein Vorschlag, man könnte es auch ganz anders aufteilen.

(Achtung! hier war/ist noch keine GUI mit drinen, die gibt's noch mal extra und diese wiedrum Kapselt wie die ganzen Objekte auf dem Bildschirm dargestellt werden.)

Als einfachsten Anfang kann ich dir Empfehlen das ganze einfach als Text aufzuschreiben (also wie man Schach spielt) oder so einen Text aus dem INet zu suchen und dann eine Dokumentenanalyse zu machen:

  1. Alle Nomen werden zu Objekten
  2. Alle Verben werden zu Methoden
  3. Die Methoden den Objekten zuordnen (m zu n)
  4. Die Objekte zusammen fassen zu Gruppen (=Klassen)

und schon hat man ein halbwegs brauchbares Klassenmodel, dass man auch besprechn könnte.

Gruß
Juy Juka

185 Beiträge seit 2005
vor 14 Jahren

hallo,

sorry + das ist jetzt nicht böse/gemein gemeint, aber ich denke für den Anfang ist ein solches Projekt zu komplex. Wenn man soetwas ordentlich implementieren möchte, ist imho. einiges an Wissen in OOP, Patterns, Schichtenmodellierung, GUI-Patterns usw. nötig.

Wundert mich, dass du soetwas i.d. Schule machen sollst - ich habe auch (vor einigen Jahren) EDV Htl gemacht + die Übungsbeispiele warn da am Anfang weit nicht so komplex.

Alleine der Ansatz "auf die Klick Events" reagieren und dort Logik impl. wäre gem. MVC oder MVP Patterns eigentlich schon der falsche Weg.

Wenn es sein MUSS, würde ich mir ein funktionierendes Sample suchen und schaun, wie es darin gelöst ist - dabei lernst du aber nichts.

Du bist Sysadmin?
Da hast du sicher nicht damit begonnen, ein hetrogenes Netzt mit > 500 Arbeitsstationen, Routern, VPN dazwischen u.v.a. aufzusetzen, ohne zu wissen, was TCPIP, LAN, Ethernet, Switch usw. sind.
Hier ist die Problematik imho. ähnlich.

@pdelvo: stimmt.

fg
hannes

L
lousek Themenstarter:in
10 Beiträge seit 2009
vor 14 Jahren

Stimmt, so habe ich nicht angefangen und bin wohl auch noch ein Weilchen nicht so weit, bin erst im 2. Lehrjahr 😉

Aber so ein Schach kann man doch auch ohne Schichten usw. programmieren ... klar ist es nicht der "professionelle" Weg eines Applis, aber der würde wohl ein Netzwerk auch nicht gerade mit allen Schikanen versehen wenn er eines aufbauen müsste 😉

Ich werde es einfach versuchen, das hat noch niemandem geschadet, und es ist besser wie nichts, auch vom Lernen her.

Naja ... bin gerade ein solches Sample am angucken 😉 Das hat wohl auch 2 Schichten ... das GUI und der Rest ...

Greetz, Lousek

1.002 Beiträge seit 2007
vor 14 Jahren

Hallo lousek,

Aber so ein Schach kann man doch auch ohne Schichten usw. programmieren ...

natürlich kannst du. Du kannst auch einen Nagel mit einer Säge in die Wand schlagen. Oder einem Schraubenzieher. Du kannst aber auch den Hammer verwenden, das Werkzeug, das dafür vorgesehen ist.

Mal abgesehen davon: Will euer Lehrer, dass ihr eine gut strukturierte OO-Anwendung entwickelt? Oder will er sehen, dass ihr vom Umfang über "Hello World!" hinauskommt? Oder sehen, dass ihr beginnt, größere Projekte in C# anzugehen? Projektmappen und Projekte in Visual Studio zu bedienen?

m0rius

Mein Blog: blog.mariusschulz.com
Hochwertige Malerarbeiten in Magdeburg und Umgebung: M'Decor, Ihr Maler für Magdeburg

2.760 Beiträge seit 2006
vor 14 Jahren

(Aber wenn man einen schönen neuen Hammer hat dann wird auch jedes Problem gleich zum Nagel Sorry der musste jetzt kommen 😉

1.002 Beiträge seit 2007
vor 14 Jahren

Hallo jaensen,

... worin z.B. das Problem des Pattern-auf-Teufel-komm-raus-Suchens besteht 😃.

m0rius

Mein Blog: blog.mariusschulz.com
Hochwertige Malerarbeiten in Magdeburg und Umgebung: M'Decor, Ihr Maler für Magdeburg

L
lousek Themenstarter:in
10 Beiträge seit 2009
vor 14 Jahren

Naja ... unser Lehrer weiss von OOP nicht mehr wie ich mit meinem jetztigen Wissensstand ... so kommt es mir zumindest vor.

Eigentlich sollte es einfach ein C#-Projektchen sein ...

Greetz, Lousek

4.207 Beiträge seit 2003
vor 14 Jahren

Was Du natürlich als supersimpeltrivial-Lösung machen kannst:

64 Buttons auf eine Form, 32 davon weißer Hintergrund, 32 schwarzer Hintergrund. Als Text steht dann irgendwas drauf, welche Figur dort steht, zB "Turm sz", "Läufer ws", etc ...

Klickt man da drauf, merkt er sich in einer Variablen, welches Feld angeklickt wurde, klickt man auf den nächsten Button, läuft halt die Schachlogik ab (prüfen, ob der Zug gültig wäre, ggf vorhandene Figur schlagen).

Mehr nicht.

Vielleicht noch implementieren, dass nur abwechselnd gezogen werden kann.

Aber prinzipiell war's das dann schon.

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo lousek,

auch wenn es sich bei dir nicht um ein ganz kleines Programm dreht, finden sich in Richtige Herangehensweise - kleine Programme schreiben einige weiterführende Links, die für dich sicher interessant sein werden.

herbivore

888 Beiträge seit 2007
vor 13 Jahren
L
lousek Themenstarter:in
10 Beiträge seit 2009
vor 13 Jahren

Halo Forum,

Ich glaube der Beginn dieses Thread ist nun schon über ein Jahr her 😉
Das funktioniert, inklusive Rochade, Austausch eines Bauers zu Dame / Läufer / Turm / Springer, Schachmatt und Pat 😃 Als Note gab es eine 5.5 (Schweiz; bei euch wäre das eine 1.5?)

Ich denke, der Thread kann geschlossen werden 😉

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo lousek,

du siehst ja selbst, dass noch nach über einem Jahr der Wunsch auftauchen kann, eine Ergänzung zu posten. Daher schließen wir Threads auch nicht, nur weil sie erledigt sind.

herbivore

888 Beiträge seit 2007
vor 13 Jahren

@lousek,

kannst du uns Dein Werk mal vorstellen, vielleicht unter Projekte posten?