verdammt, ich kapier es einfach nicht

Fragen zu Tkinter.
derkai
User
Beiträge: 169
Registriert: Montag 12. Mai 2008, 11:43

Sonntag 27. Juli 2008, 15:52

schon einmal danke, ich guck es mir an :

trotzdem noch einmal meine Frage :
Wie kann ich aus einer For Schleife Namen und Instanzierungen einer Klasse Hexfeld erreichen.
Wie muss ich meine For Schleife ändern, damit ich nachher über den Namen einer Instanz eine Methode aufrufen kann ?

Kai

Code: Alles auswählen

from math import sqrt

class Hexfeld (object) :

    laenge = 20
   
    def __init__ (self, xpos, ypos):

        laenge = 20

        self.xpos = xpos
        self.ypos = ypos

     
    def berechne (self, xpos, ypos) :

        laenge = 20
        
        x1 = xpos
        y1 = ypos
        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

        return (x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6)

x = 0
y = 0


for x in ("a","b","c") :

    for y in ("d","e","f") :
        feld = x+y
        feld = Hexfeld(20,10)
        print feld.berechne(20,10), feld
"cf".berechne(20,10)

imac
20 Zoll
2,4 ghz
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Sonntag 27. Juli 2008, 16:49

Code: Alles auswählen

from math import sqrt

class Hexfeld (object) :

    laenge = 20
   
    def __init__ (self, xpos, ypos):

        laenge = 20

        self.xpos = xpos
        self.ypos = ypos

     
    def berechne (self, xpos, ypos) :

        laenge = 20
        
        x1 = xpos
        y1 = ypos
        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

        return (x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6)

x = 0
y = 0

felder = {}
for x in ("a","b","c") :
    for y in ("d","e","f") :
        name = x+y
        feld = Hexfeld(20,10)
        print feld.berechne(20,10), feld
        felder[name] = feld
felder["cf"].berechne(20,10)
derkai
User
Beiträge: 169
Registriert: Montag 12. Mai 2008, 11:43

Montag 28. Juli 2008, 19:11

ok, ich wäre bereit für den nächsten Schritt : die Ermittlung der Nachbarfelder eines Hexagon, um darüber dann Entfernungen zum Gegner berechnen zu können.

In einem meiner schlauen Bücher steht, dass man dabei wie folgt vorgehen könnte :

x1 x2 x3 x4
x1 0 1 1 0
x2 1 0 1 0
x3 1 1 0 1
x4 usw......

dann bildet man eine Liste der Elemte die miteinander verbunden sind :
L = [{0,1,1,0),(1,0,1,0), usw ....)]

Ich hoffe Ihr könnt nachvollziehen was ich meine.

Ich könnte mir dann eine Suche überlege, wie die Nachbarfelder miteinander verbunden sind. Den von BLACKJACK vorgeschlagenen A - Algorythmus habe ich zwar nicht verstanden, aber ich habe dann noch ein weiteres Problem :

Es wären Unmengen von Daten.

Habt Ihr vielleicht eine bessere Idee ?

Kai
imac
20 Zoll
2,4 ghz
derkai
User
Beiträge: 169
Registriert: Montag 12. Mai 2008, 11:43

Montag 28. Juli 2008, 19:13

keinen Code bitte, ich würde gerne selber grübeln, mir fehlt aber das
Handwerkszeug.

Kai
imac
20 Zoll
2,4 ghz
EyDu
User
Beiträge: 4871
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Montag 28. Juli 2008, 19:48

@derkai: Die Struktur die du suchst nenn sich "Graph". Den kannst du entweder als Adjazenzmatrix darstellen, so wie du es gerade machst, oder du speicherst an jedem Knoten (in deinem Fall ein Feld) die maximal sechs Nachbarn dex Hexagons. Beide Strukturen musst du natürlich automatisch generieren, falls du das mit "Unmenge von Daten" meinst.

Wenn Dir der A*-Algorithmus noch zu unübersichtlich ist, dann wirf einen Blick auf den Dijkstra-Algorithmus. Das ist ein Spezialfall das A* mit der Heuristik h(x) = 0.
Benutzeravatar
wuf
User
Beiträge: 1481
Registriert: Sonntag 8. Juni 2003, 09:50

Montag 28. Juli 2008, 20:42

Hallo derkai

Sorry meine idiotische Frage. Warum musst du die benachbarten Felder kennen, wenn der feindliche Panzer z.B. 20 Felder neben dem eigenen steht. Jedes Feld hat doch seine exakte Zentrum-Koordinate so musst du doch nur wissen auf welchem Feld der feindliche Panzer steht.

Gruss wuf :wink:
Take it easy Mates!
derkai
User
Beiträge: 169
Registriert: Montag 12. Mai 2008, 11:43

Montag 28. Juli 2008, 23:20

den Algorythmus schaue ich mir an, vielen Dank

@wuf
die Frage ist sogar sehr gut.

ich dachte zuerst auch, dass ich mit der Entfernung von xy von Freund zu Gegner weiterkommen würde - leider ist dem nicht so, da die Entfernung nicht der Anzahl der Felder entspricht.

Wie würdest Du denn sonst die Anzahl der Felder bestimmen ?

Nach dem von blackjack vorgeschlagenen Prinzip hatte ich es so verstanden, dass es um Knoten und Seitenlängen geht.
Daher auch meine Idee "Graph".
Dem zu Folge habe ich den code jetzt auch so geändert, dass ich auf die Angabe von Zeilen- und Feldnr. verzichten wollte und einfach eine Durchnummerierung von 1 ... vorgenommen habe.
Wenn ich nun aber alle und knapp 660 Felder so mit Knoten verbinden möchte, werde ich wahrscheinlich eine riesen "Latte" von Liste erhalten.
Meine Befürchtungen gehen dahin, dass die Performance leiden wird.
Das merke ich ja sogar schon jetzt, wenn ich mir die hexliste (also die Liste aller xy Koordinaten aller Hexfelder) am Bildschirm ausgeben lassen möchte.

Gruß
derkai

Wie gesagt, ich bin für alle Vorschläge offen.
imac
20 Zoll
2,4 ghz
EyDu
User
Beiträge: 4871
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Dienstag 29. Juli 2008, 08:22

Deshalb bietet es sich ja an, an einem Feld alle Knoten anzugeben die man erreichen kann. Das sind bei einem Hexagon nicht mal 6*n Einträge, wenn n die Anzahl der Felder ist. Auch eine Adjazenzliste mit 660 Knoten ist noch nicht all zu groß. Das sind um die 200000 Einträge, da du nur 660^2/2 Felder benötigst, wenn die Abstände symmetrisch sind. Am einfachsten ließe sich das wohl in einem Dictionary ablegen, mit den Schlüsseln der Form (a, b) mit a<=b, wobei a und b die IDs der Felder sind.

Aber mach Dir über die Performance zunächst nicht all zu viele Gedanken. Am Ende kannst du zur Not noch daran drehen, zu Beginn des Projekts macht es aber keinen Sinn.

P.S.: Es heißt Algorithmus, sogar im Englischen kommt kein y vor ;-)
derkai
User
Beiträge: 169
Registriert: Montag 12. Mai 2008, 11:43

Dienstag 29. Juli 2008, 17:30

jetzt muss ich aber EyDu noch einmal fragen.

Meinst Du meine Idee des Graph zu verfolgen und eine Liste aller miteinander verbundenen Felder zu erstellen, oder exakt für jedes Feld meine bestehendes Dicionary um die Angabe der jeweiligen Nachbarfelder mit aufzunehmen ?

Also :
- eigene Liste der Knotenpunkte aller Felder
- oder bestehende Liste je Feld um die Angabe der Nachbarfelder zu
erweitern ?

Kai
imac
20 Zoll
2,4 ghz
EyDu
User
Beiträge: 4871
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Dienstag 29. Juli 2008, 19:17

Jedes Hexagon bekommt einfach eine Liste von seinen Nachbarn:

Code: Alles auswählen

h0 = Hex()
h1 = Hex()
h2 = Hex()
h3 = Hex()

#h0 hat Nachbarn h1 und h2
h0.neighbours = [h1, h2]

#h1 hat Nachbarn h0, h2 und h3
h1.neighbours = [h0, h2, h3]

#h2 hat Nachbarn h0 und h3
h2.neighbours = [h0, h3]

#h3 hat Nachbarn h1 und h2
h3.neighbours = [h1, h2]
Der Aufbau enthält zwar ein wenig Redundanz, aber es lässt sich gut damit arbeiten.
Benutzeravatar
wuf
User
Beiträge: 1481
Registriert: Sonntag 8. Juni 2003, 09:50

Freitag 8. August 2008, 11:16

Hallo derkai

Ich nehme an du hast dein Battle-Game-Projekt noch nicht an den Nagel gehängt? :lol:

Gruss wuf :wink:
Take it easy Mates!
derkai
User
Beiträge: 169
Registriert: Montag 12. Mai 2008, 11:43

Samstag 9. August 2008, 10:25

nein, nein - ich bin fleissig dran -

es gäb da allerdings wieder ein weiteres kleines Problem :

ich habe eine Liste mit sechs Elementen :

[0.0, 0.0, 80.0, 120.0, 0.0, 0.0]

und brauche den Index des kleinsten Elementes, was größer
als Null ist.

Ich habe mir dazu die Funktion min angeschaut.
Die gibt mir natürlich aber immer die null zurück.

Kann man der Funktion min beibringen, dass sie das kleinste
Element, was größer als null ist zurückgeben soll ?

Kai
imac
20 Zoll
2,4 ghz
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Samstag 9. August 2008, 10:57

derkai hat geschrieben:es gäb da allerdings wieder ein weiteres kleines Problem :

ich habe eine Liste mit sechs Elementen :
[0.0, 0.0, 80.0, 120.0, 0.0, 0.0]
und brauche den Index des kleinsten Elementes, was größer als Null ist.

Code: Alles auswählen

>>> alt = [0.0, 0.0, 80.0, 120.0, 0.0, 0.0]
>>> neu = sorted(list(set(alt)))
>>> mini = neu[0] if abs(neu[0])>0.001 else neu[1]
>>> mini
80.0
EyDu
User
Beiträge: 4871
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Samstag 9. August 2008, 11:13

Einmal den Werte und einmal den Index:

Code: Alles auswählen

>>> l = [0.0, 0.0, 80.0, 120.0, 0.0, 0.0]
>>> min(x for x in l if x>0)
80.0
>>> min(i for (i,x) in enumerate(l) if x>0)
2
>>> 
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Samstag 9. August 2008, 11:33

Ups, den Index hatte ich vergessen.
Also dann noch eine Zeile ergänzen:

Code: Alles auswählen

alt = [0.0, 0.0, 80.0, 120.0, 0.0, 0.0]
neu = sorted(list(set(alt)))
mini = neu[0] if abs(neu[0])>0.001 else neu[1]
mini_index = alt.index(mini)
@EyDu:
Da hier mit Fließkommawerten gearbeitet wird, ist ein "x>0" nicht unproblematisch. Vielleicht sollte man ein "Epsilon" einbauen.

@derkai:
Im Übrigen ist die Aufgabenstellung nicht eindeutig: Was ist, wenn es mehrere gleiche Werte gibt, die alle die Bedingung "der kleinste Wert größer als Null" erfüllen? Brauchst du dann ALLE Indizes oder nur EINEN dieser Indizes und wenn letzteres zutrifft: Welchen dann?
Antworten