ich glaub jetzt hab ich es doch. Es ist ein Gedanken Fehler bei mir.
Wenn ich den Abstand der Felder von feldalt(1,1) und neuen Feld
feldneu(2,1) berechnen möchte, dann erhalte ich natürlich bei Nachbarfeld
feldalt(2,1) und neuen Feld(2,1) gleiche Werte bei der Berechnung. Dem
zu Folge muss eine "0" zurückgegeben werden.
Oder ?
Kai
verdammt, ich kapier es einfach nicht
Eine einfachere Variante:EyDu hat geschrieben:Den Abstand berechnest du als:
Code: Alles auswählen
sqrt((mfnx-mfax)**2+(mfny-mfay)**2)
Code: Alles auswählen
math.hypot(mfnx-mfax, mfny-mfay)
HWK
@derkay: "nan" == "not a number", dass bekommt man bei einigen Rechnungen, deren Ergebnis nicht definiert sind, zum Beispiel wenn man versucht +unendlich und -unendlich zu addieren. Anscheinend gibt's das bei Dir auch wenn man von einer negativen Zahl die Wurzel zieht. Bei mir kommt an der Stelle eine Ausnahme (ValueError: math domain error).
Sinnvollerweise verwaltet man die (Mittel- und sonstigen) Punkte nicht nach Koordinaten getrennt, sondern z.B. als Tupel.
Dann lässt sich der Abstand zweier Punkte bspweise so berechnen:
Dann lässt sich der Abstand zweier Punkte bspweise so berechnen:
Code: Alles auswählen
>>> import math, operator
>>> dist = lambda a,b:math.hypot(*map(operator.sub,a,b))
>>> punkt_A = -23.3, 44.45
>>> punkt_B = 59.23, -22.35
>>> dist(punkt_A,punkt_B)
106.17646113899258
Ich glaube nicht, dass ein negativer Radikand das nan produziert. Da er immer brav ein abs() davor setzt (sogar, da wo es nicht nötig ist ), sehe ich nicht, wo das passieren sollte.BlackJack hat geschrieben:@derkay: "nan" == "not a number", dass bekommt man bei einigen Rechnungen, deren Ergebnis nicht definiert sind, zum Beispiel wenn man versucht +unendlich und -unendlich zu addieren. Anscheinend gibt's das bei Dir auch wenn man von einer negativen Zahl die Wurzel zieht. Bei mir kommt an der Stelle eine Ausnahme (ValueError: math domain error).
Welche Rechnung, in die nicht schon ein nan von vornherein eingeht, produziert denn ein nan? Ich schaffe höchstens einen Overflow-Error ...
soo, fertig ist das Teilstück zur Berechnung der Entfernung in Feldern :
Code: Alles auswählen
# -*- coding: utf-8 -*-
""" Modul zur Berechnung von Hexfeldobjekten"""
from math import sqrt, hypot
hexdic = {} # Dictionary (x,y) : x1,y1 ... x6,y6
nachbardic = {} # Dictionary Nachbarfelder
laenge = 20.0
spielreihen = 42
ungerade_spalten = 17
gerade_spalten = ungerade_spalten - 1
""" Funktion zur Berechnung der X,Y Koordinaten """
def berechne_felder (xpos, ypos) :
x1 = xpos
y1 = ypos
x2 = x1 + laenge
y2 = y1
x3 = x2 + (laenge/2.0)
y3 = y2 + ((laenge * sqrt(3.0)/2.0))
x4 = x2
y4 = (sqrt(3.0) * laenge) + y2
x5 = x1
y5 = y4
x6 = x1 - (laenge / 2.0)
y6 = y3
mittex = round((x1 + laenge /2.0),2)
mittey = round ((y3),2)
mitte = (mittex, mittey)
return x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6,mitte
""" Funktion zur Erstellung von Listen und Dictionarys der
gesamten Spielflaeche """
def erstelle_hexfeldobjekte (spielreihen, ungerade_spalten):
gerade_spalten = ungerade_spalten-1
xpos = xorg = 20
ypos = yorg = 10
xoffset = laenge * 1.5
yoffset = sqrt(3) * laenge
for reihe in range(spielreihen):
if reihe %2 == 0:
for feld in range (ungerade_spalten) :
feldid = (reihe+1,feld+1)
hexdic[feldid] = berechne_felder (xpos, ypos)
xpos = xpos + xoffset * 2
xpos = xorg + xoffset
ypos = ypos + yoffset / 2
else :
for feld in range (gerade_spalten) :
feldid = (reihe+1,feld+1)
hexdic[feldid] = berechne_felder (xpos, ypos)
xpos = xpos + xoffset * 2
xpos = xorg
ypos = ypos + yoffset / 2
""" Funktion zur Berechnung der Nachbarfelder eines Feldes aller Hexagone """
def berechne_nachbarfelder (hexdic):
""" _0_
5 / \1
4 \___/2
3
"""
zek = hexdic.keys() # zwischenergebnis keys
zew = [] # zwischenergebnis werte
for x in zek :
nf00 = x[0]-2
nf01 = x[1]
nf10 = x[0]-1
nf11 = x[1] + (1 - (x[0]%2))
nf20 = x[0]+1
nf21 = x[1] + (1 - (x[0]%2))
nf30 = x[0]+2
nf31 = x[1]
nf40 = x[0]+1
nf41 = x[1] - (x[0]%2)
nf50 = x[0]-1
nf51 = x[1] - ((x[0]%2)*1)
zew = [(nf00,nf01),(nf10,nf11),(nf20,nf21),(nf30,nf31),(nf40,nf41),(nf50,nf51)]
count = 0
for z in zew :
if zew [count][0] < 1 or zew [count][1] < 1 : zew [count] = (0,0)
if zew [count][0] > spielreihen or zew [count][1] > ungerade_spalten : zew [count] = (0,0)
count += 1
nachbardic [x] = zew
""" Funktion zur Berechnung der Entfernung Luftlinie Feldmitten """
def abstand_luft (feldalt, feldneu) :
mfax = hexdic [feldalt] [12] [0] # steht fuer mitte feld alt x
mfay = hexdic [feldalt] [12] [1] # steht fuer mitte feld alt y
mfnx = hexdic [feldneu] [12] [0] # steht fuer mitte feld neu x
mfny = hexdic [feldneu] [12] [1] # steht fuer mitte feld neu y
abstand = hypot(mfnx-mfax, mfny-mfay)
if abstand == 0 : abstand = 1
return abstand
""" Funktion zur Berechnung des kürzesten Nachbarfeldes zum Ziel """
""" ruft Funktion abstand_luft auf"""
def abstand_felder (feldalt, feldneu) :
bedingung = True
back = [] # liste rueckgabewerte entfernungen
felder_ziel = [] # liste mit den Feldern zum Zielfeld
while bedingung == True :
for i in nachbardic[feldalt] :
if i[0] < 1.0 or i[1] < 1.0 : back.append (0.0)
else : back.append (abstand_luft (i, (feldneu)))
ind = back.index (min (x for x in back if x > 0))
del back [0:6]
felder_ziel.append (nachbardic[feldalt][ind])
feldalt = nachbardic[feldalt][ind]
fax = feldalt[0] # steht fuer feld alt x
fay = feldalt[1] # steht fuer feld alt y
fnx = feldneu[0] # steht fuer feld neu x
fny = feldneu[1] # steht fuer feld neu y
if fax == fnx and fay == fny : bedingung = False
print len (felder_ziel)
print felder_ziel
return (len (felder_ziel), felder_ziel)
imac
20 Zoll
2,4 ghz
20 Zoll
2,4 ghz
@numerix: Schau mal genau hin, das "äussere" `abs()` umschliesst nur alles vor dem Minus. Da kommt bei mir besagter "math domain error" zustande, weil das "unter" der Wurzel bei den entsprechenden Koordinaten negativ wird.
Beispiel für "nan" ohne "nan" als Eingangswert hatte ich ja schon genannt:
Beispiel für "nan" ohne "nan" als Eingangswert hatte ich ja schon genannt:
Code: Alles auswählen
In [2]: inf = float('inf')
In [3]: inf - inf
Out[3]: nan
Das Minuszeichen (das da gar nicht hingehört) hatte ich übersehen. Dann ist klar, dass abs() hier nichts bringt.abstand = sqrt ((abs(mfnx-mfax)**2)-((abs(mfny-mfay))**2))
Aber nochmal zum "nan": Wenn ich für "nan" im Ergebnis zumindest ein "inf" brauche, dann stellt sich mir die Frage, wo hier ein "inf" entsteht. Ich hätte gerne mal eine "normale" Berechnung, in die nur Fließkommazahlen eingehen (und so scheint das hier ja zu sein), und trotzdem "nan" herauskommt.
In diesem Fall ist das einfach ein negativer Wert bei `math.sqrt()` der zum "nan" führt. Ob da ein "nan" oder eine Ausnahme kommt, hängt anscheinend davon ab, was die entsprechende C-Bibliothek macht. Die kann Exceptions auslösen (in Hardware), was dann in eine Ausnahme in Python umgesetzt wird, oder einfach "nan" liefern.
ok, der nächste Abschnit steht an, und auch diesen möchte ich OHNE
Gui programmieren. (das fällt mir nach wie vor richtig schwer)
Dennoch muß ich vorab wissen, was die GUI später überhaupt leisten
kann, damit ich jetzt keinen Blödsinn beginne.
Thema : Bewegung des Panzers in dem eigenen Feld (Drehung) und
Bewegung in ein neues Feld.
Rahmenbedingung 1:
- wenn sich ein Panzer dreht, dann verliert er einen Bewegungspunkt
- die Ausrichtung ändert sich
Rahmenbedingung 2:
- wenn sich der Panzer in ein neues Feld bewegt, dann verliert er
einen Bewegungspunkt (wir lassen die unterschiedlichen
Eigenschaften der Felder vorerst weg)
- der Panzer betritt ein neues Feld
Steuerung :
es werden drei verschiedene Buttons zur Verfügung stehen
1) Drehung nach links
2) Drehung nach rechts
3) Betreten des neuen Feldes
es wird eine Funktion programmiert, der folgende Attribute übergeben
werden :
- altesfeld
- gehen
- laufen
- ausrichtung
Was kann nun die GUI leisten ?
Ich hatte es mir so gedacht, dass ein Bild eines Panzers die Spielfigur
im Hexfeld darstellt. Meinetwegen kennzeichnet die Front des Panzers
auch gleichzeitig die Ausrichtung.
Kann ich nun dieses Bild ausrichten ?
Also bspweise um x Grad nach rechts einfügen ?
Gruß
Kai
Gui programmieren. (das fällt mir nach wie vor richtig schwer)
Dennoch muß ich vorab wissen, was die GUI später überhaupt leisten
kann, damit ich jetzt keinen Blödsinn beginne.
Thema : Bewegung des Panzers in dem eigenen Feld (Drehung) und
Bewegung in ein neues Feld.
Rahmenbedingung 1:
- wenn sich ein Panzer dreht, dann verliert er einen Bewegungspunkt
- die Ausrichtung ändert sich
Rahmenbedingung 2:
- wenn sich der Panzer in ein neues Feld bewegt, dann verliert er
einen Bewegungspunkt (wir lassen die unterschiedlichen
Eigenschaften der Felder vorerst weg)
- der Panzer betritt ein neues Feld
Steuerung :
es werden drei verschiedene Buttons zur Verfügung stehen
1) Drehung nach links
2) Drehung nach rechts
3) Betreten des neuen Feldes
es wird eine Funktion programmiert, der folgende Attribute übergeben
werden :
- altesfeld
- gehen
- laufen
- ausrichtung
Was kann nun die GUI leisten ?
Ich hatte es mir so gedacht, dass ein Bild eines Panzers die Spielfigur
im Hexfeld darstellt. Meinetwegen kennzeichnet die Front des Panzers
auch gleichzeitig die Ausrichtung.
Kann ich nun dieses Bild ausrichten ?
Also bspweise um x Grad nach rechts einfügen ?
Gruß
Kai
imac
20 Zoll
2,4 ghz
20 Zoll
2,4 ghz
ach so, noch eine Frage.
die bisherigen Funktionen dienten ganz allgemein der Berechnung
irgendwelcher Dinge.
Die Bewegung eines Panzers kommt jedoch häufig vor und ist
speziell für jeden im Spiel befindlichen Panzer.
Würde es daher Sinn machen nun über eine Klasse Panzer nachzudenken,
bei deren Instanzierung die jeweiligen Daten / Variablen des Panzers übergeben werden ?
Kai
die bisherigen Funktionen dienten ganz allgemein der Berechnung
irgendwelcher Dinge.
Die Bewegung eines Panzers kommt jedoch häufig vor und ist
speziell für jeden im Spiel befindlichen Panzer.
Würde es daher Sinn machen nun über eine Klasse Panzer nachzudenken,
bei deren Instanzierung die jeweiligen Daten / Variablen des Panzers übergeben werden ?
Kai
imac
20 Zoll
2,4 ghz
20 Zoll
2,4 ghz
Ja und nein.Ich hatte es mir so gedacht, dass ein Bild eines Panzers die Spielfigur
im Hexfeld darstellt. Meinetwegen kennzeichnet die Front des Panzers
auch gleichzeitig die Ausrichtung.
Kann ich nun dieses Bild ausrichten ?
Also bspweise um x Grad nach rechts einfügen ?
Wenn die Panzerfigur manuell über Canvas-Methoden gezeichnet wird, dann kannst du ihn auch - z.B. um einen gedachten Mittelpunkt - drehen. Allerdings musst du die Konsequenzen für die Darstellung selbst errechnen und dann den Panzer entsprechend gedreht neu zeichnen. Wenn du dafür z.B. auf das frog- oder xturtle-Modul zurückgreifst, dann hast du es damit deutlich einfacher, weil die Methoden/Funktionen zum Drehen von frog/turtle mitbringen und diese wiederum eine benutzerdefinierte Form haben können (also z.B. ein Panzer-frog).
Wenn der Panzer als schon fertige Bilddatei eingebunden wird, dann geht mit dem Drehen gar nichts. Entweder müsstest du dann PIL mit verwenden (damit sollte das gehen - aber ohne Gewähr) oder du entwirfst dir mit einem Grafikprogramm einen ganzen Satz an Panzern mit verschiedener Ausrichtung (z.B. alle 10° einen) und lädtst dann jeweils das zur Ausrichtung passende Bild.
Hallo derkai
Ich habe mit deinem Code-Schnipsel etwas herumgespielt:
a) Testeingabe für das Spielfeld:
Ergibt folgende Hexagon-Konstellation:
Ich finde die Bezeichnungen 'spielreihen' und 'ungerade_spalten' ein wenig verwirrend. Ich gebe für 'spielreihen' = 4 und 'ungerade_spalten' = 4 ein und erhalte wohl 4 Reihen aber wie muss man dies mit den Spalten interpretieren?
b) Testeingabe für Abstand in Feldern:
Ergibt folgende Testantwort:
Anzahl Felder: 6
Pfad: [(2, 1), (1, 2), (2, 2), (1, 3), (2, 3), (1, 4)]
Das Feld 1,4 wird mit einen Zick-Zack Pfad über 6 Feldern gefunden
c) Testeingabe für Abstand in Feldern:
Ergibt folgende Exeption obwohl der Schlüssel 4,2 im 'hexdic' existiert. Hast du diesen Fehler auch ?:
Traceback (most recent call last):
File "kai_1243_test_prg.py", line 18, in <module>
abstand_felder ((1,1),(4,2))
File "/home/spy/Documents/python_download/battle_tech/start_14072008/kais_code_10082008/funktionen.py", line 143, in abstand_felder
else : back.append (abstand_luft (i, (feldneu)))
File "/home/spy/Documents/python_download/battle_tech/start_14072008/kais_code_10082008/funktionen.py", line 117, in abstand_luft
mfax = hexdic [feldalt] [12] [0] # steht fuer mitte feld alt x
KeyError: (5, 2)
Gruss wuf
Ich habe mit deinem Code-Schnipsel etwas herumgespielt:
a) Testeingabe für das Spielfeld:
Code: Alles auswählen
erstelle_hexfeldobjekte (4, 4)
Code: Alles auswählen
1,1 1,2 1,3 1,4
2,1 2,2 2,3
3,1 3,2 3,3 3,4
4,1 4,2 4,3
Ich finde die Bezeichnungen 'spielreihen' und 'ungerade_spalten' ein wenig verwirrend. Ich gebe für 'spielreihen' = 4 und 'ungerade_spalten' = 4 ein und erhalte wohl 4 Reihen aber wie muss man dies mit den Spalten interpretieren?
b) Testeingabe für Abstand in Feldern:
Code: Alles auswählen
abstand_felder ((1,1),(1,4))
Anzahl Felder: 6
Pfad: [(2, 1), (1, 2), (2, 2), (1, 3), (2, 3), (1, 4)]
Das Feld 1,4 wird mit einen Zick-Zack Pfad über 6 Feldern gefunden
c) Testeingabe für Abstand in Feldern:
Code: Alles auswählen
abstand_felder ((1,1),(4,2))
Traceback (most recent call last):
File "kai_1243_test_prg.py", line 18, in <module>
abstand_felder ((1,1),(4,2))
File "/home/spy/Documents/python_download/battle_tech/start_14072008/kais_code_10082008/funktionen.py", line 143, in abstand_felder
else : back.append (abstand_luft (i, (feldneu)))
File "/home/spy/Documents/python_download/battle_tech/start_14072008/kais_code_10082008/funktionen.py", line 117, in abstand_luft
mfax = hexdic [feldalt] [12] [0] # steht fuer mitte feld alt x
KeyError: (5, 2)
Gruss wuf
Take it easy Mates!
Hallo wuf,
1) das bei den Eingaben 1,1 - 1,4
6 Felder ausgegeben werden und ein zick, zack
Kurs erstellt wird entspricht genau der späteren
Bewegung des Panzers um dort hin zu gelangen.
Offen gesagt, es kommt hier eigentlich auch nur
darauf an, dass die Anzahl der Felder stimmt.
ich denke, hier ist alles ok
2) 1,1 - 4,2 erzeugt bei mir folgenden Pfad :
ich glaube auch hier ist alles OK
Einen Fehler erhalte ich nicht - komisch, woran mag das denn liegen ?
ich habe den Code schon wieder etwas umgeschrieben. Die funktion
gibt zuerst die Anzahl der Felder, dann den Pfad aus. Beachte die 2 in
der nächsten Spalte einfach noch nicht
3) tja ich weiss es nicht mehr ?
Ist die Summer der Innenwinkel nicht 720 Grad und somit je
Winkel 120 Grad ?
Gruß
der Kai
1) das bei den Eingaben 1,1 - 1,4
6 Felder ausgegeben werden und ein zick, zack
Kurs erstellt wird entspricht genau der späteren
Bewegung des Panzers um dort hin zu gelangen.
Offen gesagt, es kommt hier eigentlich auch nur
darauf an, dass die Anzahl der Felder stimmt.
ich denke, hier ist alles ok
2) 1,1 - 4,2 erzeugt bei mir folgenden Pfad :
Code: Alles auswählen
Python 2.5 (r25:51918, Sep 19 2006, 08:49:13)
[GCC 4.0.1 (Apple Computer, Inc. build 5341)] on darwin
Type "copyright", "credits" or "license()" for more information.
****************************************************************
Personal firewall software may warn about the connection IDLE
makes to its subprocess using this computer's internal loopback
interface. This connection is not visible on any external
interface and no data is sent to or received from the Internet.
****************************************************************
IDLE 1.2
>>> ================================ RESTART ================================
>>>
(3, [(2, 1), (3, 2), (4, 2)])
2
>>>
Einen Fehler erhalte ich nicht - komisch, woran mag das denn liegen ?
ich habe den Code schon wieder etwas umgeschrieben. Die funktion
gibt zuerst die Anzahl der Felder, dann den Pfad aus. Beachte die 2 in
der nächsten Spalte einfach noch nicht
3) tja ich weiss es nicht mehr ?
Ist die Summer der Innenwinkel nicht 720 Grad und somit je
Winkel 120 Grad ?
Gruß
der Kai
imac
20 Zoll
2,4 ghz
20 Zoll
2,4 ghz
ach so, noch die Erklärung :
Spielreihen ist die gesamt Anzahl der untereinander aufzubauenden
Reihen.
1
. 2
3
. 4
Da die Reihen 1, 3, 5 usw je ein Feld mehr haben als die Reihen
2, 4, 6 usw habe ich dies unterscheiden können wollen
Kai
Spielreihen ist die gesamt Anzahl der untereinander aufzubauenden
Reihen.
1
. 2
3
. 4
Da die Reihen 1, 3, 5 usw je ein Feld mehr haben als die Reihen
2, 4, 6 usw habe ich dies unterscheiden können wollen
Kai
imac
20 Zoll
2,4 ghz
20 Zoll
2,4 ghz
Hallo derkai
Betreffs Drehstellung des Panzers auf dem Hexagonfeld:
Es ist doch so, dass ein Panzer ein Hexagon-Spielfeld nur in sechs Richtungen verlassen kann.Somit kann ein Panzer nur sechs Stellungen einnehmen. Wenn wir die einzelnen Kanten des Hexagon im Uhrzeigersinn anschauen ergeben sich folgende sechs Stellungen:
a) 0 Grad (Kante Richtung Norden)
b) 60 Grad (Kante Richtung Nord-Ost)
c) 120 Grad (Kante Richtung Süd-Ost)
d) 180 Grad (Kante Richtung Süden)
e) 240 Grad (Kante Richtung Süd-West)
f) 300 Grad (Kante Richtung Nord-West)
Die Frage stellt sich auch noch im Zusammenhang der GUI-Programmierung. Da es bei Tkinter keine Grafik-Methode gib die ein Bildobjekt drehen kann braucht es für jede Richtung ein eigenes Image also insgesamt sechs Images pro Panzer!
Frage a:
Wenn der Panzer das Hexagon-Feld verlässt muss seine Frontseite (Kanone) in die gewählte Richtung zeigen?
Frage b:
Kann der Panzer auch rückwärts fahren?
Vielleicht könnest du dein Projekt-Katalog sukzessive mit den neuesten Erkenntnissen erweitern.
Gruss wuf
Edit: Habe die Sauerei mit den Umlauten bereinigt!
Betreffs Drehstellung des Panzers auf dem Hexagonfeld:
Es ist doch so, dass ein Panzer ein Hexagon-Spielfeld nur in sechs Richtungen verlassen kann.Somit kann ein Panzer nur sechs Stellungen einnehmen. Wenn wir die einzelnen Kanten des Hexagon im Uhrzeigersinn anschauen ergeben sich folgende sechs Stellungen:
a) 0 Grad (Kante Richtung Norden)
b) 60 Grad (Kante Richtung Nord-Ost)
c) 120 Grad (Kante Richtung Süd-Ost)
d) 180 Grad (Kante Richtung Süden)
e) 240 Grad (Kante Richtung Süd-West)
f) 300 Grad (Kante Richtung Nord-West)
Die Frage stellt sich auch noch im Zusammenhang der GUI-Programmierung. Da es bei Tkinter keine Grafik-Methode gib die ein Bildobjekt drehen kann braucht es für jede Richtung ein eigenes Image also insgesamt sechs Images pro Panzer!
Frage a:
Wenn der Panzer das Hexagon-Feld verlässt muss seine Frontseite (Kanone) in die gewählte Richtung zeigen?
Frage b:
Kann der Panzer auch rückwärts fahren?
Vielleicht könnest du dein Projekt-Katalog sukzessive mit den neuesten Erkenntnissen erweitern.
Gruss wuf
Edit: Habe die Sauerei mit den Umlauten bereinigt!
Zuletzt geändert von wuf am Montag 11. August 2008, 21:32, insgesamt 2-mal geändert.
Take it easy Mates!
Naja, wie ich schon weiter oben geschrieben habe, hängt das auch davon ab, ob fertige Panzer-Images als Grafikdateien verwendet werden sollen (für den Fall trifft deine Aussage zu) oder eben innerhalb des Canvas selbst gezeichnet werden (dann trifft sie nicht zu - dann lässt sich das alles berechnen).wuf hat geschrieben:Da es bei Tkinter keine Grafik-Methode gib die ein Bildobjekt drehen kann braucht es für jede Richtung ein eigenes Image also insgesamt sechs Images pro Panzer!