Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

31

05.04.2013, 14:27

Kann kein Java, aber mein Versuch den Du mal testen könntest...

Java-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
 //wozu n?
 //public int[][] Floodfill(int x, int y, int n, int[][] Array1, int xZiel, int yZiel) {
 public int[][] Floodfill(int x, int y, int[][] Array1, int xZiel, int yZiel) {

    int[][] Array2 = new int[20][20]; //temp map
   
    //wurden nirgendwo benutzt...?
    //String Wert;
    //String[] WertBereich;

    Stack<String> stack = new Stack<String>();
    //stack.push(x + "," + y + "," + n);
    stack.push(x + "," + y); //add first entry

    while(!stack.isEmpty()) {

        ElementTeile = Element.split(",");//split entry
        x = Integer.parseInt(ElementTeile[0]);
        y = Integer.parseInt(ElementTeile[1]);
        //n = Integer.parseInt(ElementTeile[2]); //?
        
        Element = stack.pop(); //del entry
        Array2[x][y] = Array2[x][y] + 1; //set pathcost
        
        //hier notausgang einrichten!
        if (x == xZiel && y == yZiel) { 
        //exit while??? kenne den Befehl zum verlassen nicht
        // glaube er heisst 
            break;
        }
        
        if (x > 0) { //links
            if (Array1[x-1][y] == 0 && Array2[x-1][y] == 0) { //nur pushen wenn 'erreichbar'
                Array2[x-1][y] = Array2[x][y];
                stack.push((x-1) + "," + y);
            } // end if
        } // end if
            
        if (y > 0) { //oben
            if (Array1[x][y-1] == 0 && Array2[x][y-1] == 0) { //nur pushen wenn 'erreichbar'
                Array2[x][y-1] = Array2[x][y];
                stack.push(x + "," + (y-1));
            } // end if
        } // end if

        if (x < 19) { //ich würde hier vorschlagen eine Globale oder Klassenvariable 
                      //wie MapWidth oder ähnliches zu benutzen statt fixer Werte...
            if (Array1[x+1][y] == 0 && Array2[x+1][y] == 0) { //nur pushen wenn 'erreichbar'
                Array2[x+1][y] = Array2[x][y];
                stack.push((x+1) + "," + y);
            } // end if
        } // end if         

        if (y < 19) { //ich würde hier vorschlagen eine Globale oder Klassenvariable 
                      //wie MapHeight oder ähnliches zu benutzen statt fixer Werte...
            if (Array1[x][y+1] == 0 && Array2[x][y+1] == 0) { //nur pushen wenn 'erreichbar'
                Array2[x][y+1] = Array2[x][y];
                stack.push(x + "," + (y+1));
            } // end if
        } // end if         
        
    } // wend
    
    //da ich mich nicht auskenne; aber muss stack nicht noch gelöscht werden?
    //delete[] stack //?
    
    return Array2;
} // end function

Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von »EternalPain« (05.04.2013, 17:55) aus folgendem Grund: kleinere Korrekturen


MitgliedXYZ

Alter Hase

  • »MitgliedXYZ« ist der Autor dieses Themas

Beiträge: 1 369

Wohnort: Bayern

  • Private Nachricht senden

32

06.04.2013, 12:10

Danke das du dir die Mühe gemacht hast, aber ich brauch doch die Entfernungen im Array2, also sind die n Werte durchaus wichtig.
Mit was wird denn in deiner Variante Array2 gefüllt? Mit den Werten der Nachbarzelle? Ich glaube in meiner Variante bringt mir das nichts.

String Wert; //Muss "Element" heißen
String[] WertBereich; //Muss "ElementTeile" heißen (hab die Namen fürs Forum ungründlich geändert, ich benutze andere Namen, dachte aber die sind aussagekräftiger)

Und evtl. an die hier im Forum die sich mit Stack auskennen, muss man den Stack am Ende der Berechnung löschen?
Ich finde einfach keinen Grund warum mein Array leer bleibt...

33

06.04.2013, 12:18

n ist bei meinem Beispiel oben unnötig, die Entfernungen ergeben sich von selbst...
hast du es mal ausprobiert? funktioniert es? und wenn, sieh Dir die Ausgabe an...

Warum dein Code gar nicht geht erklärt sich vorallem hier:

Quellcode

1
2
3
4
5
6
7
8
9
         Element = stack.pop(); 'hier gibst Du das Element aus stack frei

         ElementTeile = Element.split(","); 'hier willst du ein element das nicht mehr existiert auseinandernehmen....

         x = Integer.parseInt(ElementTeile[0]);

         y = Integer.parseInt(ElementTeile[1]);

         n = Integer.parseInt(ElementTeile[2]);


mach stack.pop unter den split, könnte gehen...
solltest dir aber trotzdem mal ansehen und durchlesen was hier gepostet wird, sonst wird das hier ein Selbstgespräch...

Edit: sorry, mir ist jetzt erst klar wie das stack beispiel funktioniert... mit einer linkedlist wärs für mich einfacher... vergiss den Beistrag hier

MitgliedXYZ

Alter Hase

  • »MitgliedXYZ« ist der Autor dieses Themas

Beiträge: 1 369

Wohnort: Bayern

  • Private Nachricht senden

34

06.04.2013, 12:34

n ist bei meinem Beispiel oben unnötig, die Entfernungen ergeben sich von selbst...
hast du es mal ausprobiert? funktioniert es? und wenn, sieh Dir die Ausgabe an...


Ähm ok, aber in deinem Code ist doch die einzig "wichige" Funktion die ausgeführt wird Array2[x-1][y] = Array2[x][y]; aber jedes Array-Element hat zu Beginn den Wert 999, also passiert da auch wenig, ich glaube das würde mich nicht weiter bringen...
Warum dein Code gar nicht geht erklärt sich vorallem hier:

Quellcode

1
2
3
4
5
6
Element = stack.pop(); 'hier gibst Du das Element aus stack frei

mach stack.pop unter den split, könnte gehen...

Ich dachte ein Element aus dem Stack wird der Variable "Element" zugewiesen, das Stack-Element kann dann ruhig nicht mehr gespeichert sein, da es ja die Variable nun enthält, ich glaube
[code]Element = Stack.pop();Element.Split(...)

ist das selbe wie

Quellcode

1
ElementTeile[] = Stack.pop().Split(...)

falls das letztere so überhaupt funktioniert.

solltest dir aber trotzdem mal ansehen und durchlesen was hier gepostet wird, sonst wird das hier ein Selbstgespräch...


Ich habe natürlich alles gelesen, ich dachte mein Code ist auch richtig, wie er hier beschrieben worden ist, umgesetzt worden, zumindest Teilweise, aber eine Lösung für den aktuellen Codeausschnitt, oder einen Hinweis, wurde hier noch nicht gepostet.
Edit: sorry, mir ist jetzt erst klar wie das stack beispiel funktioniert... mit einer linkedlist wärs für mich einfacher... vergiss den Beistrag hier


Ok, aber würde es denn einen Unterschied machen, ob ich einen Stack benutze, oder eine Linkedlist?

Falls jemandem noch etwas einfällt wäre ich sehr dankbar.
Gruß,
MitgliedXYZ

Edit: Die Forensoftware hat die Zitate falsch formatiert
?(

TGGC

1x Rätselkönig

Beiträge: 1 799

Beruf: Software Entwickler

  • Private Nachricht senden

35

06.04.2013, 13:10

Edit: Die Forensoftware hat die Zitate falsch formatiert
Genau. Und dein Computer hat den Weg falsch berechnet. ;-)

36

06.04.2013, 13:13

Wie gesagt, kann kein Java...
Aber mein Beispiel oben funktioniert soweit... hab mir NetBeans mit JDK installiert und bisschen gespielt:

Java-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package pathfind;

//import java.awt.Point;
import java.util.Stack;
import java.io.*;




public class Pathfind {
    public void Pathfind(){}
    
    public int[][] Floodfill(int x, int y, int[][] Array1, int xZiel, int yZiel) {
        int[][] Array2 = new int[20][20]; //temp map
   
        //wurden nirgendwo benutzt...?
        String Element;
        String[] ElementTeile;

        Stack<String> stack = new Stack<String>();
        //stack.push(x + "," + y + "," + n);
        stack.push(x + "," + y); //add first entry

        while(!stack.isEmpty()) {
            
            Element = stack.pop(); //del entry
            ElementTeile = Element.split(",");//split entry
            x = Integer.parseInt(ElementTeile[0]);
            y = Integer.parseInt(ElementTeile[1]);
            //n = Integer.parseInt(ElementTeile[2]); //?
        
            
            Array2[x][y] = Array2[x][y] + 1; //set pathcost
        
            //hier notausgang einrichten!
            if (x == xZiel && y == yZiel) { 
            //exit while??? kenne den Befehl zum verlassen nicht
            // glaube er heisst 
                break;
            }
        
            if (x > 0) { //links
                if (Array1[x-1][y] == 0 && Array2[x-1][y] == 0) { //nur pushen wenn 'erreichbar'
                    Array2[x-1][y] = Array2[x][y];
                    stack.push((x-1) + "," + y);
                } // end if
            } // end if
            
            if (y > 0) { //oben
                if (Array1[x][y-1] == 0 && Array2[x][y-1] == 0) { //nur pushen wenn 'erreichbar'
                    Array2[x][y-1] = Array2[x][y];
                    stack.push(x + "," + (y-1));
                } // end if
            } // end if

            if (x < 19) { //ich würde hier vorschlagen eine Globale oder Klassenvariable 
                          //wie MapWidth oder ähnliches zu benutzen statt fixer Werte...
                if (Array1[x+1][y] == 0 && Array2[x+1][y] == 0) { //nur pushen wenn 'erreichbar'
                    Array2[x+1][y] = Array2[x][y];
                    stack.push((x+1) + "," + y);
                } // end if
            } // end if         

            if (y < 19) { //ich würde hier vorschlagen eine Globale oder Klassenvariable 
                          //wie MapHeight oder ähnliches zu benutzen statt fixer Werte...
                if (Array1[x][y+1] == 0 && Array2[x][y+1] == 0) { //nur pushen wenn 'erreichbar'
                    Array2[x][y+1] = Array2[x][y];
                    stack.push(x + "," + (y+1));
                } // end if
            } // end if         
        
        } // wend
    
        //da ich mich nicht auskenne; aber muss stack nicht noch gelöscht werden?
        //delete[] stack //?
    
        return Array2;
    } // end function

    public static void main(String[] args) {
        // TODO code application logic here
        Pathfind SPath = new Pathfind();
        
        int[][] Array1 = new int[20][20];
        int[][] Array2;
        int x;
        int y;
        
               
        Array2 = SPath.Floodfill(1,1,Array1,18,18);
        
        for (y = 0; y < 19; y++){
            for (x = 0; x < 19; x++){
                System.out.println(Array2[x][y]);
            }
            
        }
        
                
        
    }
}


Da ich bisschen Probleme mit Befehlen und Syntax von Java habe wäre es hilfreich wenn mir einer ein Beispiel posten könnte wie ich die Ausgabe besser gestalten kann?! jedenfalls zeigt das doch knappe Beispiel das es funktioniert....

Edit

Zitat

ich dachte mein Code ist auch richtig, wie er hier beschrieben worden ist, umgesetzt worden, zumindest Teilweise, aber eine Lösung für den aktuellen Codeausschnitt, oder einen Hinweis, wurde hier noch nicht gepostet.


Das ist der Selbe Code, nur angepasst...

das mit deiner 999 ist nicht nur umständlich als auch unnötig... (und eine zusätzliche schleife kostet nur unnötige Rechenzeit)
Wenn Erklärungen und Code Dir schon nicht helfen dann vielleicht ein bebildertes Beispiel wie der Code arbeitet?


(Link)




Hier noch ein schönes Beispiel wie der vorher noch von mir gepostete Code in Aktion funktioniert:
Labyrinth.exe

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »EternalPain« (06.04.2013, 14:10)


MitgliedXYZ

Alter Hase

  • »MitgliedXYZ« ist der Autor dieses Themas

Beiträge: 1 369

Wohnort: Bayern

  • Private Nachricht senden

37

06.04.2013, 15:58

Ok, du lieferst ja recht viele Beispiele mit, aber ist das wirklich der Code, den du hier gepostet hast?

Eigentlich weißt deine Methode doch nur der Nachbarzelle ihren eigenen Wert zu, woher dann die immer größeren Werte?

Quellcode

1
Array2[x-1][y] = Array2[x][y];

Eigentlich müsste doch, wenn das Array vorher leer war, auf jedem betretbaren Feld der Wert des Startfeld sein, oder?


Außerdem hat bei mir das Startfeld den Wert 0 statt eins, weil man ja 0 Schritte vom Start entfernt ist, bis auf das rechte untere Beispiel finde ich die Werte etwas komisch. Wenn es mehrere 1er gibt (und keine 0), woher weißt du dann, wo du gestartet bist? Und wieso wird im 4. Beispiel eine 1 durch eine 2 ersetzt?


Vielleicht habe ich dich aber auch nur falsch verstanden...
Genau. Und dein Computer hat den Weg falsch berechnet. ;-)

Ja, ich hätte die Zitate von Hand ausbessern können, im Editor war aber alles normal, erst beim Absenden ist irgendetwas verrutscht. Ist aber jetzt auch irgendwie Offtopic.

38

06.04.2013, 16:10

Zitat

Eigentlich weißt deine Methode doch nur der Nachbarzelle ihren eigenen Wert zu, woher dann die immer größeren Werte?


Ich weise dem 'freien' Nachbarfeld den Wert des aktuellen Feldes zu, quasi als markierung und um zu sagen, dieses Feld wurde von diesem Feld markiert...
Dannach geht diese Position in deinen stack

wie zB hier:

Quellcode

1
stack.push((x-1) + "," + y);


am anfang wird nur die Startposition in den Stack gepusht, dann schon zu beginn der Zeile
wird die position geholt:

Quellcode

1
Element = stack.pop();


Und hier wird der Wert der Zelle erhöht:

Quellcode

1
Array2[x][y] = Array2[x][y] + 1;


es gibt nur einmal eine 1, da die 1 nur das erste mal gespeichert wird...
dann wird 1 aber 4 mal (wenn möglich) weitergegeben, beim durchlauf der
schleife aber direkt erhöht, sind dann also 2
daher ist 1 der startwert, das vereinfacht die Sache

wenn du unbedingt den wert 0 haben willst, mach anschliessend bei der weiteren berechtnung sowas wie
wegkosten = array[x][y] -1

Denn 0 steht hier wie unbenutzt, daher ist es so einfacher... spart schleifen und variablen

und wenn du dann das Ziel erreicht hast, hast du dort einen wert, von den wert, gehst du dann
ganz ähnlich mit einer vier seiten suche aus, zum nächst kleineren wert der erreichbar ist bis du
bei 1 angekommen bist und BAM, fertig ist der Weg

MitgliedXYZ

Alter Hase

  • »MitgliedXYZ« ist der Autor dieses Themas

Beiträge: 1 369

Wohnort: Bayern

  • Private Nachricht senden

39

06.04.2013, 16:40

Ok, dann hab ich das nur falsch verstanden.

Die 0 als Startwert muss natürlich nicht sein, ich hab es halt so gemacht... Aber deine Bilder waren etwas verwirrend.


Ich hab jetzt einen kleinen Fehler in meinem Java-Code gefunden, die Abbruchbedingung war falsch, aber das Array bleibt immer noch leer.

Fehlerhafte Abbruchbedingung (bricht auch schon ab, wenn x = xZiel, auch wenn y anders ist):

Quellcode

1
 if (Array1[x][y] == 0 && Array2[x][y] > n && x != xZiel && y != yZiel)

Richtig muss es so lauten: (Mit neuer Methode "KoordinatenGleich")

Quellcode

1
if (Array1[x][y] == 0 && Array2[x][y] > n && KoordinatenGleich(x, y, xZiel, yZiel) == false)



Habe jetzt den selben Code noch einmal in C# geschrieben, habe meinen Java Code in VisualStudio kopiert, ein paar Elemente geändert (es gibt ja doch ein paar Sprachliche Unterschiede) und dann den Code getestet, nun bekomme ich ein volles Array zurück. Liegt also irgendwie an Java.


Deine Variante ist evtl. ein bisschen effizienter, aber ich glaube auf eine Variable kommt es dann auch nicht an...

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »MitgliedXYZ« (06.04.2013, 16:46)


TGGC

1x Rätselkönig

Beiträge: 1 799

Beruf: Software Entwickler

  • Private Nachricht senden

40

06.04.2013, 20:04

Liegt also irgendwie an Java.
Oh sorry, da hatte man wohl vergessen dir zu sagen, das Java kein Floodfill unterstuetzt.

Werbeanzeige