Autor Beitrag
DarkPrisma
Hält's aus hier
Beiträge: 11



BeitragVerfasst: Mi 09.06.10 13:42 
Hallo leude,

ich war grade dran eine Füll-Funktion für meinen Karten editor zu schreiben, als ich auf ein Problem traf das ich bisher nicht lösen konnte.
Der gedanke war recht einfach: Ich wollte die möglichkeit haben alle zusammenhängenden Felder mit einer bestimmten Textur eine andere Textur zuzuweisen.
Dazu dachte ich, bau ich mir eine kleine Recursive-Funktion auf die von dem Startpunkt, alle benachbarten Felder untersucht, von denen die Textur ändert und dann weiter sucht.

bis 50*50 Felder gehts gut, aber dann is ende. Dummerweise ist die Standardgröße 500*500 Felder. Seltsamerweise krieg ich keine Exception wenn ich nur nach oben, rechts und links suche.
Sobald ich nach unten suche bricht der bei X: 7 Y: 422 ab. Das ganze sieht so aus:

ausblenden volle Höhe C#-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:
        private void _fillMap()
        {
            this._findFields(49949910);
        }

        private int _getTextureIDByPosition(int X, int Y, int LayerIndex)
        {
            if (X >= 0 && Y >= 0 && X < this._map.MapSize.Width && Y < this._map.MapSize.Height)
            {
                return this._map.Tiles[X, Y, LayerIndex].Texture.TextureIndex;
            }
            return -1;
        }

        private void _findFields(int X, int Y, int CurrentTextureID)
        {
            this._changeFieldTexture(X, Y - 1, CurrentTextureID);
            this._changeFieldTexture(X, Y + 1, CurrentTextureID); // kommentiere ich das aus, geht es zwar aber nicht alle Felder werden durchsucht
            this._changeFieldTexture(X - 1, Y, CurrentTextureID);
            this._changeFieldTexture(X + 1, Y, CurrentTextureID);
        }

        private void _changeFieldTexture(int X, int Y, int CurrentTextureID)
        {
            int TextureID = this._getTextureIDByPosition(X,Y, this._layer);

            if (CurrentTextureID == TextureID && this.TextureID != TextureID)
            {
                System.Diagnostics.Debug.WriteLine("X: " + X + " Y: " + Y);
                this._map.Tiles[X, Y, this._layer].Texture.TextureIndex = this.TextureID;
                this._findFields(X, Y, CurrentTextureID);
            }
        }


jemand eine idee wieso er sich da aufhängt?
Bergmann89
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1742
Erhaltene Danke: 72

Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
BeitragVerfasst: Mi 09.06.10 14:12 
Hey,

das liegt daran, weil nicht genügend Speicher für den Stack reserviert wurde. Guck ma in den Projekteinstellungen, da kann man den erhöhen.
Projekt --> Optionen --> Linker --> Maximale Stackgröße

€: bei Delphi is das so, aber hab grad erst gecheckt, das es C# is. Da geht das aber bestimmt auch irgeendwo. Musste ma googeln.

MfG Bergmann

_________________
Ich weiß nicht viel, lern aber dafür umso schneller^^
fragnix
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Mi 09.06.10 14:24 
Moin,


user profile iconDarkPrisma hat folgendes geschrieben Zum zitierten Posting springen:

Seltsamerweise krieg ich keine Exception wenn ich nur nach oben, rechts und links suche.
Sobald ich nach unten suche bricht der bei X: 7 Y: 422 ab.


Naja, 500 mal 500 mal vier Richtungen ist halt zu viel. Nimm halt weniger Breite oder weniger Richtungen (was ja bei Dir funktioniert hat ;-) )

Du musst die Anzahl der Unteraufrufe verringern. Vorschläge:

1) _findFields entfernen, in _fillMap() und in _changeFieldTexture() die vier Richtungszeilen direkt einbauen. Ist doppelter Code, halbiert aber die Aufruftiefe.

2) Im Zweifelsfall wird alles vom ersten Feld aus gefüllt und damit aufgerufen. Daher die hohe Aufruftiefe. Willst Du bei beliebiger Größe einen StackOverflow vermeiden würde ich mit Listen statt mit Rekursion arbeiten. Also alle Nachbarfelder sofort prüfen und jene die in Frage kommen an eine Liste anfügen. Diese Liste in einer Schleife solange durchforsten und Elemente bearbeiten + löschen bis die Liste leer ist. Weitere Optimierung nach Geschmack.

Beste Grüße
Jörg