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
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
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
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
@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
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
**:::
@GoloRoden:
Das mit den Schichten verstehe ich, aber wie realisiert man sowas (Stichwörter)?
Wie werden die verschiedenen Schichten erstellt / abgetrennt?
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
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/
Ja, das geht in die Richtung.
Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden
Sorry wenn ich schwer von Begriff bin, aber ich sehe irgendwie nicht, WIE ich das realisieren soll :S
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
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
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
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:
und schon hat man ein halbwegs brauchbares Klassenmodel, dass man auch besprechn könnte.
Gruß
Juy Juka
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
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
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
(Aber wenn man einen schönen neuen Hammer hat dann wird auch jedes Problem gleich zum Nagel Sorry der musste jetzt kommen 😉
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
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
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
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
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 😉
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
@lousek,
kannst du uns Dein Werk mal vorstellen, vielleicht unter Projekte posten?