Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - procedure soll mehrere werte zurückliefern


nkp90 - Mi 18.06.08 17:01
Titel: procedure soll mehrere werte zurückliefern
und zwar wöllt ich ne procedure/function machen um für ein creep den schnellsten weg zu finden von einem punkt zum anderen (pathfinding halt ^^)

1. wie beschreibt man diese procedure/function so dasss diese 2 oder mehr werte wieder zurückgibt?

bissl noch was: man hat x und y koordinate vom creep gegeben und wo das ziel is (x und y halt, und man weiß wie die karte aussieht, dh wo hindernisse stehen oder nicht ^^)

anfänglich hätte ich so was gemacht wie: procedure Tcreep.findpath(xs,ys,xz,yz:integer);

aber ich weiß nicht wie ich dann das ausgrechnete zurüückgeben kann ...



ps: gibts auch methoden wo der weg der als schnellster ausgerechnet wurde gespeichert wird somit der mob dort immer lang rennt? (ich weiß A* und so ... aber geht das auch ohne dem?^^)
(als 2. frage --> 2.)

Moderiert von user profile iconNarses: Topic aus Algorithmen, Optimierung und Assembler verschoben am Mi 18.06.2008 um 18:02


Narses - Mi 18.06.08 17:05

Moin und :welcome: im Forum!

bitte ändere den Titel des Topics, da er wenig über das eigentlich Thema verrät. Vorschlag: "procedure soll Werte zurückliefern" :nixweiss:

Hier der entsprechende Absatz aus den Richtlinien [http://www.entwickler-ecke.de/richtlinien.html]:

1.2 Beiträge:
Bitte formuliere den Betreff Deiner Beiträge so, dass andere Mitglieder anhand dieser bereits das eigentliche Thema festmachen können. Beiträge wie etwa "Eine Anfängerfrage" oder "Weiß jemand, wie das geht?" lassen den Leser im Unklaren darüber, was das Thema der Diskussion ist.[...]


Einfach oben bei Deinem ersten Beitrag auf user defined image oder user defined image klicken und den Titel ändern. Danke Dir!

btw: Bitte nicht mehr als eine Frage pro Thread, sonst wird das "unübersichtlich" und wir müssen den Thread schließen. ;)

cu
Narses


g1o2k4 - Mi 18.06.08 18:29

schau dir mal records an damit kann man leicht mehrere werte zurückliefern. oder mit arrays.


Gausi - Mi 18.06.08 18:30

Alternativ kannst du mit var- oder out-Parametern arbeiten.


BenBE - Mi 18.06.08 20:06

Oder im Falle von Variabler Anzahl gleichartiger Rückgabewerte EIN dynamisches Array zurückgeben.


Hidden - Mi 18.06.08 21:29

user profile iconBenBE hat folgendes geschrieben:
Oder im Falle von Variabler Anzahl gleichartiger Rückgabewerte EIN dynamisches Array zurückgeben.
Oder auch einen varianten record damit gehen auch unterschiedliche Rückgabewerte.


oldmax - Do 19.06.08 08:52

Hi
Sicherlich kann man aus Proceduren auch Werte zurückbekommen, aber ich halte es nach wie vor nicht elegant. Dafür hat mal ein schlauer Erfinder die Function vorgesehen. Was spricht für eine Typisierung des Rückgabewertes. Wo doch klar ist, das es sich um einen Punkt handelt (x- y Koordinatte) sollte auch ein TPoint die richtige Lösung sein.
Function TMyForm.New_Point( OldPoint :TPoint):TPoint;
Soweit ich weiß, ist TPoint bereits definiert


Delphi-Quelltext
1:
2:
3:
4:
5:
Type 
             TPoint = Record
                  x : LongInt;
                  y : LongInt;
             end;

Über die Variablendeklaration geht

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
Var
  ....
  MyPoint   : TPoint;

  .....
Procedure TMyForm.Initialisiere;
Begin
  MyPoint.x:=23243;
  MyPoint.Y:=23123; 
end;

Ich denke, wenn es solche vordefinierten geeigneten Variablentypen gibt, sollte man diese auch benutzen. Außerdem sieht man auch sehr deutlich, das man sich für alles mögliche auch geeignete Variablentypen selbst zusammenstellen kann.
Gruß oldmax


baka0815 - Do 19.06.08 09:14

Naja, er möchte ja den Weg zurück kriegen und nicht nur einen einzelnen Punkt.

Man könnte hier natürlich ein Array oder eine Liste von Punkten zurückgeben lassen. Die Reihenfolge der Einträge ist dann entsprechend der Weg.


BenBE - Do 19.06.08 09:38

user profile iconoldmax hat folgendes geschrieben:

Delphi-Quelltext
1:
2:
3:
4:
5:
Type 
             TPoint = Record
                  x : LongInt;
                  y : LongInt;
             end;

Über die Variablendeklaration geht

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
Var
  ....
  MyPoint   : TPoint;

  .....
Procedure TMyForm.Initialisiere;
Begin
  MyPoint.x:=23243;
  MyPoint.Y:=23123; 
end;

Bloß nicht mit globalen Variablen arbeiten!!! Dann lieber Var\Out-Parameter oder gar eine ordinäre Funktion, ABER in keinem Fall globale Variablen für die Rückgabe eines Wertes nutzen!!! Wenn man sauber programmiert ist JEDE Funktion reentrant - das geht einem durch so nen Scheiß SOFORT!!! verloren!


baka0815 - Do 19.06.08 09:51

Huch, gar nicht gesehen.

Da kann ich Ben nur voll unterstützen!

Habe hier gerade Sourcecode am Wickel bei dem es hunderte(!) von globalen Variablen gibt, die dann lustig von Funktionen und Prozeduren gelesen und geschrieben werden - das zu verfolgen ist wirklich grausam.

Was jedoch für (einige, wenige(!)) globale Einstellungen funktionieren mag, sollte für Rückgabewerte definitiv nicht verwendet werden.
Man könnte das ganze in ein Objekt kapseln und eine Objekt-lokale (als private deklarierte) Variable verwenden, aber nicht global.
Irgendwann schreibt irgendwer auf jeden Fall von wo anders da rein und dann geht gar nichts mehr :)


Fabian E. - Do 19.06.08 11:15

Wenn du doch schon eine Klasse TCreep hast, warum lässt du die Methode dass dann nicht direkt intern auswerten?
Dann brauchst du auch nichts zurück geben.


oldmax - Do 19.06.08 11:40

hi
Sorry, sollte nur ein Beispiel für den Zugriff auf die einzelnen Elemete des Records sein. Ist mir heut morgen bei der oberflächlichen Betrachtung gar nicht bewußt gewesen, das es in Richtung globale Variable verstanden werden kann. :shock:
gruß oldmax


nkp90 - Do 19.06.08 14:25

erst ma danke für die vielen antworten :)

und wenn ich mir das so durchgelesen hab bin ich der meinung das ich ein record erstellen werde das gleich in TCreep drin is und dann in dieser unit das ganze berechnen lasse ^^... so brauch ich kein rückgabe-wert und hab trotzdem das ergebniss ^^

aber das mit den globalen variablen und so was ihr dort mit ins spiel geworfen habt verwirrt mich etwas... globale variablen sind doch das worauf von jeder unit aus darauf zugegriffen werden kann? wenn ja ... is doch nicht so schlimm wenn es von mehreren proceduren bearbeitet werden kann? oder täusch ich mich da^^?

mfg


baka0815 - Do 19.06.08 15:56

Solang dein Programm klein ist und nur aus wenigen Units und Funktionen besteht, mag das alles kein Problem sein.
Wenn dein Programm jedoch wächst, kann es sein, dass du irgendwann vergisst, welche Funktion unter welchen Umständen in welche globale Variable schreibt und bekommst auf einmal Seiteneffekte die du dir nicht erklären kannst.

Wenn du dann 30 Units à 1.500 Zeilen Code hast ... viel Spaß beim Suchen ;)


nkp90 - Do 19.06.08 16:15

aso ^^

ne so viel code hab ich noch net .. aber ma sehen wie weit wir kommen :P

ty


delfiphan - Do 19.06.08 17:08

Da gibt es unzählige Möglichkeiten. Je nach Fall und Grösse der Rückgabe:Pointer und globale Variablen erwähne ich jetzt nicht ;)


hansa - Do 19.06.08 18:56

Da gibts wirklich viele Möglichkeiten. Was noch fehlt sind Form-basierende Variablen. Also solche im private Abschnitt deklarierte. Nur die eine Form kann die dann benutzen. Vorteil : die (eventuell lange) Parameterliste entfällt.


alzaimar - Do 19.06.08 19:50

user profile iconhansa hat folgendes geschrieben:
Vorteil : die (eventuell lange) Parameterliste entfällt.

In Zeiten von Code Completion kein großer Vorteil.

Ich plädiere für klare Formen und Parameter. Funktionen liefern etwas, Prozeduren führen Aktionen aus. Wenn eine Aktion bzw. Prozedur die Änderung von Werten mit sich zieht, wird der (Var)Parameter eben verändert. Wieso sollte nur deshalb eine Funktion draus werden?

Beide Metapher können im Code friedlich nebeneinander koexistieren.

Eine Funktion kann eine Klasse liefern, oder einen Record. Ein Array ist theoretisch auch möglch nur fällt mir gerade kein Beispiel ein, wo eine Funktion ein Array liefert bzw. berechnet.

Letztendlich bleibt es jedem selbst überlassen, wie er seine Parameter ändert oder Werte zurückliefert. Persönlich finde ich die Methode mit privaten Feldern oder globalen Variablen nicht gut, ums mal sehr freundlich auszudrücken.


delfiphan - Do 19.06.08 20:20

user profile iconalzaimar hat folgendes geschrieben:
Eine Funktion kann eine Klasse liefern
Eine Klasse zurückliefern bringt nicht viel. Du meinst ein Objekt, d.h. eine Klasseninstanz ;) (die Vermischung mag ich nicht...)

user profile iconhansa hat folgendes geschrieben:
Persönlich finde ich die Methode mit privaten Feldern oder globalen Variablen nicht gut, ums mal sehr freundlich auszudrücken.
Da bin ich nicht einverstanden. Man kann ruhig eine Klasse haben mit einer Methode Calculate; die den Weg berechnet und im Objekt ablegt.

Das unterscheidet sich nicht wesentlich davon eine Liste zuerst mit Namen zu füllen und am Schluss mit Sort; zu sortieren und wieder auszulesen. Oder du macht bei den Indy's ein TIdHTTP().Get('http://www.delphi-forum.de') und liest den Inhalt über eine andere Methode wieder aus.

Es gibt sogar ein Design-Pattern (Command Pattern [http://en.wikipedia.org/wiki/Command_pattern]), wo man einzelne Befehle in einzelne Klassen packt. Dabei wird die Klasse zuerst instanziert, dann die Parameter über Properties gesetzt und am Schluss die Aktion (z.B. Berechnung) über eine Methode gestartet. Das Objekt verändert sich dann entweder selbst oder verändert ein anderes. Wenn das Resultat einigermassen komplex ist kannst du dann über die geeignete Methode das Resultat abholen, du kannst aber auch das Objekt unverändert an eine Grafikengine zum Rendern übergeben, das Objekt als XML serialisieren, was auch immer.


hansa - Do 19.06.08 22:45

Das hier ist falsch zitiert.

user profile icondelfiphan hat folgendes geschrieben:
user profile iconhansa hat folgendes geschrieben:
Persönlich finde ich die Methode mit privaten Feldern oder globalen Variablen nicht gut, ums mal sehr freundlich auszudrücken.


Das war Alzaimar und dem sind globale Variablen anscheinend auch suspekt. :mrgreen:

user profile iconalzaimar hat folgendes geschrieben:
user profile iconhansa hat folgendes geschrieben:
Vorteil : die (eventuell lange) Parameterliste entfällt.

In Zeiten von Code Completion kein großer Vorteil.


Was nützt denn eine mehrzeilige Parameterliste mit Code-Completion und dem Verwechseln der Parameter. Viel zu fehlerträchtig.


Hidden - Fr 20.06.08 19:00

user profile iconhansa hat folgendes geschrieben:
Was nützt denn eine mehrzeilige Parameterliste mit Code-Completion und dem Verwechseln der Parameter. Viel zu fehlerträchtig.
imho geht es um intuitive Bedienbarkeit deines Quelltextes. Eine Methode, die im Namen hat, was/welches Feld sie verändert, braucht das gewöhnlicherweise nicht und kann mit Feldvariablen der Klasse arbeiten.

Leider ist es aber teilweise so, dass Methoden "TuWas" heißen(original-Bezeichnung meines Info-Lehrers vor dem ganzen Kurs beim Erklären einer Sache, hatten nachher mit exakt dem Namen auch alle anderen :( )

mfG,


hansa - Fr 20.06.08 19:10

user profile iconHidden hat folgendes geschrieben:
..Eine Methode, die im Namen hat, was/welches Feld sie verändert, braucht das gewöhnlicherweise nicht und kann mit Feldvariablen der Klasse arbeiten...


Und ? Was habe ich vorher gesagt ?


Hidden - Fr 20.06.08 19:19

user profile iconhansa hat folgendes geschrieben:
Und ? Was habe ich vorher gesagt ?
Okay, tschuldigung :D habe ihc so nicht herausgelesen^^ Sieh es einfach als eine Bekräftigung deiner Aussage :wink:

mfG,