![]() |
Array an procedure übergeben
Hallo zusammen,
folgendes Problem: Ich habe ein dynamisches Array der Form
Delphi-Quellcode:
mit
type EKarte = record
name: string; ort: integer; status: integer; end;
Delphi-Quellcode:
und einem späteren
P1EKarte, P2EKarte: Array of Ekarte;
SetLength(P1EKarte,20). Jetzt möchte ich das Array mischen und mir dazu eine Prozedur "mischen" schreiben, die von 0 bis High(P1EKarte) läuft und die Einträge von 0 bis zum Ende mit einem zufälligen Eintrag vertauscht. Dazu benötige ich aber ein Dummyrecord vom Typ EKarte als Zwischenspeicher. Folgendes funktioniert schon mal nicht ;-)
Delphi-Quellcode:
Das Mischen selbst ist noch nicht implementiert, da ich hier bereits schon mit inkompatiblen Typen zu kämpfen habe.
procedure MixECards(PECards: Array of EKarte);
var CDummy: EKarte; ix: integer; begin For ix:=0 to High(PECards) do begin CDummy:=Copy(PECards, ix, 1); end; end; Gruß Kay [edit=sakura] [delphi]-Tags gesetzt. Mfg, sakura[/edit] |
Re: Array an procedure übergeben
Hallo Igotcha,
die Erklärung für dieses Phänomens sowie eine brauchbare Lösung solltest Du in dem Thread ![]() |
Re: Array an procedure übergeben
Zitat:
Willst du einfach die EKarte am Index ix in CDummy kopieren? Wenn ja dann so:
Delphi-Quellcode:
grüße, daniel
CDummy := PECards[ix];
|
Re: Array an procedure übergeben
Ja, beim Copy, stimmt.
CDummy := PECards[ix] funktioniert aber grundsätzlich. Ich habe aber noch einen völlig anderen Denkfehler drin ;-) Das Array wird so natürlich in der Procedure schön gemischt, aber mein Input-Array nicht. Ich benötige also folgendes:
Code:
oder
GemischtesArray:=MixECards(UngemischtesArray);
Code:
Wobei ein
P1EKarte:=MixEcards(P1EKarte);
Code:
Das bekomme ich aber auch nicht so recht hin...
P2EKarte:=MixEcards(P2EKarte) natürlich auch funktionieren sollte.
Gruß Kay |
Re: Array an procedure übergeben
Meinst du das so etwa ?
Delphi-Quellcode:
Type EKarte = Record
name: String; ort: Integer; status: Integer; End; AEKarte = Array of EKarte; Var P1EKarte: AEKarte; Procedure MixECards(Var PECards: AEKarte); Var CDummy: EKarte; ix, p1, p2: Integer; Begin //For ix := 0 to High(PECards) do // CDummy := PECards[ix]; For ix := 0 to 10000 do Begin p1 := Random(High(PECards)); //zu tauschende Karten ermitteln p2 := Random(High(PECards)); CDummy := PECards[p1]; //Karten tauschen PECards[p1] := PECards[p2] PECards[p2] := CDummy; End; End; ... MixECards(P1EKarte); |
Re: Array an procedure übergeben
Ich versuche es mal etwas ausführlicher:
Gegeben ist
Code:
Davon gibt es nun für die beiden Spieler
Type EKarte = Record
name: String; ort: Integer; status: Integer; End;
Code:
Diese beiden Arrays werden nun mit den Karten der Spieler geladen. Da es ist keine festgesetzte Anzahl von Karten gibt, wurde ein dynamisches Array verwendet (beim Laden wird mit Setlength jeweils die Endgröße der Arrays P1EKarte und P2EKarte bestimmt.
var
P1Ekarte, P2EKarte: Array of Ekarte Jetzt soll eine Funktion / Prozedur existieren, die die gefüllten Arrays "mischt". Nach dem Mischen sollen in den beiden Arrays jeweils die ursprünglichen Karten vorhanden sein, nur gemischt. Gesucht ist also ein Funktion / Prozedur "MixECards" in der Form:
Code:
die sich dann auch als
P1EKarte (gemischt) :=MixECards(P1Ekarte (ungemischt));
Code:
benutzen lassen sollte.
P2EKarte (gemischt) :=MixECards(P2Ekarte (ungemischt));
Wie schon geschrieben, ein Mischen innerhalb der Prozedur habe ich hinbekommen, nur blieb da mein Input-Array unverändert.
Code:
Bei einem MixEcards(P1EKarte) wurde praktisch "PECards" innerhalb der Prozedur gemischt, aber nicht "P1EKarte" als Ergebnis.
procedure MixECards(PECards: Array of EKarte);
begin ... end; Gruß Kay |
Re: Array an procedure übergeben
In dem Thread, auf den ich in meinem vorherigen Posting verwiesen habe, würdest Du etwas in der Art
Delphi-Quellcode:
finden...
type
TMyArray = array of TMyType; function MyFunc(const AParam: TMyArray): TMyArray; begin SetLength(Result, Length(AParam)); //... end; //... AnArray:= MyFunc(AnotherArray); |
Re: Array an procedure übergeben
Also dann so ?
Delphi-Quellcode:
Type EKarte = Record
name: String; ort: Integer; status: Integer; End; AEKarte = Array of EKarte; Var P1Ekarte, P2EKarte: AEKarte; Procedure MixECards(Var PECards: AEKarte); Var CDummy: EKarte; ix, p1, p2: Integer; Begin For ix := 0 to 10000 do Begin {je mehr Durchgänge, desto mehr wird gemischt} //2 Karten durch Zufall auswählen, die getauscht werden sollen p1 := Random(High(PECards)); p2 := Random(High(PECards)); //die Beiden ermittelten Karten austauschen CDummy := PECards[p1]; PECards[p1] := PECards[p2]; PECards[p2] := CDummy; End; End; IrgendeineProzedur/Funkktion; Begin ... {hier sind die Karten noch ungemischt} MixECards(P1EKarte); MixECards(P2EKarte); {und hier sind sie gemischt} ... End; Sowas ist doch nicht nötig:
Delphi-Quellcode:
Es geht doch so viel einfacher:
Function MixECards(PECards: AEKarte): AEKarte;
... P1EKarte := MixECards(P1EKarte); P2EKarte := MixECards(P2EKarte);
Delphi-Quellcode:
Die Angabe von VAR in der Parameterdeklaration der Prozedur gibt an, dass der übergebene Parameter geändert werden kann, daher ist auch der Umweg über ein zweites Array nicht nötig.
Procedure MixECards(Var PECards: AEKarte);
... MixECards(P1EKarte); MixECards(P2EKarte); |
Re: Array an procedure übergeben
Zitat:
Delphi-Quellcode:
Oh Mann, schwere Geburt, aber keine Typenfehler mehr ;-)
function MixECards(const AParam: EDummy): EDummy;
function MixECards(Var AParam: EDummy): EDummy; Vielen Dank Euch und ein frohes Fest... Gruß Kay |
Re: Array an procedure übergeben
Bitte ändere zunächst Deine Bezeichnungen. Typen, die mit einem großen "E" beginnen, haben in Delphi eine besondere Bedeutung...
Das Problem besteht erneut in den unterschiedlichen Typen TKarteArray (vormals EDummy) versus array of TKarte (vormals EKarte). Ändere einfach die Deklaration von P1EKarte entsprechend ab und es sollte funktionieren (abgesehen davon, dass Dir die Funktion MixCards (vormals MixECards) zwar ein Array der passenden größe allerdings mit nicht belegten Daten zurückgibt...). |
Re: Array an procedure übergeben
Delphi hat mit zwar gleichen Typendeklaration einige Progleme.
So geht es NICHT:
Delphi-Quellcode:
So dürfte es geh'n:
type EDummy = array of EKarte;
function MixECards(const AParam: EDummy): EDummy; var P1EKarte: Array of Ekarte; {P1EKarte <> AParam}
Delphi-Quellcode:
type EDummy = array of EKarte;
function MixECards(const AParam: EDummy): EDummy; var P1EKarte: EDummy; {P1EKarte = AParam} |
Re: Array an procedure übergeben
@choose:
Die Namen sind Delphi total egal. Diese "Vorgaben" für die Namensvergabe (das hast du bestimmt irgendwo gelesen) ist nur zum einfachen lesen/verständnis der Quellcodes gedacht und hat nichts mit der Funktion zu tun. Und das was Igotcha da geschrieben hat, sind mit Sicherheit nur Beispiele und sehen nicht im direkten Zusammenhang mit dem Prog. :wink: Ich halte mich auch nicht an diesen sogenanten "Standard", hab mir ein eigenes System zur Namensvergabe im laufe der Jahre angeeignet. |
Re: Array an procedure übergeben
Zitat:
Zitat:
Oder würdest Du hinter EConvertError eine Klasse zur Darstellung von Schachfiguren erwarten, deren Dartellungsmethode sinnigerweise Create heißt? Technisch machbar. Zitat:
|
Re: Array an procedure übergeben
Zitat:
Delphi-Quellcode:
In der Game-Unit ist deklariert
unit AKarten;
// Klasse der Aktionskarten interface uses DXDraws, DXClass,DXSprite, SysUtils, EKarten; Type TACard = class(TImageSpriteEx) // Felder private fname: String; // Kartenname; fed: String; // Kürzel der Edition, z.B. 'WC' fnummer: String; // Nummer der Karte, z.B. 39 fcid : integer; // lfd. Nummer im Stapel fcowner: integer; // Spieler, der die Karte besitzt // Methoden function getName: String; procedure setName(Name: String); function getED: String; procedure setED(Edition: String); function getNummer: String; procedure setNummer(Nummer: String); function getCID: integer; procedure setCID(CID: integer); function getCOwner: integer; procedure setCOwner(COwner: integer); public property Name: string read getName write setName; property Edition: string read getED write setED; property Nummer: string read getNummer write setNummer; property CID: integer read getCID write setCID; property COwner: integer read getCOwner write setCOwner; procedure DoMove(MoveCount: Integer);override; procedure DoCollision(Sprite: TSprite; var Done: Boolean);override; procedure LoadECard(Imagelist: TDXImageList); // Lädt das Bild der Karte end; implementation ... procedure TACard.LoadECard(ImageList: TDXImageList); var ix: integer; strCName: String; bImGFound: Boolean; begin bImgFound:=false; strCname:=fed+fnummer; for ix:=0 to Imagelist.Items.Count-1 do begin if Imagelist.Items.Items[ix].Name=strCName then begin bImgFound:=true; Break; end; end; if bIMgFound=false then begin ImageList.Items.Add; with ImageList.Items[ImageList.Items.Count-1] do begin Picture.LoadFromFile (MYPFAD+fed+'\small\'+fnummer+'.jpg'); fname:=strCName; Name := fname; PatternWidth := 0; PatternHeight := 0; SkipHeight := 0; SkipWidth := 0; SystemMemory := False; //Transparent := Transp; //TransparentColor := TranspColor; Restore; end; end; Image:=Imagelist.Items.Find(strCName); end;
Delphi-Quellcode:
und
type ADummy = array of TACard;
Delphi-Quellcode:
Erstellt werden die ADeck1-Objekte in einer Schleife mit:
ADeck1, AADeck1: ADummy;
Delphi-Quellcode:
Das Mischen der Karten funktioniert mit Eurer Hilfe nun super mit:
inc(iA);
SetLength(ADeck1,iA); ADeck1[iA-1]:=TACard.Create(frmMain.DXSpriteEngine1.Engine); ADeck1[iA-1].Edition:=strLeft(S,2); ADeck1[iA-1].Nummer:=strRight(S,Length(S)-2); ADeck1[iA-1].CID:=iA-1; ADeck1[iA-1].COwner:=0; ADeck1[iA-1].LoadECard(frmMain.DXCards); ADeck1[iA-1].Height:=127; ADeck1[iA-1].Width:=90; ADeck1[iA-1].X:=200+(iA*20); ADeck1[iA-1].Y:=250;
Delphi-Quellcode:
Wenn in der Mischroutine
function MixACards(Var AParam: ADummy): ADummy;
var CDummy: TACard; ix, ir: integer; begin SetLength(Result, Length(AParam)); for ix:=0 to High(AParam) do begin ir:=Random(High(AParam)); CDummy:=Aparam[ix]; AParam[ix]:=AParam[ir]; AParam[ir]:=CDummy; end; end;
Delphi-Quellcode:
funktioniert, warum klappt dann dies nicht?
AParam[ix]:=AParam[ir];
Delphi-Quellcode:
Der Compilerlauf ist fehlerfrei, jedoch bricht das Programm mit einem "Access-Violation" beim "Draw" der SpriteEngine ab. Kommentiere ich die Drei Zeilen aus, gibt es keine Probleme.
Setlength(AADeck1,1);
AADeck1[0]:=TACard.Create(frmMain.DXSpriteEngine1.Engine); AADeck1[0]:=ADeck1[High(ADeck1)]; Sorry, wenn das Ganze nun etwas länger geworden ist, aber ich bin ja lernwillig ;-) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:26 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz