#pydesw: Programmierung eines Brettspiels

Du hast eine Idee für ein Projekt?

Welches Brettspiel soll programmiert werden?

Umfrage endete am Montag 20. Februar 2017, 16:25

Mühle
6
75%
Dame
2
25%
etwas anderes (bitte im Thread vorschlagen)
0
Keine Stimmen
 
Insgesamt abgegebene Stimmen: 8
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Hallo zusammen,

die neueste Idee für ein gemeinsames Programmier-Projekt ist die Umsetzung eines einfachen Brettspiels. Vorgeschlagen wurde bisher Dame oder Mühle. Hier sollten zunächst die Rollen "Design / GUI" (1), "Implementierung des Regelwerks / API für Spielablauf" (2) und "Programmierung des Computergegners (KI)" (3) besetzt werden. Außerdem muss am Ende natürlich alles zusammengebracht werden.

Grobe Abhängigkeiten

* Von der Rolle "Design / GUI" sollte eine Schnittstelle zum Setzen, Bewegen und Schlagen von Steinen erstellt werden. Der GUI-Anteil dieser Rolle stellt die Abbildung des Designs dar (Zeichnen des Bretts und der Steine). Hier sollte außerdem auf Maus- und Tastatur-Events gehorcht werden (denkbar wäre das Ziehen von Steinen auf die neue Position via Drag & Drop und/oder das Verschieben der Steine mittels Pfeiltasten auf der Tastatur). Die Events sollten als Spielzüge interpretiert und diese Spielzüge an die Logik übergeben werden. Nach einem erfolgreichen Spielzug sollte die GUI sich die veränderte Spielsituation aus der Logik abrufen (möglicherweise wurde ein gegnerischer Stein geschlagen) und die neue Situation grafisch darstellen.

* Die eigentliche Spiellogik hat Infos zur Belegung aller Felder und zu den bisher geschlagenen Steinen. Die grafische Umsetzung erfolgt durch entsprechende Aufrufe seitens der Design-API. IMHO sollte die Logik sich passiv verhalten und nur auf Anforderungen reagieren, d.h. sie selbst tätigt keine Aufrufe von anderen Komponenten. Die Logik meldet dem Aufrufer außerdem per Exception zurück, falls ein Spielzug nicht erlaubt ist. Die Folgen eines Spielzuges (neue Feldbelegung, Entfernen geschlagener Steine) berechnet die Logik selbständig und stellt die veränderte Spielsituation zum Abruf durch den Aufrufer bereit. Die Logik sollte außerdem ein eigenes Signal/Event aussenden können, um eine Änderung der Spielsituation zu signalisieren. Mit diesem Signal ist die GUI (und vielleicht später etwas anderes) verbunden, damit die Änderung abgebildet werden kann. Ein weiteres Signal sollte abbilden, dass jetzt Spieler XY (Computer oder Mensch) dran ist, um eine lose Kopplung zu gewährleisten.

* Die KI muss die Besetzung aller Felder mit den Steinen beider Spieler abrufen können. Sie muss außerdem ihre eigenen Steine setzen und bewegen können sowie die Steine des Gegners schlagen können. Wenn die KI einen Zug durchführen möchte, dann sollte dies mit dem entsprechenden Aufruf bei der Logik-API erfolgen. Sie sollte außerdem auf eine mögliche Exception vorbereitet sein (auch eine KI kann Fehler machen). Während der menschliche Gegner an der Reihe ist, könnte die KI schon die neue Spielsituation abrufen. Ich glaube aber, dass es für den Anfang reicht, wenn die Berechnungen erst nach dem neuen Spielzug des menschlichen Gegners gemacht werden und dementsprechend erst dann die neue Feldbelegung durch die KI abgerufen wird. Die KI "weiß", wann sie wieder an der Reihe ist, indem sie auf das oben genannte Signal der Logik lauscht.

___________________________________________________________________________________________________________________

Das wären so meine Einfälle, die sicherlich noch detailliert ausgearbeitet werden müssten. Wichtig ist auch (adressiert an die Interessenten): Seid ihr eher für Dame oder für Mühle? Ich persönlich tendiere zu Mühle, hätte aber auch kein Problem damit, wenn sich die Mehrheit für Dame entscheidet. Hierzu habe ich eine Umfrage erstellt, die 7 Tage laufen wird.

PS: Natürlich sind schon jetzt Kritik und Verbesserungsvorschläge (am besten hier im Thread) gern gesehen... :)
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Für einen besseren Überblick zitiere ich mal aus einem anderen Thread einen Beitrag mit ein paar guten Ideen und einem sicherlich hilfreichen Link zu den Spielregeln:
Pygoscelis papua hat geschrieben:Da wir merken, dass schon ein spiel wie Jump'n'Run zu kompliziert und vor allem zu
unkonkret ist dachte ich mir, das es keine schlechte Idee ist Mühle zu programmieren.
Dort haben wir die Regeln schon klar vorgegeben, müssen uns jetzt noch um folgendes kümmern:
- Gui: vermutlich Pygame
- Pythonversion war eigentlich schon als 3.4 festgelegt oder liege ich da falsch?

Mein Vorschlag fürs weitere vorgehen:
- Spielregeln zusammenfassen, bzw. durchgehen und klar stellen welche verwendet werden
(keine Ahnung ob es im Netz verschiedene gibt)
- Klassendiagramm/Plan woraus das Spiel besteht erstellen
- Meilensteine festlegen
...
- fehlt hier noch was???
...
- mit programmieren loslegen???

hier ein denke ich sinnvoller link für die Regeln: http://www.brettspielnetz.de/spielregeln/muehle.php
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@Pygoscelis papua:
1) Sollen wir wirklich Python 3.4 verwenden? Python ist inzwischen bei Version 3.6 (war zum Zeitpunkt unserer Entscheidung noch nicht draußen). Vielleicht als Mindestversion jetzt besser Python 3.5 erwarten? Wobei ich bezweifle, dass wir tatsächlich Python 3.5 spezifische Features verwenden werden. Ich find's trotzdem besser, auf eine halbwegs aktuelle Version zu setzen, auch damit die Abhängigkeiten auf dem neuesten Stand gehalten werden können. Denn die könnten ja tatsächlich mal Features aus einer aktuellen Python-Version einsetzen.

2) IMHO brauchen wir im Falle eines Brettspiels nicht zwingend PyGame. Das sollte soweit auch mit PyQt / PySide ganz gut zu schaffen sein. Von mir aus können wir aber bei PyGame bleiben, sofern die Mehrheit das lieber beibehalten möchte. Ich möchte es jetzt auch nicht zu kompliziert machen oder unnötige Verzögerungen in die Planung bringen...
Pygoscelis papua
User
Beiträge: 206
Registriert: Freitag 13. März 2015, 18:36

Letztendlich werde ich mich was das anbetrifft zurückhalten, ich habe sowohl PyQt als auch Pygame ausprobiert und das mit 3.4 und 3.5 bei Python ist mir denke ich auch nicht so wichtig...
Aber wie es sich anhört sollten wir eher 3.5 verwenden,
vom Gefühl her denke ich das Pygame einfacher ist als Qt aber Qt sieht natürlich besser aus :)
import this
hidden python features

JAVA = Just Another Vulnerability Announcement :D
Pygoscelis papua
User
Beiträge: 206
Registriert: Freitag 13. März 2015, 18:36

Würde es sinn machen wenn ich schon mal so ein Klassendiagramm aufstelle und hochlade?
import this
hidden python features

JAVA = Just Another Vulnerability Announcement :D
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Überleg dir ruhig was, wenn du willst. Jedes Vorankommen ist hilfreich. :)
sebastian0202
User
Beiträge: 168
Registriert: Montag 9. Mai 2016, 09:14
Wohnort: Berlin

Ich wusste gar nicht, dass man mit PyQt kleinere Spiele entwickeln kann.
Dachte, damit können immer nur 'Programme' entwickelt werden.
Hätte also nichts dagegen, wenn wir PyQt / PySide nutzen.
Python3.5 fände ich auch in ordnung, gerade weil ich dieses installiert habe.
Ich habe mal für Dame abgestimmt. Ich denke die KI ist dort einfacher zu programmieren.
Auch fühlt sich die Programmierung der GUI einfacher bei Dame an.

Jetzt bin ich übrigens neugierig auf das Klassendiagramm.
Wenn wir das richtig ausformuliert haben, stehen die Schnittstellen ja so gut wie fest.
Dann kann sich jeder einen Programmierhappen nehmen und loslegen.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Du kannst mit Qt beliebige Objekte zeichnen, ähnlich wie mit PyGame. Animationen sind auch möglich. Für ein Brettspiel mit einfachem 2D Design bietet Qt ausreichend Möglichkeiten.
Benutzeravatar
Kebap
User
Beiträge: 686
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

PyQt fände ich auch spannend, damit wollte ich mich sowieso nochmal intensiver beschäftigen.
sebastian0202 hat geschrieben:Ich habe mal für Dame abgestimmt. Ich denke die KI ist dort einfacher zu programmieren.
Wird das erstmal ein 2-Personen-Spiel, oder brauchen wir auch direkt Computergegner?
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wir können die KI auch erstmal weg lassen. Hier bestehen auch die größten Unsicherheiten, denke ich. Also dann warten wir mal aufs Klassendiagramm. Aufgrund des Stands bei der Umfrage gehe ich mal stark von Mühle aus. Und Python 3.5 mit PyQt scheint auch Konsens zu sein, oder hat hierbei jemand Einwände?
BlackJack

@snafu: Python 3? Und bei Qt dann wahrscheinlich auch Qt5? Bah, neumodisches Zeug, das gibt's nicht auf meinen stabilen/LTS Systemen. :P
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Dann musst du möglicherweise mal über deinen Schatten springen und dir ein vEnv mit Python 3.5 anlegen. Ich persönlich bin nicht so scharf auf das compat-Gedöns (auch nicht auf six) nur damit noch Python 2.7 unterstützt wird. Ich weiß ja nicht wie die anderen das sehen. Ich unterstütze inzwischen Python 2.7 nur noch bei Projekten, die als Bibliothek gedacht sind, weil man da mitunter nicht so leicht umsteigen kann. Für Projekte, die sich an Endanwender richten, erwarte ich einen aktuellen 3.x Interpreter.
BlackJack

@snafu: Was neueres als Python 3.3 bekomme ich hier nicht installiert. Sonst muss ich anfangen Abhängigkeiten die zu alt sind zu kompilieren und das hatte dann wieder irgendwelche Abhängigkeiten die neuer sein mussten. Bevor ich mir das halbe System selbst neu kompiliere bleibe ich lieber bei Python 2.7. Da funktioniert auch Unicode und vor allen ”nicht-unicode” problemloser.
Pygoscelis papua
User
Beiträge: 206
Registriert: Freitag 13. März 2015, 18:36

@BlackJack aber ernsthaft, die meisten und besonders einsteiger verwenden doch python3 und nicht python2.7 oder?
Außerdem ist es nicht schwer Python entweder als VirtualEnv oder sogar einfach Kompiliert auf einem Usb-Stick oder Home-Ordner zu erstellen,
das braucht kaum Abhängigkeiten, das konnte ich selbst in der Schule kompilieren, wo ich sonst gar nichts installieren etc. kann.
Aber Insgesammt denke ich werden wir die neusten Features eh nicht wirklich nutzten können, also wird es auch auf 3.3 laufen denke ich,
wenn nicht gar auf 2.7 ...


Wie kann man hier eigentlich einen Anhang anfügen?
Hier ist das Klassendiagramm, es muss aber noch verbessert werden:
gaming_piece-> hängt von crossroad ab
- color
- position #need??
- crossroad_id
- __init__(pos, crossroad_id)

crossroad -> hängt von game ab
- neighbours (horizontal/vertical)
- content
- position #only needed for gui
- id?
- is_protected() -> True/False #mill

player -> hängt von game ab
- id
- color
- move_piece(from_pos, to_pos)
- num_pieces_placed
- remove_piece(pos)

game
- players
- move_piece(from_crossroad, to_crossroad) -> Mill -> True/False?
- crossroads
- has_won(player) -> True/False
- place_piece(pos) -> Mill? -> True/False?
- turn
- get_removeable_pieces() -> list
- turn_end()

das Gui habe ich nicht mit aufgenommen, das ist also eher der logische teil ...
eventuell sollte noch eine Klasse board dazu getan werden,
im code werden die Klassen natürlich CamelCase verwenden ...
Ich hoffe ihr habt noch viele Verbesserungsvorschläge :D
import this
hidden python features

JAVA = Just Another Vulnerability Announcement :D
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Vorab eine sprachliche Sache: Crossroad ist im Englischen eine Straßenkreuzung. Für Kreuzungen im Allgemeinen trifft es Crossing besser.

Dann würde ich die ganzen IDs weglassen. Das erinnert eher an einen datenbankorientierten Ansatz. Ich sehe nicht, inwiefern das hier benötigt wird.

Dem Spieler könnte man zusätzlich einen Namen als Attribut zuweisen, den der Anwender dann natürlich selbst bestimmt.

Statt GamingPiece reicht IMHO einfach Piece. Das ist schön prägnant und dass der Kontext ein Spiel ist, erklärt sich eigentlich von selbst.

Du hast es schon als Kommentar angerissen: Der Stein muss seine Position nicht kennen, denn das Brett verwaltet die Positionen.

Insgesamt finde ich auch das Konzept einer speziellen Klasse für Kreuzungen problematisch. Wurde das zu Ende gedacht? Wenn ja: Was soll der Vorteil davon sein? Ich würde das Spiel besser in 3 Quadrate unterteilen (außen, Mitte, innen). Jedes Quadrat hat 9 Positionen (dass die um die Ecke gehen, ist ja erstmal egal). Jede zweite Position stellt hierbei eine Kreuzung dar.

Anstatt das Feld zu befragen ob es geschützt ist, würde ich das besser über Hilfsmethoden in der Logik lösen. Die Ermittlung könnte in dem Fall auf Abruf erfolgen (d.h. wenn ein Stein auf das Feld gesetzt bzw gezogen werden soll) und im Falle eines ungültigen Zuges mit einer Exception antworten. Ähnlich verhält es sich mit get_removable_pieces() in der Game-Klasse. Wird das wirklich benötigt? Oder hast du dabei so eine Art visuelle Hilfestellung für den Spieler im Hinterkopf?

Außerdem bin ich über die move_piece()-Methode als Teil der Player-Klasse gestolpert. Das ist doch eher Teil der Game-Klasse, oder nicht? Zudem besteht neben dem Verschieben von Steinen am Anfang ja die Variante des Setzens der ersten Steine. Und ganz am Ende können die Steine wieder springen. Allgemeiner ausgedrückt wäre player.play() vielleicht passender. Die Game-Klasse könnte in einer Schleife dann immer abwechselnd die play()-Methode des jeweiligen Spielers aufrufen. Oder hier einfach ein Signal aussenden, dass der Andere an der Reihe ist.

So, jetzt mach ich erstmal Schluss, damit es nicht zuviel wird. Bitte von der umfangreichen Kritik nicht entmutigen lassen. Zum Einen gibt es vielleicht andere Meinungen dazu und zum Anderen finde ich es super, dass du einen ersten Entwurf geliefert hast. Kritisieren an einem Entwurf ist immer viel einfacher als den Entwurf überhaupt mal zu erstellen und ihn zu präsentieren. Vielleicht hast du Lust, ein paar Überarbeitungen zu machen...? Nimm einfach die Dinge, die du ähnlich siehst. Vielleicht möchtest du die Ideen noch etwas modifizieren. Das Projekt ist schließlich eine Gruppenarbeit, wo sich jeder mit seinen Ansichten einbringen soll. ;)
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

BlackJack hat geschrieben:@snafu: Was neueres als Python 3.3 bekomme ich hier nicht installiert.
Naja, das ist ja schonmal was. Gut möglich, dass das Spiel auch unter Python 3.3 laufen wird oder dass nur geringe Anpassungen nötig sind. Über die könnte man sich, sofern sie tatsächlich auftreten, bestimmt noch einigen. :)
BlackJack

@Pygoscelis papua: Die meisten Einsteiger werden wahrscheinlich Python 3 verwenden, so insgesamt würde ich mich diese Aussage nicht trauen zu machen.

Und doch, Python >3.3 selber zu kompilieren ist bei mir schwer. Ich habe ja den Punkt beschrieben ab dem ich aufgegeben habe. Eine Abhängigkeit die ich mir nicht selbst kompilieren möchte, wäre beispielsweise OpenSSL. Da habe ich eine ”alte” Version, aber mit den entsprechenden Sicherheitsupdates, aber Python lässt sich dagegen nicht kompilieren. Für Tkinter müsste ich Tk neu kompilieren und dem war dann mein X-Server zu alt. Wenn ich den Rattenschwanz anschaue der da dran hängt beim neu kompilieren, immer in der Hoffnung das dadurch am System und den Anwendungen irgendwas nicht mehr läuft, könnte ich mir auch die Zeit nehmen das System komplett neu aufzusetzen. Das hat aber sein EOL noch nicht erreicht und ist näher an den Rechnern für die ich ernsthaft programmiere, also will ich da jetzt noch keine Zeit drauf verwenden.

Selbst mit der 3.3 hätte ich dann ja immer noch ein Problem mit Qt wenn das 5 sein sollte. Qt5 zu kompilieren würde mir nämlich auch zu viel Aufwand sein. :-)

Na egal, ich bin ja auch nicht die Zielgruppe für das Projekt.

Zu den Klassen: Wenn das die Logik ist, dann brauchen `Crossroad`-Exemplare keine Position in der GUI.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wegen dem Qt 4/5 Thema habe ich mir noch keine Gedanken gemacht. Ich fänd's schön, wenn du dabei wärst, BlackJack. Ich für meinen Teil könnte mich auch gut mit Qt 4 anfreunden, weil ich mir nicht vorstellen kann, dass Qt 5 etwas mitbringt, das wir unbedingt benötigen.

Ansonsten haben wir ja viel GUI und Spiellogik in der Planung drin. Das müsste normalerweise alles auch von Python 3.3 unterstützt werden. Es klang bei dir erst so, als wolltest du zwingend bei Python 2.7 bleiben. Da sind die Unterschiede ja nun doch etwas größer. Dass du dein System lieber stabil halten möchtest anstatt den "heißesten Scheiss" drauf zu haben, ist dein gutes Recht und das kann ich auch nachvollziehen - gerade bei Linux.

Ich finde, dass wir uns an den exakten Versionen unserer Abhängigkeiten in der jetzigen Projektphase noch nicht aufhängen sollten. Es ist gut, dies mal besprochen zu haben, aber ich denke schon, dass sich hier ein Kompromiss finden lässt. Wie gesagt: Wenn der kleinste gemeinsame Nenner zumindest Python 3 ist, kann ich gut damit leben. Sofern man irgendwann das fertige Projekt überarbeiten möchte (z.B. das Spiel als mobile App), könnte man ja wieder neu über die geforderten Versionen nachdenken, da Qt 5 in dem Punkt deutliche Stärken gegenüber seinem Vorgänger hat. Soweit meine Meinung zu dem Thema...
Pygoscelis papua
User
Beiträge: 206
Registriert: Freitag 13. März 2015, 18:36

ok hier ein paar Änderungen:
piece-> hängt von crossing ab
- color
- crossroad_id
- __init__(pos, crossroad_id)

crossing -> hängt von game ab
- neighbours (horizontal/vertical)
- content #(piece/None)
- id

player -> hängt von game ab
- name
- color
- num_pieces_placed
- play(game??? :K )

game
- players
- move_piece(from_crossing, to_crossing) -> Mill -> True/False?
- remove_piece(crossing)
- crossings
- has_won(player) -> True/False
- place_piece(pos) -> Mill? -> True/False?
- turn
- get_removeable_pieces() -> list
- turn_end()
- is_protected(crossroad) -> True/False #mill
Ähnlich verhält es sich mit get_removable_pieces() in der Game-Klasse. Wird das wirklich benötigt? Oder hast du dabei so eine Art visuelle Hilfestellung für den Spieler im Hinterkopf?
Ja ich hatte da so eine Hilfestellung im Hinterkopf :) sollte das dann eher in das Gui?

Wie würde player.play auf das spiel zugreifen? (wird das spiel einfach als parameter übergeben wie angedeutet? )
Bei dem kreuzungs-modell habe ich mir einfach vorgestellt, das es nicht so kompliziert ist. Ich habe mir das ganze eher als Netz gedacht und dann muss man einfach nur den Kreuzungen Nachbarn zuordnen, das klang für mich am einfachsten ...
import this
hidden python features

JAVA = Just Another Vulnerability Announcement :D
BlackJack

@Pygoscelis papua: Die IDs sind noch drin. Objekte haben ganz automatisch schon selbst eine Identität, man kann Objekte eindeutig voneinander unterscheiden. Zumindest solange man die Vergleichsoperatoren für den Datentyp nicht anders definiert sogar auf ganz triviale Weise, denn dann ist ein Objekt immer nur gleich sich selbst und nicht gleich einem anderem Objekt [1]_, selbst wenn das die gleichen Werte/den gleichen Zustand besitzt. Und wenn man die Vergleiche doch anders definiert, kann man die Identität immer noch in Form einer Zahl mit der `id()`-Funktion ermitteln und ``is`` oder ``is not`` verwenden um zu ermitteln ob es sich bei gleichen Objekten auch tatsächlich um das selbe Objekt handelt. Wenn man das braucht.

.. [1] Stimmt nur solange man nicht einen Datentyp mit pathologischen Implementierungen von den Vergleichsoperationen hat. :-)
Antworten