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 hat geschrieben:@snafu: Was neueres als Python 3.3 bekomme ich hier nicht installiert.
#pydesw: Programmierung eines Brettspiels
@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.
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.
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...
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...
-
- 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
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 ...
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
Ja ich hatte da so eine Hilfestellung im Hinterkopf sollte das dann eher in das Gui?Ä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?
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 ...
@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.
.. [1] Stimmt nur solange man nicht einen Datentyp mit pathologischen Implementierungen von den Vergleichsoperationen hat.
-
- User
- Beiträge: 206
- Registriert: Freitag 13. März 2015, 18:36
ok denk dir die id einfach weg.
Und zu player.play hat da jemand eine Antwort für mich? Ist einfach game übergeben ok? Sonst müsste man ja verbotener weise global verwenden oder?
Und zu player.play hat da jemand eine Antwort für mich? Ist einfach game übergeben ok? Sonst müsste man ja verbotener weise global verwenden oder?
Ein Spieler könnte bereits bei seiner Erzeugung das Spiel, zu dem er gehört, übergeben bekommen. Die Rückgabe seiner play()-Methode wäre dabei der nächste Spielzug. Was hältst du von diesem Ansatz?
-
- User
- Beiträge: 206
- Registriert: Freitag 13. März 2015, 18:36
ok das ist doch dann"call bei Referenz" oder?
Klar kannst du ein Bild erstellen und hier hochladen, oder du benutzt direkt ein Tool, um Klassendiagramme online zu erstellen/teilen/verbessern, da gibt es sehr vielePygoscelis papua hat geschrieben: Wie kann man hier eigentlich einen Anhang anfügen?
Hier ist das Klassendiagramm, es muss aber noch verbessert werden:
...
Ich hoffe ihr habt noch viele Verbesserungsvorschläge
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.
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
Call by Reference ist etwas ganz anderes. Ich dachte es mir so, dass die play()-Methode ein namedtuple liefert mit den Angaben "from" (bzw "from_") und "to". Ein noch nicht gesetzter Stein hätte keine Angabe bzw den Standardwert None für das from-Attribut. Diese Rückgabe könnte vom Aufrufer (also dem Spiel) entsprechend verarbeitet werden. Im Falle eines ungültigen Zuges erfolgt eine Rückmeldung durch das Spiel per Exception, die von der GUI visuell dargestellt wird. Der Spieler ist dann weiterhin an der Reihe und play() müsste erneut aufgerufen werden.Pygoscelis papua hat geschrieben:ok das ist doch dann"call bei Referenz" oder?
-
- User
- Beiträge: 206
- Registriert: Freitag 13. März 2015, 18:36
Ich meine wenn man am Anfang dem Spieler das Spiel übergibt,
dann wird ja wohl nicht das Spiel in dem Spieler gespeichert, sondern eher sozusagen ein "Zeiger", da wenn man es verändert (in einer Methode von Spieler), wird das Spiel, dass übergeben wurde ja auch z.B bei einem 2. Spieler geändert, dem das Spiel auch übergeben wurde oder?
Wie wird das Spiel denn sonst angesprochen, als über einen "Zeiger", wenn es nicht im Spieler gespeichert ist?
Das Call ist hier natürlich nicht wirklich angebracht, da es keine Funktion ist ...
@Kebap die Frage was nicht ob sondern wie ...
dann wird ja wohl nicht das Spiel in dem Spieler gespeichert, sondern eher sozusagen ein "Zeiger", da wenn man es verändert (in einer Methode von Spieler), wird das Spiel, dass übergeben wurde ja auch z.B bei einem 2. Spieler geändert, dem das Spiel auch übergeben wurde oder?
Wie wird das Spiel denn sonst angesprochen, als über einen "Zeiger", wenn es nicht im Spieler gespeichert ist?
Das Call ist hier natürlich nicht wirklich angebracht, da es keine Funktion ist ...
@Kebap die Frage was nicht ob sondern wie ...
@Pygoscelis papua: Du bewegst Dich da auf der Ebene der Implementierung. Egal welchen Wert Du übergibst oder an ein Attribut bindest, es handelt sich bei Python immer um das selbe Objekt. Python kopiert bei Aufrufen und Zuweisung niemals Objekte/Werte. Das Aufrufmodell kann man als „call by object sharing“ bezeichnen. Namen und Attribute stehen in Python nicht für Speicher(adressen) wo man Werte ”rein tut”. Der Speicher gehört zum Wert/Objekt.
Die Übergabe des Spiels war eine erste Idee. Eigentlich muss nur das Spielfeld übergeben werden. Als Rückgabe dann wie gesagt ein Spielzug. Hierdurch müsste die play() Methode nichts vom Spiel wissen, sondern nur das Spielfeld mit seiner aktuellen Stellung auslesen können.
Denkbar wäre auch, einen GuiPlayer und einen KIPlayer von der Player Klasse abzuleiten, die als Schnittstelle nur Farbe, Name und die play() Methode haben.
Denkbar wäre auch, einen GuiPlayer und einen KIPlayer von der Player Klasse abzuleiten, die als Schnittstelle nur Farbe, Name und die play() Methode haben.
-
- User
- Beiträge: 206
- Registriert: Freitag 13. März 2015, 18:36
@snafu: Könntest du das Diagramm vielleicht deinen Vorstellungen entsprechend ändern?
Ich habe jetzt dafür nicht so viel Zeit und außerdem weiß ich nicht wie du dir das genau vorstellst
Ich habe jetzt dafür nicht so viel Zeit und außerdem weiß ich nicht wie du dir das genau vorstellst
-
- User
- Beiträge: 168
- Registriert: Montag 9. Mai 2016, 09:14
- Wohnort: Berlin
Ich versuche es mal. Es ist glaube zu viel des Guten und vermutlich wieder so viel vermischt..
Ich habe es halb als Pseudo Python Code geschrieben grausam
Ich habe es halb als Pseudo Python Code geschrieben grausam
Code: Alles auswählen
class Feld(feldtyp):
feldtyp=feldtyp
besitzer = 'Spiel'
def besetzt():
wenn besitzer != 'Spiel':
return True
return False
def setze(spielername):
besitzer=spielername
def typ():
return feldtyp
def leere():
besitzer='Spiel'
def besitzer():
return besitzer
class Rechteck():
# beginnen oben-links, enden unten-rechts
acht_felder = [Feld('Ecke'), Feld('Kreuzung'), ... , Feld('Ecke')]
def besetzt(feldnummer):
return acht_felder[feldnummer].besetzt()
def setze_besitzer(feldnummer, spielername):
acht_felder[feldnummer].setze(spielername)
def loesche_besitzer(feldnummer):
acht_felder[feldnummer].leere()
def hole_besitzer(feldnummer):
return acht_felder[feldnummer].besitzer()
class Spiellogik():
spielfeld = {
'außen': Rechteck(),
'mittig': Rechteck(),
'innen': Rechteck()
}
selbiges_rechteck = ([1,2,3], [6,7,8], [1,4,6], [3,5,7])
ungleiches_rechteck = ([2,2,2], [4,4,4], [5,5,5], [7,7,7])
def ist_muehle(info):
rechteck, nummer = unpack(info)
fuer muehle in selbiges_rechteck:
wenn nummer in muehle:
besitzer = set()
fuer nummer in muehle:
besitzer.add(ermittle_spielstein_besitzer(rechteck, nummer))
if len(besitzer) == 1:
return True
fuer muehle in ungleiches_rechteck:
wenn nummer in muehle:
besitzer = set()
for rechteck in ('außen', 'mittig', 'innen')
besitzer.add(ermittle_spielstein_besitzer(rechteck, nummer))
if len(besitzer) == 1:
return True
return False
def ermittle_spielstein_besitzer(rechteck, nummer):
return spielfeld[rechteck].hole_besitzer(nummer)
class Spielfeld(Spiellogik):
def setze_spielstein(spielstein, nach, spielername):
wenn spielfeld[nach['rechteck']].besetzt(nach['nummer']):
return False
ansonsten
wenn spielstein.ist_gesetzt():
info = spielstein.hole_information()
spielfeld[info['rechteck']].loesche_besitzer(info['nummer'])
spielfeld[nach['rechteck']].setze_besitzer(nach['nummer'], spielername)
return True
def loesche_feld(spielstein):
info = spielstein.hole_information()
wenn ist_muehle(info): return False
ansonsten:
spielfeld[info['rechteck']].loesche_besitzer(info['nummer'])
spielstein.toete()
return True
def analysiere(info):
wenn ist_muehle(info): return True
ansonsten: return False
class Spielstein():
gesetzt = False
lebendig = True
info = ['position':None, 'rechteck':None]
def hole_information():
return info
def ist_gesetzt():
return gesetzt
def toete():
lebendig = False
class Auswahl():
nach = [rechteckID, feldID]
def hole_rechteck(gui):
def spielstein_waehlen(gui):
return auswahl aus der gui
class Spieler():
spielsteine = [8*spielstein()]
spielername =
gui = Auswahl() (emit Funktion spaeter?)
letzer_zug = None
def zug(spielfeld):
spielsteingesetzt = False
solange bis spielsteingesetzt:
spielstein = gui.spielstein_waehlen()
spielsteingesetzt = spielfeld.setze_spielstein(spielstein, gui.nach, spielername)
letzer_zug = spielstein.hole_information()
def anzahl_lebendiger_spielsteine():
anzahl = 0
fuer stein in spielstein:
wenn stein.lebendig:
anzahl + 1
return anzahl
class Spiel():
spieler = [Spieler(), Spieler()]
spielfeld = Spielfeld()
generiere_schicke_grafik()
def mache_zug(spieler_am_zug):
spieler[spieler_am_zug].zug(spielfeld)
def werte_zug_aus(spieler_am_zug):
info = spieler_am_zug.letzer_zug()
darf_stein_loeschen = spielfeld.analysiere(info)
wenn darf_stein_loeschen:
spielstein = spieler_am_zug.gui.spielstein_waehlen()
solange wie nicht wahr:
spielfeld.loesche_feld(spielstein)
def spiel_vorbei():
fuer gamer in spieler:
wenn spieler.anzahl_lebendiger_spielsteine() == 0:
return True
return False
def update():
solange True:
spieler_am_zug = spieler[0]
spieler = spieler[::-1]
mache_zug(spieler_am_zug)
werte_zug_aus(spieler_am_zug)
wenn spiel_vorbei(): break
-
- User
- Beiträge: 206
- Registriert: Freitag 13. März 2015, 18:36
+100 für die Anstrengung und das mitarbeiten an der Ausarbeitung des Spiel-Plans
es wäre wirklich übersichtlicher es als Bild darzustellen, ich weiß aber immer noch nicht wie man hier einen Anhang anfügt...
Und ich glaube ein Klassendiagramm soll noch nicht festlegen, wie die einzelnen Funktionen Implementiert werden, was es auch noch einmal
unübersichtlicher macht.
Ich finde es dennoch gut, dass du neues zu dem Diagramm beigetragen hast, ich habe nur jetzt nicht die Zeit alles genau durch zuschauen bzw. zu durchschauen.
Wenn es möglich wäre das als Bild irgendwie Darzustellen wäre es echt cool, vieleicht kann das bild einfach auf GitHub hochgeladen werden (in eine fork
von der repo zur Vorstellung des Projekts?) und dann hier verlinkt werden?
Ich finde man hat hier einen recht schlechten Überblick,sebastian0202 hat geschrieben:Ich versuche es mal. Es ist glaube zu viel des Guten und vermutlich wieder so viel vermischt..
Ich habe es halb als Pseudo Python Code geschrieben grausam
es wäre wirklich übersichtlicher es als Bild darzustellen, ich weiß aber immer noch nicht wie man hier einen Anhang anfügt...
Und ich glaube ein Klassendiagramm soll noch nicht festlegen, wie die einzelnen Funktionen Implementiert werden, was es auch noch einmal
unübersichtlicher macht.
Ich finde es dennoch gut, dass du neues zu dem Diagramm beigetragen hast, ich habe nur jetzt nicht die Zeit alles genau durch zuschauen bzw. zu durchschauen.
Wenn es möglich wäre das als Bild irgendwie Darzustellen wäre es echt cool, vieleicht kann das bild einfach auf GitHub hochgeladen werden (in eine fork
von der repo zur Vorstellung des Projekts?) und dann hier verlinkt werden?
Schonmal auf die Idee gekommen, dass man auch einfach einen Link zum Bild setzen könnte...?
Den Code werde ich gleich mal genauer anschauen und vielleicht später eine überarbeitete Version hier zeigen.
Den Code werde ich gleich mal genauer anschauen und vielleicht später eine überarbeitete Version hier zeigen.
Man könnte sich auch mal Werkzeuge zum erstellen von UML-Diagrammen aus Text anschauen. PlantUML wäre so ein Kandidat. UMLet habe ich auch schon mal verwendet.