Schach (Konsole && OOP && Anfänger :p)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Karl
User
Beiträge: 252
Registriert: Freitag 29. Juni 2007, 17:49

Samstag 30. Juni 2007, 23:44

Also wie sich aus dem Titel ergibt, hab ich vor ein konsolenbasiertes Schachspiel zu machen. Ich hab gar nicht erst vor, sowas komplexes wie eine KI zu erstellen, sondern einfach ein Schachspiel, in dem beide Spieler ihre Züge machen können. Nichtmal über Netzwerk, weil ich noch relativ wenig Ahnung von Python hab und die ganzen Module nicht so kenn :p Aber ich denk das wird auch ohne so Zeug genug Arbeit.

Ich hab eigentlich auch noch fast nichts mit OOP gemacht (ich komm aus der PHP-Ecke) und bräuchte auch erstmal ein paar Hilfestellungen zum Aufbau.

Ich hab mir überlegt, eine Klasse für das Spielbrett zu machen, in der das Spielbrett erstellt wird, eine Klasse für die Spielfiguren, eine für die Spieler und eine, die alles zusammenfasst.
Praktisch:

Code: Alles auswählen

class ChessBoard:
        
class Player:

class Chessman:

class Chess:
Also die 1. Klasse, ChessBoard, stellt das Spielbrett als 2-Dimensionale Liste bereit, Eine Player-Instanz soll eben einen Player vertreten, dh ihr wird die Farbe und der Namen Zugewiesen, und ein Chessman bekommt eben eine Bezeichnung/Klassifizierung (König, Dame, Bauer, ...) und wird einem Spieler zugewiesen und hat vllt noch den Status living/dead.

Naja und die Klasse Chess soll das eben alles irgendwie zusammenfassen, also erstmal alles instanzieren und mithilfe der Instanzen und deren Methoden schön die ganzen Züge usw implementieren.

So hab ich mir das erstmal gedacht... Nur kommen mir da ein paar Probleme auf. Also irgendwie haben ja zB die Spielfiguren rein gar nichts mit dem Spielbrett zu tun? Wenn ich eine Spielfigur bewege, würde ich das ja so machen:
Ich rufe eine Methode von Chess auf, die eine Methode der Instanz von ChessBoard aufruft, welche einmal das Feld, auf dem die Figur stand auf unbesetzt setzt und das Feld, auf die sie gesetzt wird, mit der Figur belegt.

Mir kommt das halt irgendwie komisch vor, wenn die Figur gar nichts mit dem Spielbrett zu tun hat. Wie gesagt ich hab nicht viel erfahrung mit OOP ...


Gibt es vielleicht ein viel besseres Konzept? Ich bin dankbar für jeden Ratschlag ;)
Sry für die lange und eventuell langweilige Beschreibung!

Edit: Mir fällt grad auf, dass Ideen vielleicht nicht das richtige Forum war, sondern eher Allgemeine Fragen?
Es ist spät :p
Sorry.
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Sonntag 1. Juli 2007, 00:49

Eine einfache KI zu schreiben ist eigentlich nicht so ein Ding. Das mühsame am Schach ist es die ganzen Regeln zu implementieren. Für die KI brauchst du meistens noch einen weg einen Spiel stand zu bewerten.

Zur Implementierung, ich würde nicht versuchen das Problem mit einem Unmenge Klassen tot zu schlagen.

Das Schachfeld ist eine Liste, ob mehr oder eindimensional ist Geschmacks Sache. Die Figur Typen würde ich jeweils eine Klasse verwenden.

Für die Player braucht es meiner Meinung nach gar keine Klassen. Du musst in deinen Programmen nicht die Wirklichkeit 1:1 nachbauen.

Die Frage ist jetzt wie du die Regeln Implementierst. Du könntest diese ja in die Klasse der Figur packen. Dann verbleiben noch Züge wie die Rochade. wobei ich die Anfangs einfach weglassen würde.

Könnte dann so aussehen:
class Chess
- render/__str__
- move(x1, y1, x2, y2)
class Piece
- render/__str__
- canMove(x1, y1, x2, y2)
class Pawn(Piece):
....
;)

Könnte grob funktionieren ;)
BlackJack

Sonntag 1. Juli 2007, 10:10

Das Board würde ich schon als Klasse realisieren. Da kann man dann zum Beispiel `__getitem__` und `__setitem__` überschreiben und entweder über (Zeile, Spalte) auf ein Feld zugreifen, oder vielleicht gleich die schachüblichen Feldbezeichner 'A5' etc. erlauben. Ausserdem lässt sich dort auch ein Teil der Regeln unterbringen, die nicht auf einzelne Figuren beschränkt sind, zum Beispiel ob eine Rochade (noch) möglich ist, oder nicht.
Benutzeravatar
Michael Schneider
User
Beiträge: 567
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Bremen
Kontaktdaten:

Sonntag 1. Juli 2007, 10:47

Hallo,

meine Meinung ist inzwischen, dass man sich beim Verwenden vom objektorientierten Python den Grundsätzen der OOP zu- und denen der prozeduralen Programmierung abwenden sollte. Aus meiner Sicht ist eine Klasse für das Schachbrett Pflicht, da sich das Brett eben nicht nur die Figur-Positionsreferenzen kümmern, sondern auch Züge speichern sowie übergreifende Regeln UND Hilfsfunktionen verwalten muss. Hilfsfunktionen wären z.B. das Prüfen ob Rochade (noch) möglich ist, ob schach/matt vorliegt bzw. nach dem Zug vorliegen würde, ob ein Pfad zwischen zwei Feldern passierbar ist usw.
Dazu kann sich das Schachbrett freilich der Figurenmethoden bedienen, die deren Eigenheiten implementieren (wie weit ziehen, relevant ob Figuren dazwischen stehen, ...).

Das gleiche gilt für die Spieler. Deren Methoden werden von der Spielklasse verwaltet und steuert Namen, Zeiten, Punkte usw.

Man sollte immer darauf achten, dass Klassen und Methoden sinnvolle Umfänge behalten. Meiner Meinung nach sollten Methoden ein Schock Zeilen nur in Ausnahmefällen übersteigen, aber auch nicht nur aus der Rückgabe eines Attributwerts bestehen (außer in Ausnahmefällen).

Viel Glück. Wenn Du mit dem Konsolenprogramm fertig bist und ordentlich objektorientiert programmiert hast, dann solltest Du mit wenig Aufwand auch eine grafische Oberfläche mit wenig Aufwand hinzufügen können.

Grüße,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Sonntag 1. Juli 2007, 14:20

BlackJack hat geschrieben:Das Board würde ich schon als Klasse realisieren. Da kann man dann zum Beispiel `__getitem__` und `__setitem__` überschreiben und entweder über (Zeile, Spalte) auf ein Feld zugreifen, oder vielleicht gleich die schachüblichen Feldbezeichner 'A5' etc. erlauben. Ausserdem lässt sich dort auch ein Teil der Regeln unterbringen, die nicht auf einzelne Figuren beschränkt sind, zum Beispiel ob eine Rochade (noch) möglich ist, oder nicht.
Mit Chess meinte ich das Brett. Vielleicht wäre Chessboard der bessere Name gewesen.
Karl
User
Beiträge: 252
Registriert: Freitag 29. Juni 2007, 17:49

Sonntag 1. Juli 2007, 19:07

Hey danke für eure Antworten erstmal ;)
Also ich hab mich jetzt entschieden die Playerklasse rauszulassen, ihr habt recht, die hat ja eigentlich gar keinen Sinn.
Den Vorschlag, dass die Klasse, die für die Spielfiguren zuständig ist, sich um die Züge der Figuren zu kümmern hat, finde ich auch gut :)

Ich stell mir das jetzt wie folgt vor:

Code: Alles auswählen

class ChessBoard:
    # Kümmert sich um alle grundlegenden (!) Funktionen des Schachbretts
    # zB Move()

class Chessman:
    # Überprüft gültigkeit der Züge von Figuren allgemein (ist die Figur eine eigene Figur, oder ist der König bedroht, ...?
    # Subklassen (also alle Figurentypen) implementieren ihre Bewegungsart


class Chess:
    # Erstellt das Schachbrett mit den Figuren
    # Führt Züge aus
    # ... der ganze Rest :p
Also die Chessklasse erstellt das gesamte Spiel, wenn jetzt ein Zug ausgeführt werden soll, wird das über die Instanz von Chess gemacht und diese ruft die Instanz des Figurentyps auf, welche den Zug überprüft und wenn es gültig ist, trägt die Chessklasse das ganze in das Schachbrett ein, indem sie die Instanz des Schachbrettes benutzt.
Soweit ein brauchbares Konzept?

Michael Schneider hat ja einen völlig anderen Vorschlag, nämlich die Klasse ChessBoard die ganzen Überprüfungen übernehmen zu lassen.
Aber im Prinzip ist das doch egal, entweder ich verlagere das auf das Schachbrett oder auf die Figuren oder?
Harald Lüßen
User
Beiträge: 1
Registriert: Montag 2. Juli 2007, 08:43

Montag 2. Juli 2007, 09:14

Du hast dich für englische Begriffe entschieden. Gut, dann antworte ich
auch so. Das hilft auch beim googeln.

Üblicherweise findet man beim Computerschach diese Objekte und
Funktionen:

Board: Die Datenstruktur für das Schachbrett selbst, manchmal zusätzlich
mit weiteren Daten wie En-Passant-Möglichkeit, Rochaderechte, wer ist
am Zug. Man kann eine so erweiterte Klasse auch Position nennen.

Move: Eine kleine Struktur oder nur ein Integer mit den Infos: From, To,
Piece, NewPiece, CapturedPiece, MoveType und Flags. Hier kann man
kleine Hilfsfunktionen zum Lesen und Schreiben dieser Infos unterbringen.

MoveList: Eine Liste von Zügen, z.B. die im Spiel schon gemachten Züge
oder die in der Position möglichen Züge. Hier kann man Funktionen wie
das Durchsuchen der Zugliste nach bestimmten Zügen oder das
Herausgeben des jeweils nächsten Zugs implementieren.

Piece: Die gibt es als Klasse eher selten, meist sind die Figuren nur
Nummern auf dem Schachbrett. Wer mag, kann unter Piece die
Buchstabendarstellung oder ähnliches unterbringen. Zur Berechnung der
Bewegung braucht man ohnehin das Board und man faßt dabei auch oft
die Langschrittler (sliding pieces) zusammen. Deswegen sollte man das
nicht in eine Piece-Klasse tun.

Player oder Game: Die kann man zur Verwaltung seines Spiels und für das
Benutzerinterface des Programms verwenden. Innerhalb einer klassischen
chess engine sind sie eher ungewöhnlich.

Viele Funktionen erfordern eine Übersicht über alles oder sie kombinieren
die Infos. Dann packt man sie entweder in eine große Board/Position
Klasse oder man bringt sie gleich außerhalb aller Klassen unter. Zu diesen
Funktionen gehört z.B. der Zuggenerator, der zu einer Position die
möglichen Züge berechnet und sie in eine Zugliste packt. Andere Beispiele
sind eine ImSchach-Funktion oder eine KI/chess engine, aber die möchtest
du ja erstmal nicht bauen.

Vielleicht implementierst du die Hauptschleife deines Programms als eine
Art state machine. Soll es eine Zeitverwaltung oder Schachuhr geben?
Das könnten Klassen werden.

Nützlich wären Funktionen zur Behandlung von Eingaben im den Formaten
FEN oder EPD für Positionen und PGN für Partien.

Kennst du die GUIs mit der Winboard/Xboard oder UCI Schnittstelle?

Ich habe gerade die ganzen Links nicht parat, also bitte selber googeln.

Gruß, Harald
skypa
User
Beiträge: 97
Registriert: Freitag 5. Januar 2007, 03:13

Donnerstag 20. Dezember 2007, 13:11

Ich hatte vor geraumer Zeit auch ein Thread hier erstellt.
Es ging dabei auch um ein Schachspiel, ich habs aber halt mit GUI gemacht, schaus dir doch mal an ;)

http://www.python-forum.de/topic-9208.html?highlight=
Antworten