Seite 4 von 16
Verfasst: Freitag 11. Juli 2008, 18:11
von wuf
Hallo
@numerix & @EyDu -> Danke noch für eure Vorschläge
Hier ist noch die dritte Variante. Habe die for...Schleifen noch in einer neuen Funktion 'create_poly_array' untergebracht. Das Code-Snippet enthält noch keine Klasse.
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# Skriptname derkai_05_02_03 (11.07.2008)
import Tkinter as tk
from math import sqrt,sin,cos,pi
from random import choice
def create_xyoffset(length):
"""Berechnet die XY-Versatzabstände"""
poly_data = [(cos(pi/3*x)*length,sin(pi/3*x)*length) for x in range(6)]
xa,ya = poly_data[0]
xb,yb = poly_data[1]
xc,yc = poly_data[5]
return (length+(xa-xb),yb-yc)
def create_hex_polygon(spiel_feld,length,xpos,ypos,farbe):
"""Erzeugt das grafische Sechseck-Objekt"""
poly_data = [(cos(pi/3*x)*length+xpos,
sin(pi/3*x)*length+ypos) for x in range(6)]
poly_obj = spiel_feld.create_polygon(
poly_data,outline="black",fill=choice(farbe))
return poly_obj
def create_poly_array(spiel_feld,xorg,yorg,spalten,zeilen,hex_laenge,farbe):
"""Platziere ein zweidimensionalen Sechseck-Array"""
xpos = xorg
ypos = yorg
toggle = 0
poly_id_list = []
#~~ Berechnung der XY-Versatzabstände für die Platzierung der Sechsecke
xoffset,yoffset = create_xyoffset(hex_laenge)
#~~ Poly Objekte platzieren
for x in xrange(spalten):
for y in xrange(zeilen):
poly_id = create_hex_polygon(spiel_feld,hex_laenge,xpos,ypos,farbe)
ypos += yoffset
poly_id_list.append(poly_id)
xpos += xoffset
if not toggle:
toggle = 1
ypos = yorg + yoffset/2.0
else:
toggle = 0
ypos = yorg
return poly_id_list
def main():
#~~ Erzeugt das Hauptfenster
master = tk.Tk()
spiel_feld = tk.Canvas(master, width=1024, height=768)
spiel_feld.pack()
HEX_LAENGE = 20.0 # Seitenlänge
XORG = 30 # X Start-Koordinate
YORG = 30 # Y Start-Koordinate
SPALTEN = 10 # Anzahl Spalten
ZEILEN = 10 # Anzahl Zeilen
HEX_FARBE = ("yellow","green","blue","red") # Zufalls-Farben
poly_id_list = create_poly_array(
spiel_feld,XORG,YORG,SPALTEN,ZEILEN,HEX_LAENGE,HEX_FARBE)
print poly_id_list
master.mainloop()
main()
Wie steht es mit der PEP8-Konformität bitte kontrollieren. Verbesserungsvorschläge.
Gruss wuf
Verfasst: Freitag 11. Juli 2008, 18:23
von derkai
ja und nein, ich habe es leider noch nicht vollständig verstanden, beschränke mich aber für den Moment auf den URsprungscode.
Eh ich den nicht vollständig begriffen habe, möchte ich mich noch
nicht an Verändeurngen ran machen.
Leider hatte ich bisher kaum Zeit mich "wieder ein zu denken". Das mach
ich aber heute abend und morgen vormittag.
Ich würde dann bestimmt wieder ne Frage fragen.
Trotzdem muss ich auch den Original Code nochmals ändern, da
ich es mir in den Kopf gesetzt hatte, dass der Aufbau und speziell die Reihenfolge der Hexfelder anders von statten gehen soll.
(bin halt ´n kleiner Sturkopf, sagt meine Frau)
Die Felder sollen sich zeilenweise von links nach rechts aufbauen. Betrachtet man das Spielfeld, so würde das 1. Hesagon natürlich "links oben" erzeugt werden. Weiter ging es dann x + 2 x laenge, y ist gleiche Höhe. Und das so lange, bis 15 .. 16 Felder nebeneinander horizontal aufgebaut sind. Danach erfolgt die nächste Zeile. x = x + laenge
Deswegen und weil ich es mir anders ausgemalt hatte, habe ich im Moment auch noch Schwierigkeiten mit dem Code.
Ich werde aber jetzt mal weiter drüber brüten ...
Die Geschwindigkeit ist genial !!!!
besten Dank
Kai
Verfasst: Freitag 11. Juli 2008, 18:27
von numerix
wuf hat geschrieben:Verbesserungsvorschläge.
Die Sache mit dem toggle in Zeile 52-59 kann man sich sparen.
Stattdessen einfach
Verfasst: Freitag 11. Juli 2008, 18:32
von numerix
derkai hat geschrieben:Trotzdem muss ich auch den Original Code nochmals ändern, da ich es mir in den Kopf gesetzt hatte, dass der Aufbau und speziell die Reihenfolge der Hexfelder anders von statten gehen soll.
Die Felder sollen sich zeilenweise von links nach rechts aufbauen.
Warum willst du das so haben? Wichtig ist doch für das Spielfeld nur das Ergebnis und das ist doch - jedenfalls auf meinem 7 Jahre alten Rechner - sofort nach dem Start komplett da. Wenn du beim Aufbau zugucken willst, dann nimm halt wieder das frog-Modul ...
Verfasst: Freitag 11. Juli 2008, 18:49
von derkai
weil wenn ICH das hinbekomme, dann hab ich es KAPIERT.
Ausserdem dachte ich halt, dass ich bei jedem Schleifendurchlauf
direkt die Koordinaten + n speichern könnte. z.b. in einem Dictionary.
Dann hätte ich später eine Lister aller Koordinaten.
Ich weiss, dass geht soo auch.
Aber wenn ich später noch Entfernung und Bewegung einfügen muss,
dann wäre es doch bestimmt einfacher, oder ? (auch für den Kopf)
Denkst Du denn, es wäre anders programmiert langsamen ?
Es geht nicht ums zugucken, sondern um die Reihenfolge
Kai
Verfasst: Freitag 11. Juli 2008, 18:57
von derkai
mit diesen "booleschen" Ausdrücken habe ich
auch noch so mein Problem.
toggle = 0
Code: Alles auswählen
if not toggle:
toggle = 1
ypos = yorg + yoffset/2.0
else:
toggle = 0
ypos = yorg
Was passiert hier genau ?
Ich weiss, dass hier entchieden wird, ob die Spalte Versatz haben soll, oder nicht. Aber wie könnte man das "umgangssprachlich" beschreiben.
Gruß
kai
Verfasst: Freitag 11. Juli 2008, 19:02
von derkai
und dann noch eine kleine andere Frage :
Code: Alles auswählen
def create_hex_polygon(spiel,xpos,ypos,points,farbe):
"""Erzeugt das grafische Sechseck-Objekt"""
x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6 = points
x1 += xpos
y1 += ypos
x2 += xpos
y2 += ypos
x3 += xpos
y3 += ypos
x4 += xpos
y4 += ypos
x5 += xpos
y5 += ypos
x6 += xpos
y6 += ypos
return spiel.create_polygon(x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6,
outline="black",fill=choice(farbe))
in die Funktion wird das Argument "points" übergeben. Dieses erhält dann die Werte aus hex_point_list.
Frage ?
was macht diese Zeile : x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6 = points
wenn doch die weitere Verarbeitung weiter unten statt findet ?
Verfasst: Freitag 11. Juli 2008, 19:07
von numerix
derkai hat geschrieben:Ich weiss, dass hier entchieden wird, ob die Spalte Versatz haben soll, oder nicht. Aber wie könnte man das "umgangssprachlich" beschreiben.
Umgangssprachlich: Es wird immer abwechselnd die Hälfte von yoffset dazu addiert oder eben nicht. Das toggle sorgt dafür, dass es immer abwechselnd (alternierend) passiert. Wie man das kürzer machen kann, habe ich ja schon gepostet.
derkai hat geschrieben:was macht diese Zeile : x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6 = points
Das nennt man "Entpacken einer Sequenz": Die einzelnen Koordinaten der Sequenz points werden den Variablen x1 ... y6 zugewiesen. Auch das ist hier ja nicht erforderlich, wie schon gezeigt wurde.
Verfasst: Freitag 11. Juli 2008, 20:36
von wuf
Hallo derkai
Das ist klar wir machen hier erst weiter, wenn du verstanden hast wie dein Spiel-Code abläuft und was er macht, und natürlich, dass er so abläuft wie du dir es vorgestellt hast. Es kamen in kurzer Zeit sehr viele interessante Vorschläge für die Code-Optimierung und Minimierung zusammen. Aber es ist schon so, dass bei den ersten Programmier-Gehversuchen einem viel neues über den Weg läuft. Sicher ist es besser den Code so zu schrieben, dass man in ohne grosse Decodierarbeit beim durchlesen versteht. Das optimieren kann später erfolgen
Das mit der Platzierung der Poly-Objekte von link nach rechts machen wir sollte kein Problem sein. Wegen den Positions-Koordinaten jedes platzierten Objekt es mache dir auch keine Sorgen. Du kannst die Eigenschaften jedes platzierten Poly-Objektes über dessen ID-Nummer abfragen. Bei der Erstellung des Poly-Objektes gibt die 'create_poly'-Methode eine ID-Nummer (Ganzzahl) des erstellten Objektes zurück. Wie du richtig vermutet hast müssen diese Nummern gespeichert werden. Ich habe bei der letzten dritten Variante eine Sammel-Liste 'poly_id_list' hierfür verwendet.
So wie ich dich verstanden habe möchstes du nicht mehr zu deinem Projekt mit dem frog-Modul zurück sondern zum ersten Code-Snippet unter dem Post vom Do Jul 10, 2008 18:04. Ist das richtig?
Die 5. Zeile dieses Code-Snippets sieht wie folgt aus:
Dort hast du noch dein eigenes Code-Fragment für die Berechnung der Sechseck Eckdaten drin. Wenn du möchtest fahren wir dort weiter. Überlege dirs. Wir machen das nach deiner Tempovorgabe. Step by Step bis du jede Code-Zeile verstehst. Wir haben hier keine Zeittreibende Bestie hinter uns stehen.
OK. derkai Gruss wuf
Verfasst: Freitag 11. Juli 2008, 20:46
von derkai
ihr seit wirklich klasse, aber wie viel Zeit habt Ihr ?
Ich plane mein Projekt so ungefähr bis zu meiner Rente.
Wenn ich viel Glück habe, dann bietet man mir irgendwann einmal
den Vorrihestand an.
Da ich aber erst 34 Lenze zähle muss ich da wohl viel viel Glück haben.
Neee, Spass bei Seite.
Ja, ich würde gerne mit dem Code vom 10. Juli fortfahren, nicht mit dem Frog. Das da vielleicht etwas zu viel Code "drin" ist, stört mich nicht. Im Gegenteil. Ich brauch das um es zu verstehen. Ich möchte das halt als Hobby betreiben und habe halt neben meiner normalen Arbeit halt auch nicht so viel Zeit dafür.
Wie gesagt, ich werde Morgen vormittag versuchen den Code so umzustricken, dass er so abläuft wie ich es mit wünschen würde.
Danke für die vielen Erklärungen.
Das mit dem Entpacken ist nun klar.
Über Toggle mache ich mir gleich noch mal Gedanken.
Kai
Verfasst: Samstag 12. Juli 2008, 06:39
von wuf
Hallo derkai
Alles klar. Betreffs dem 'toggle'. Hier nochmals der Code-Abschnitt:
Code: Alles auswählen
if not toggle:
toggle = 1
ypos = yorg + yoffset/2.0
else:
toggle = 0
ypos = yorg
Die Variable 'toggle' ist nicht ein spezieller Datentyp 'BOOL'. Gib es übrigens in Python nicht. Eine Variable wir in Python auch als Objekt bezeichnet. Da für Python der Name 'toggle' nicht der zugewiesene Wert darstellt sondern eine Adressnummer (auch als Referenz oder Zeiger benannt), welche sich auf die Position des zugewiesenen Wertes im Speicher bezieht. Ich hoffe ich habe mich hier richtig ausgedrückt, sonst wird das sicher durch anderen Forummitglieder umgehend korrigiert.
Wichtig ist einfach das die Variable 'toggle' in deinem Code schon existiert bevor dein Programm das obige Code-Stück durchläuft. Sonst wird Python eine Fehlermeldung (Exception) erzeugen. Wenn du das bestehende Code-Snippet 'derkai_05_02.py' vom 10. Juni durchliest siehst du, dass dieser Variable 'toggle' schon vor derer Benützung den wert 0 zugewiesen bekommt. Hier der entsprechende Code-Abschnitt:
Code: Alles auswählen
toggle = 0
#~~ Platziere den zweidimensionalen Sechseck-Array
for x in xrange(columns):
Zurück zu deiner Frage:
Die Variable 'toggle' wird in diesem Programm nur mit der Zahl 0 oder 1 belegt. Bei jedem Durchlauf der Schleife wird der Wert von 'toggle' von 0 auf 1 oder von 1 auf 0 gewechselt.
Heisst einfach, wenn 'toggle' den Wert 0 hat für den folgenden Code aus:
Der Wert 0 entspricht 'falsch' bzw. 'FALSE'
und der Wert 1 entspicht 'wahr' bzw. 'TRUE'
OK. Ich hoffe deine Frage beantwortet zu haben.
Gruss wuf
Verfasst: Samstag 12. Juli 2008, 07:19
von BlackJack
Und die Korrektur kommt auch umgehend: Python kennt einen Typ für Wahrheitswerte und der heisst `bool`:
Code: Alles auswählen
In [248]: map(type, (True, False))
Out[248]: [<type 'bool'>, <type 'bool'>]
Und den sollte man auch verwenden und nicht Zahlen als Wahrheitswerte missbrauchen. Umgekehrt ändert es nichts daran, dass man mit `True` und `False` "rechnen" kann, weil `bool` eine Unterklasse von `int` ist, und sich `True` und `False` bei Rechenoperationen wie 1 und 0 verhalten.
Der Name `toggle` ist vielleicht auch etwas zu nichtssagend. `is_even_row`, `is_odd_column` oder irgend etwas in der Richtung, was verdeutlicht was der Schalter *bedeutet* statt es einfach "Schalter" zu nennen.
Verfasst: Samstag 12. Juli 2008, 08:35
von wuf
Hallo BlackJack
Danke für deine lehrreiche und erleuchtende Korrektur. Ein Chemiker, Physiker oder Biologe hätte für 'toggle' sicher noch eine andere in sein Umfeld passende Bezeichnung gefunden. Aber du hast recht deine Bezeichnungen sind für die Allgemeinheit besser verständlich.
@derkai Du siehst in diesem Forum kannst du nicht auf einen falschen Pfad geraten. Sorry für meine Fehlorientierung
Habe es mir durch 'Idle' bestätigen lassen:
>>> is_even_row = True
>>> print type(is_even_row)
<type 'bool'>
>>>
Gruss wuf
Verfasst: Samstag 12. Juli 2008, 09:38
von wuf
Hallo derkai
Nach der erleuchtenden Korrektur von BlackJack habe ich den Code-Abschnitt des Code-Snippet 'derkai_05_02.py' für bessere Lesbarkeit und Verständlichkeit wie folgt abgeändert:
Code: Alles auswählen
GERADE = True
UNGERADE = False
xpos = xorg = 10 # X Start-Koordinate
ypos = yorg = 10 # Y Start-Koordinate
spalten = 30 # Anzahl vertikale Reihen
zeilen = 10 # Anzahl horizontale Reihen
farbe = ("yellow","green") # Zufalls-Farben
#~~ Erste Spalte hat die Nummer 0
# 0 = gerade
# 1 = ungerade
# 2 = gerade
# usw.
spalten_nummer = GERADE
#~~ Platziere den zweidimensionalen Sechseck-Array
for spalte in xrange(spalten):
for zeile in xrange(zeilen):
create_hex_polygon(spiel,xpos,ypos,hex_point_list,farbe)
ypos += yoffset
xpos += xoffset
if spalten_nummer == GERADE:
spalten_nummer = UNGERADE
ypos = yorg + yoffset/2.0
else:
spalten_nummer = GERADE
ypos = yorg
@derkai Somit wird die Verwirrung mit dem magischen Wort 'toggle' etwas transparenter. Hi.
Gruss wuf
Verfasst: Samstag 12. Juli 2008, 09:48
von numerix
Ich verstehe nicht, warum ihr so an dem "toggle" hängt.
In einem vorangegangenen Post hatte ich ja schon darauf hingewiesen, dass man das ganze in
einer Zeile erledigen kann.
Für den letzten Codeschnipsel von wuf würde es dann so aussehen (und exakt das gleiche leisten):
Code: Alles auswählen
xpos = xorg = 10 # X Start-Koordinate
ypos = yorg = 10 # Y Start-Koordinate
spalten = 30 # Anzahl vertikale Reihen
zeilen = 10 # Anzahl horizontale Reihen
farbe = ("yellow","green") # Zufalls-Farben
#~~ Platziere den zweidimensionalen Sechseck-Array
for spalte in xrange(spalten):
for zeile in xrange(zeilen):
create_hex_polygon(spiel,xpos,ypos,hex_point_list,farbe)
ypos += yoffset
xpos += xoffset
ypos = yorg + (spalte+1)%2*0.5*yoffset
Verfasst: Samstag 12. Juli 2008, 10:00
von wuf
Hallo numerix
Stimmt natürlich. Dein Vorschlag habe ich nicht übersehen. Ich weiss aber nicht wie 'derkai' dies interpretiert.
Danke für deinen genialen Tipp.
Gruss wuf
Verfasst: Samstag 12. Juli 2008, 10:20
von derkai
derkai ist gerade erst wach geworden und wird gleich loslegen.
toggle ist nun auch klar.
Kai
Verfasst: Samstag 12. Juli 2008, 12:21
von derkai
so, nun habe ich den Code schon einmal meinen Wünschen angepasst.
Als nächstes werde ich mich noch um die Farben kümmern müssen und anschließend versuche ich die Veränderungen zu verstehen.
Danach geht es dann mit dem Erstellen einer Liste aller Koordinaten weiter -
ich möchte ja später gezielt die Position, Farbe und Eigenschaften jedes einzelnen Feldes auslesen können ....
Ich weiss, dass haben wir hier schon angesprochen, ich muß aber leider immer noch erst einen Fuss vor den anderen setzen.
Guckst Du :
Code: Alles auswählen
import Tkinter as tk
from math import sqrt
from random import choice
def calculate_polygon_points(laenge,xorg,yorg):
"""Berechne die Eckpunkte für ein Sechseck"""
x1 = xorg
y1 = yorg
x2 = x1 + laenge
y2 = y1
x3 = x2 + (laenge/2.0)
y3 = y2 + ((laenge * sqrt(3)/2))
x4 = x2
y4 = (sqrt(3) * laenge) + y2
x5 = x1
y5 = y4
x6 = x1 - (laenge / 2.0)
y6 = y3
#~~ Gebe die berechneten Eckpunkte in einer Liste zurück
return [x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6]
def create_hex_polygon(spiel,xpos,ypos,points,farbe):
"""Erzeugt das grafische Sechseck-Objekt"""
x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6 = points
x1 += xpos
y1 += ypos
x2 += xpos
y2 += ypos
x3 += xpos
y3 += ypos
x4 += xpos
y4 += ypos
x5 += xpos
y5 += ypos
x6 += xpos
y6 += ypos
return spiel.create_polygon(x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6,
outline="black",fill=choice(farbe))
def calculate_xyoffset(points):
"""Berechnet die X- und Y-Versatzabstände"""
x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6 = points
laenge = x2 - x1
xoffset = laenge + (x3-x2)
yoffset = y5 - y1
return (xoffset,yoffset)
def main():
master = tk.Tk()
spiel = tk.Canvas(master, width=1024, height=768)
spiel.pack()
hex_laenge = 20 # Bestimmt die Sechseckgrösse
hex_xorg = 15
hex_yorg = 5
#~~ Eckpunkte für das Sechseck berechnen
hex_point_list = calculate_polygon_points(hex_laenge,hex_xorg,hex_yorg)
#~~ Horizontaler- & Vertikaler-Versatz die Sechseck-Platzierung berechnen
xoffset, yoffset = calculate_xyoffset(hex_point_list)
xpos = xorg = 10 # X Start-Koordinate
ypos = yorg = 10 # Y Start-Koordinate
ungerade_spalten = 17 # Spalten
gerade_spalten = 16 # Zeilen
farbe = ("green","green","green","green","green","green",
"brown","green","blue","green") # Zufalls-Farben
#Vorbelegung der Spalten/Zeilen
GERADE = True
UNGERADE = False
spalten_nummer = GERADE
#~~ Platziere den zweidimensionalen Sechseck-Array
for x in range(42):
if spalten_nummer == GERADE :
for x in range(ungerade_spalten):
create_hex_polygon(spiel,xpos,ypos,hex_point_list,farbe)
xpos = xpos + (xoffset *2)
spalten_nummer = UNGERADE
xpos = xorg + xoffset
ypos = ypos + yoffset / 2
else :
for x in range(gerade_spalten):
create_hex_polygon(spiel,xpos,ypos,hex_point_list,farbe)
xpos = xpos + (xoffset *2)
spalten_nummer = GERADE
xpos = xorg
ypos = ypos + yoffset / 2
master.mainloop()
main()
Kai
Verfasst: Samstag 12. Juli 2008, 12:24
von derkai
das habe ich gerade noch geändert :
(Spielfeld ist auch eine Variable)
Code: Alles auswählen
xpos = xorg = 10 # X Start-Koordinate
ypos = yorg = 10 # Y Start-Koordinate
ungerade_spalten = 17 # Spalten
gerade_spalten = 16 # Spalten
spielfeld = 42 #Gesamtanzahl der Zeilen
farbe = ("green","green","green","green","green","green",
"brown","green","blue","green") # Zufalls-Farben
#Vorbelegung der Spalten/Zeilen
GERADE = True
UNGERADE = False
spalten_nummer = GERADE
#~~ Platziere den zweidimensionalen Sechseck-Array
for x in range(spielfeld):
Verfasst: Samstag 12. Juli 2008, 13:04
von derkai
ok, Farbe ist vorerst auch fertig :
Code: Alles auswählen
farbe = ("#F6C783","#F6C783","#F6C783",
"#F6C783","#F6C783","#F6C783", #hellbaun
"#F6C783","#F6C783","#F6C783",
"#F6C783","#F6C783","#F6C783",
"#F6C783","#F6C783","#F6C783",
"#18C85A","#A0A6F5") #gruen,blau
Kai