Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Array (Spielkarten) sortieren


galagher - Do 29.04.10 19:42
Titel: Array (Spielkarten) sortieren
Hallo!

Ich möchte ein Spielkarten-Array sortieren, habe aber keine Idee, wie ich das fehlerfrei hinbekomme. Erst dachte ich, ich gehe das Array immer wieder durch und sortiere es so, um nach Farben zu sortieren:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
  n := 0;

  for i := 0 to High(plHuman) do
  begin
   if Pos('Pik|', plHuman[i]) > 0 then
   begin
    plTemp[n] := plHuman[i];
    Inc(n);
   end;
  end;

  for i := 0 to High(plHuman) do
  begin
   if Pos('Treff|', plHuman[i]) > 0 then
   begin
    plTemp[n] := plHuman[i];
    Inc(n);
   end;
  end;
//usw.

Danach schreibe ich plTemp zu plHuman zurück und fertig, aber dann habe ich dann manche Karten doppelt!
Das muss doch einfacher gehen, und zwar so, dass ich gleich nach Farben und Werten sortiere!

Aus zB. dem:

Delphi-Quelltext
1:
Herz|5 Joker|J Herz|4 Pik|2 Herz|B Pik|D                    

soll das werden:

Delphi-Quelltext
1:
Pik|2 Pik|D Herz|4 Herz|5 Herz|B Joker|J                    


So sollen die Farben sortiert werden:

Delphi-Quelltext
1:
Pik, Treff, Herz Karo                    

So die Werte:

Delphi-Quelltext
1:
2..10, Bube, Dame, König, As, Joker                    


ZB. Treff|B Herz|7 Karo|As
Ausserdem können Array-Bereiche auch leer sein, dann haben sie einen leeren String, also ''.

Bitte um Tipps!


bole - Do 29.04.10 19:55

Hallo

Ich denke am einfachsten wäre es statt Pik und Karo usw die verschiedenen Spielkarten als Zahlen zu repräsentieren und erst bei der Ausgabe in Pik und Karo umzuwandeln. So hättest Du keine Probleme bei der Sortierung.

Gruss

Bole


Xion - Do 29.04.10 20:05

Ich hab dein Problem nicht so ganz verstanden.

Aber wenn du die Karten sortieren willst, machs doch so:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
const
  ASS=1;
  //2..10
  BUBE=11;
  DAME=12;
  KOENIG=13;

  KARO=0;
  HERZ=1;
  PIK=2;
  KREUZ=3;


Ne karte wäre dann z.B.: Farbe*20+Karte

Also z.B. Herz König:

Delphi-Quelltext
1:
HERZ*20+KOENIG;                    


Insgesamt ergibt sich dann

1-13 = Karo
21-33 = Herz
41-53 = Pik
61-73 = Kreuz


galagher - Do 29.04.10 20:47

Danke euch, aber alles nochmal umschreiben... :(

Es klappt aber, wenn ich nur die belegten Arraybereiche verarbeite und die leeren weglasse, also

Delphi-Quelltext
1:
2:
3:
4:
//statt
  for i := 0 to High(plHuman) do
//verwende ich jetzt
  for i := 0 to iCardCount-1 do

Wenn ich nun zuerst nach Farben, dann nach Werten sortiere und das Ganze dann erst grafisch darstelle, ist alles korrekt. Zwar ist der Code immer noch umfangreich, aber es geht.

//Edit: Zu früh gefreut, es kommt immer wieder zu doppelt vorhandenen "Karten" im Array...


delfiphan - Fr 30.04.10 16:05

Nimm doch ein klassisches Sortierverfahren und implementiere noch eine Funktion, die zwei Karte miteinander vergleicht. Letzteres implementierst du so, dass du zuerst nur die Farben miteinander vergleichst und wenn sie gleich sind, dann geh auf die Zahlen.


galagher - Fr 30.04.10 16:47

Nach Tests mit Ausgabe in einem Memo:
Prinzipiell ist mein Code korrekt, solange nicht leere Strings im Array sind. Das ist immer dann der Fall, wenn eine Karte gespielt wurde. Wenn ich mir nach dem Ausspielen einer Karte eine Liste des Arrays anzeigen lasse, sieht diese zB. so aus:

Delphi-Quelltext
1:
2:
3:
4:
5:
Herz|9
Pik|9
       //<- hier eine Karte gespielt
       //<- hier eine Karte gespielt
Karo|6

Es gibt also leere Bereiche im Array - leer für jede ausgespielte Karte, und das soll auch so sein. Wenn ich mir dann das sortierte Array anzeigen lasse, stimmt alles - das Array ist absolut immer korrekt!
Mein Problem ist also offenbar die Zuordnung des Arrays zu den Images, die es darstellen. Daran feile ich nun.

Aber das nun darzulegen, ist kompliziert. Ich vergleiche das sortierte (und natürlich im Vergleich zu ALLEN Karten relativ wenige "Karten" enthaltende) Array mit einem Array, das ALLE Karten enthält, um das entsprechende Image in einer ImageList zu finden.
So, als ob man als Kartenspieler jede "seiner" Karten mit einem Stapel aller vorhandenen Karten vergleicht.
Naja, wie gesagt, kompliziert zu erklären. Aber ich denke, ich weiss, dass der Fehler in der Zuordnung liegt.


galagher - Sa 01.05.10 09:28

Ok, das klappt jetzt so:
Es gibt also das Spielkarten-Array, und es gibt ein temporäres Array zum Sortieren.
Für jeden leeren Bereich im Spielkarten-Array setze ich ein '-' als Platzhalter im temporären Array, um dieses Bereich zu markieren. Dann sortiere ich zuerst nach Werten, dann nach Farben ins temporäre Array. Jedesmal, wenn ich dabei auf '-' treffe, erhöhe ich einen Integer um 1. So spare ich diese Bereich aus.
'' kann ich nicht nehmen, da im temporären Array zunächst ja alles leer ist.

Nach dem Zurückschreiben entferne ich noch die '-' und fertig! Das Array ist sortiert und dabei sind die Leerbereiche berücksichtigt! Es wäre natürlich mit Zahlen einfacher gewesen...

Danke für eure Anregungen!