Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Array of Record mit Konstanten füllen (https://www.delphipraxis.net/75872-array-record-mit-konstanten-fuellen.html)

MarcoZ 26. Aug 2006 11:14


Array of Record mit Konstanten füllen
 
Hallo zusammen!

Stehe gerade irgendwie völlig auf dem Schlauch und bräuchte mal einen Denkanstoß. Für ein Kartenspiel möchte ich ein konstantes Array mit allen im Spiel vorhandenen Spielkarten erstellen. Dazu habe ich mir zwei Enums definiert: Eines hält die vier Farben, das andere die verfügbaren Werte. Weiterhin ein Record-Typ, der jeweils ein Feld vom Typ TFarben und TWerte enthält. Und von diesem Record-Typ möchte ich jetzt ein Array von 48 Elementen definieren, das lediglich die Karten enthält, sortiert nach der Standard-Trumpffolge, wie sie im Spiel sortiert sind. Aber ich bekomme die Klammerung nicht ganz hin: Entweder sind ihm zu wenig Klammern da, oder er meckert, dass 96 Elemente nicht den 48 angegebenen entsprechen.
:?
Hier mein Beispiel:

Delphi-Quellcode:
type
  TKartenfarbe = (Kreuz, Pik, Herz, Karo);
  TKartenWert = (Neun, Bube, Dame, Koenig, Zehn, Ass);
  tEinfacheSpielkarte = record
    Farbe: TKartenfarbe;
    Wert: TKartenWert;
  end;
const
  KartenImSpiel = 48;
  AlleKarten : array[1..KartenImSpiel] of tEinfacheSpielkarte = (
    ((Farbe:Herz), (Wert:Zehn)),
    ((Farbe:Herz), (Wert:Zehn)),
...
   ((Farbe:Herz), (Wert:Neun)),
    ((Farbe:Herz), (Wert:Neun))
  );
Hat irgendjemand hierzu eine Idee? In der Form habe ich das noch nie gemacht und bin irgendwie gerade ganz :?

Vielen Dank im Voraus!

Herzliche Grüße
Marco

Hawkeye219 26. Aug 2006 11:30

Re: Array of Record mit Konstanten füllen
 
Hallo Marco,

versuche es so:

Delphi-Quellcode:
...
(Farbe:Herz; Wert:Zehn),
...
Gruß Hawkeye

Jürgen Thomas 26. Aug 2006 11:38

Re: Array of Record mit Konstanten füllen
 
Hallo Marco,

an dieser Stelle wiederholen sich bei einer konstanten Deklarierung viele Begriffe (Farben und Werte) ständig. Ich würde deshalb sowieso vorschlagen, die Initialisierung zur Laufzeit durch eine Prozedur in drei verschachtelten Schleifen zu erledigen:
Delphi-Quellcode:
var x1, x2, i1: integer;
//  die ersten 24 Karten registrieren
for x1 := Low(TKartenfarbe) to High(TKartenfarbe) do
begin
  for x2 := Low(TKartenWert) to High(TKartenWert) do
  begin
    //  die folgende Index-Berechnung noch genau prüfen!!!
    i1 := (x1+1)*6 + x2 + 1;
    AlleKarten[i1].Farbe := TKartenfarbe(x1);
    AlleKarten[i1].Wert := TKartenWert(x2);
  end;
end;
//  jetzt jede Karte verdoppeln
for x1 := 1 to 24 do
begin
  AlleKarten[x1+24].Farbe := AlleKarten[x1].Farbe;
  AlleKarten[x1+24].Wert := AlleKarten[x1].Wert;
end;
(auf die Schnelle skizziert ohne Test; z.B. weiß ich jetzt nicht mehr: müssen die Laufindizes als integer oder als TKartenfarbe/TKartenWert deklariert werden? funktionieren low/high an dieser Stelle? je nachdem sind die Schleifen und die Zuweisungen zu ändern. Bitte habe Verständnis für meine Unsicherheit...)

Aber grundsätzlich sollte das so funktionieren (und umgeht das Problem der Klammerung). Jürgen

MarcoZ 26. Aug 2006 12:23

Re: Array of Record mit Konstanten füllen
 
Hallo Hawkeye,

Zitat:

Zitat von Hawkeye219
versuche es so:

Delphi-Quellcode:
...
(Farbe:Herz; Wert:Zehn),
...

Danke, das hat funktioniert! Wusste doch, dass es nur so was in der Richtung sein konnte! :-D

Grüße
Marco

Hawkeye219 26. Aug 2006 12:24

Re: Array of Record mit Konstanten füllen
 
Jürgens Vorschlag, die Initialisierung per Code durchzuführen, ist insbesondere bei größeren Strukturen sinnvoll. Wichtig ist es dabei, das Schreiben von initialisierten Konstanten in den Compiler-Optionen zu aktivieren. Alternativ kann das Array in den VAR-Bereich verschoben werden. Die Prüfung der Indexberechnung entfällt, wenn der Index in jedem Schritt inkrementiert wird.

Sollen - wie in Marcos Beispiel angegeben - zwei gleiche Karten im Array hintereinander abgelegt werden, kann folgender Code benutzt werden:

Delphi-Quellcode:
var
  Farbe : TKartenfarbe;
  Wert : TKartenWert;
  Index : Integer;
begin
  Index := Low(AlleKarten);
  for Farbe := Low(Farbe) to High(Farbe) do
    for Wert := Low(Wert) to High(Wert) do
      begin
        AlleKarten[Index].Farbe := Farbe;
        AlleKarten[Index].Wert := Wert;
        Inc (Index);
        AlleKarten[Index].Farbe := Farbe;
        AlleKarten[Index].Wert := Wert;
        Inc (Index);
      end;
end;
Jürgen geht davon aus, daß zwei identische Kartenstapel hintereinander im Array abgelegt werden. Dies geht mit folgendem Code:

Delphi-Quellcode:
var
  Stapel : Integer;
  Farbe : TKartenfarbe;
  Wert : TKartenWert;
  Index : Integer;
begin
  Index := Low(AlleKarten);
  for Stapel := 1 to 2 do
    for Farbe := Low(Farbe) to High(Farbe) do
      for Wert := Low(Wert) to High(Wert) do
        begin
          AlleKarten[Index].Farbe := Farbe;
          AlleKarten[Index].Wert := Wert;
          Inc (Index);
        end;
end;
Beim zweiten Code könnte man auf die äußere Schleife verzichten und die Kopie des ersten Stapels durch einen Move-Befehl erzeugen. Die dazu notwendigen Parameter (Zielindex und Umfang der Daten) müssen dann allerdings bei einer Änderung der Sets angepaßt werden.

Gruß Hawkeye

MarcoZ 26. Aug 2006 12:28

Re: Array of Record mit Konstanten füllen
 
Hallo Jürgen!

Zitat:

Zitat von Jürgen Thomas
an dieser Stelle wiederholen sich bei einer konstanten Deklarierung viele Begriffe (Farben und Werte) ständig. Ich würde deshalb sowieso vorschlagen, die Initialisierung zur Laufzeit durch eine Prozedur in drei verschachtelten Schleifen zu erledigen:

Danke Dir für Deinen Vorschlag! Das Problem ist, dass ich die Karten in einer ganz bestimmten Reihenfolge möchte (für ein Doppelkopfspiel), und deshalb eine rein farborientierte auf- oder absteigende Sortierung nur bei bestimmten Soli nützlich ist (Fleischlos). Ansonsten hat Doppelkopf eine recht eigenwillige Trumpfreihenfolge, beginnend mit den beiden Herz-Zehnen, gefolgt von allen Damen in der Farbreihenfolge Kreuz, Pik, herz und Karo, gefolgt von allen Buben, gefolgt von allen restlichen Karos, beginnend bei Ass, Zehn, König, Neun. Dann kommen alle Fehlfarben (Ass, Zehn, König, Neun) in den Farben Kreuz, Pik und Herz (bei Herz entfällt natürlich die Zehn). Und die möchte ich in der ursprünglichen Aufzählung einhalten. Und dabei fällt der schleifenorientierte Algoritmus natürlich in dem Moment vornüber, wo er auf die Karo-Zehn trifft. ;-) Nur, wenn es um diese soli geht möchte ich die Sortierung ändern.
Und dabei werden mir Deine Ideen zu gegebener Zeit sicher helfen!

Viele Grüße
Marco

Jürgen Thomas 26. Aug 2006 13:10

Re: Array of Record mit Konstanten füllen
 
@Marco2,
ich bin davon ausgegangen, dass Du zunächst nur alle Karten registrieren wolltest, aber die Trumpf-Reihenfolge hier noch keine Rolle spielen sollte; anschließend würden die Karten ja sowieso gemischt werden. Aber wenn Du das anders steuerst, spielt die Reihenfolge bei der Initialisierung natürlich eine Rolle. (Auch das wäre mit Schleifen möglich, aber dann ist die Verschachtelung genauer festzulegen.)

@Hawkeye219
Grundsätzlich geht es natürlich auch nach Deinem Vorschlag (das ist eher eine Geschmacksfrage). Aber es ist zumindest gefährlich, den Variablen den gleichen Namen wie den Record-Feldern zu geben.

Gruß Jürgen

MarcoZ 26. Aug 2006 13:23

Re: Array of Record mit Konstanten füllen
 
Hallo Jürgen,

Zitat:

Zitat von Jürgen Thomas
Ich bin davon ausgegangen, dass Du zunächst nur alle Karten registrieren wolltest, aber die Trumpf-Reihenfolge hier noch keine Rolle spielen sollte; anschließend würden die Karten ja sowieso gemischt werden.

Du hast recht, eine Vorsortierung bringt mir in diesem Fall wirklich kaum was. Zumal ich dem Benutzer die Kartn dann ja auch richtig sortiert auf die Hand geben will.
OK, ich werde esjetzt tatsächlich nach Deinem Vorschlag machen und das Array als Variable mit schleifen initialisieren. Das bringt mir jetzt, wo ich mich einen Vormittag damit beschäftigt habe, sogar noch ein paar andere Vorteile mehr... :-D

Viele Grüße
Marco


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:24 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz