AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Array Zeile löschen

Ein Thema von VkPenguin · begonnen am 2. Mär 2012 · letzter Beitrag vom 7. Mär 2012
Antwort Antwort
Seite 1 von 3  1 23   
VkPenguin

Registriert seit: 23. Dez 2011
150 Beiträge
 
Delphi XE7 Architect
 
#1

Array Zeile löschen

  Alt 2. Mär 2012, 22:08
Hallo,
mit eurer Hilfe habe ich inzwischen einiges an meinem Projekt geschafft. Ich brauchte mich eine Weile nicht melden,kam ich gut vorwärts . Nun gibt es aber einen Fehler in meinem Programm, der mir schon seit Anfang an zu schaffen macht, den ich aber immer vor mir hergeschoben hab. Folgendes Problem: In meinem Spiel werden die Positionen und Eigenschaften von z.B. Gegnern in Arrays (of Record) gespeichert. Wenn nun einer von ihnen stirbt (Dat[X].Alive=False) soll die Zeile gelöscht werden und alle anderen um Platz zu sparen "eins aufrücken". Grundsätzlich funktioniert das auch, aber wenn mehrere Gegner gleichzeitig ins Jenseits befördert werden entstehen Fehler. Hier meine bisherige Technik:

Delphi-Quellcode:
  X:=0;
  For I:=1 To Gegneranzahl+X DO
  Begin
   if not Gegner[I-X].alive then
   Begin
    if ((I-X)<>Gegneranzahl) THEN
    Begin
     Gegner[I-X].Wert:=Gegner[Gegneranzahl].Wert;
     Gegner[I-X].Funktion:=Gegner[Gegneranzahl].Funktion;
     Gegner[I-X].PosX:=Gegner[Gegneranzahl].PosX;
     Gegner[I-X].PosY:=Gegner[Gegneranzahl].PosY;
     Gegner[I-X].breite:=Gegner[Gegneranzahl].breite;
     Gegner[I-X].hoehe:=Gegner[Gegneranzahl].hoehe;
     Gegner[I-X].Farbe:=Gegner[Gegneranzahl].Farbe;
     Gegner[I-X].Maxzeit:=Gegner[Gegneranzahl].Maxzeit;
     Gegner[I-X].Alter:=Gegner[Gegneranzahl].Alter;
     [...............]
    End;
    X:=X+1;
    Gegneranzahl:=Gegneranzahl-1;
   End;
  End;
In einigen Tutorials hab ich "Swap Values" kennengelernt, damit könnte man das ganze sicher etwas vereinfachen; ich konnte aber nichts dazu finden, was hieran falsch sein könnte. Hat jemand vielleicht eine Idee ?

Alternativ: Könnte ich nicht theoretisch auch einfach den letzten mit demjenigen, der gelöscht werden soll Tauschen (es sei den selbiger ist der letzte) und dann den letzten löschen?

Danke schoneinmal!

Geändert von VkPenguin ( 2. Mär 2012 um 22:11 Uhr)
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.380 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Array Zeile löschen

  Alt 2. Mär 2012, 22:12
Ist das ein statisches array?
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#3

AW: Array Zeile löschen

  Alt 2. Mär 2012, 22:17
Das und die Sortierung dürfte der Grund sein warum meist Listen bevorzugt werden.
Du könntest mehrfach 1 löschen oder umkopieren in ein initial leeres Array, wenn die Reihenfolge egal ist kannst Du auch wie von Dir bereits vorgeschlagen eine Lückenliste erstellen,auffüllen,löschen
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#4

AW: Array Zeile löschen

  Alt 2. Mär 2012, 22:28
@VkPenguin

Nur mal so, du kannst das auch so in einem Rutsch übergeben:

Gegner[I-X] := Gegner[Gegneranzahl]; Macht alles etwas übersichtlicher.

Und hier: http://www.delphipraxis.net/166529-f...heinander.html

Da ging es um Objekte, aber auch da wird Array von unnötigen Datensätzen befreit.

Geändert von Popov ( 2. Mär 2012 um 22:31 Uhr)
  Mit Zitat antworten Zitat
VkPenguin

Registriert seit: 23. Dez 2011
150 Beiträge
 
Delphi XE7 Architect
 
#5

AW: Array Zeile löschen

  Alt 4. Mär 2012, 14:40
Hallo, danke für eure Hilfe..

@ Bjoerk: Ja, ist es, bisher zumindest, später werde ich das aus Performancegründen vielleicht ändern.
@ Popov: Ah, das macht das ganze zumindest schon mal einfacher, Dankeschön für den Tipp.
@ Bummi: Da hast du wahrscheinlich recht. Ist es denn schwierig mein Programm auf die Verwendung von Listen umzubauen?

Kennt jemand zufällig ein gutes Tutorial, wie man Listen verwendet? Ansonsten werde ich mich mal umschauen..
  Mit Zitat antworten Zitat
Breager

Registriert seit: 18. Feb 2012
40 Beiträge
 
#6

AW: Array Zeile löschen

  Alt 5. Mär 2012, 18:34
Zitat von VkPenguin:
Ist es denn schwierig mein Programm auf die Verwendung von Listen umzubauen?
Nein. Listen sind zudem viel schneller und komfortabler als dynamische Arrays. Du musst nur darauf achten, den reservierten Speicher wieder freizugeben, ansonsten entsteht ein Speicherleck.

Hier ein einfaches Beispiel:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  PGegnerRecord = ^TGegnerRecord;
  TGegnerRecord = record
   Name:AnsiString;
   PosX:Integer;
   PosY:Integer;
   {...}
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

  Gegnerliste:TList;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
 Gegnerliste:=TList.Create;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
Var i:Integer;
Begin
 For i:=Gegnerliste.Count-1 downto 0 do //Löschen von Einträgen
    Dispose(PGegnerRecord(Gegnerliste.Items[i])); //Speicher wieder freigeben!

 Gegnerliste.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
Var GegnerRec:PGegnerRecord;
    index:Integer;
begin
 New(GegnerRec); //Speicher reservieren
 Gegnerliste.Add(GegnerRec);
 index:=Gegnerliste.Count;
 GegnerRec.Name:='Gegner'+IntToStr(index);
 GegnerRec.PosX:=index;
 GegnerRec.PosY:=30;
end;

procedure TForm1.Button2Click(Sender: TObject);
Var i:Integer;
begin
 For i:=0 to Gegnerliste.Count-1 do
     ShowMessage(TGegnerRecord(Gegnerliste[i]^).Name);
end;
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
39.664 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Array Zeile löschen

  Alt 5. Mär 2012, 20:02
Nein. Listen sind zudem viel schneller und komfortabler als dynamische Arrays. Du musst nur darauf achten, den reservierten Speicher wieder freizugeben, ansonsten entsteht ein Speicherleck.
Schneller nicht. Ordentlioch implementiert ist Beides etwa gleich schnell.

Aber Komfortabler auf jedenfall.

Nja, es wäre ja zu praktisch, wenn die Fragesteller ihre Delphi-Version mal verrraten würden.
Ab Delphi 2009 könnte man z.B. den Generics und einer generischen TList den Komfort nochmal wesentlich erhöhen.

Und was die Speicherlecks angeht:
Eine TObjectList, bzw. einer generischen TObjektList und mit OwnsObjects=True, würde man nochmal etweas mehr Sicherheit und Kompfort rausholen.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.400 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Array Zeile löschen

  Alt 6. Mär 2012, 07:24
Eine TObjectList, bzw. einer generischen TObjektList und mit OwnsObjects=True, würde man nochmal etweas mehr Sicherheit und Kompfort rausholen.
Dazu müsste man aus den Records aber erst Klassen machen
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.389 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: Array Zeile löschen

  Alt 6. Mär 2012, 08:32
Zum ursprünglichen Problem:
Delphi-Quellcode:
for i := Gegneranzahl downto 1 do
begin
  if not Gegner[i].alive then
  Begin
    if i < Gegneranzahl then
      Gegner[I] := Gegner[Gegneranzahl];
 
    Dec(Gegneranzahl);
  end;
end;
Die Umstellung von Records und Arrays auf Objekte und Objektlisten scheint hier sinnvoll. Der Aufwand dürfte sich in Grenzen halten.
Die Alternative mit TList und Pointern zu arbeiten, erfordert mindestens den selben Aufwand und ist nicht so komfortabel.

Geändert von Blup ( 6. Mär 2012 um 08:35 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
39.664 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Array Zeile löschen

  Alt 6. Mär 2012, 08:53
Dazu müsste man aus den Records aber erst Klassen machen
Jupp.

Die generische TList ist leider nur für die haltung von statischen Records, deren Daten man nicht ändert, bzw. die man nur im ganzen ändert.
Das Ändern einzelner Werte eines Records ist nicht (sehr unpraktsich) änderbar.
Und da sich hier ja bestimmte mindestens Werte wie PosX und PosY ändern werden...

Ich hatte mir damit beholfen, daß ich die TList<> erweiterte und ein Items einführte, welches den Pointer auf den Record und nicht eine Kopie Records zurückliefert.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:29 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf