Autor Beitrag
JoelH
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 806
Erhaltene Danke: 17

Win10
Delphi Alexandria 11.2 Patch 1
BeitragVerfasst: Di 30.10.12 16:52 
Sorry, für den Topictitel, wem was besseres einfällt darf sich gerne melden. Es geht um folgendes. Ich möchte die Rangposition einer Hand aus fünf Karten berechnen. Leider komm ich nicht auf die Formel, allerdings bin ich mir sehr sicher, dass es sie gibt, und dass sie nicht mal so kompliziert ist.

Also folgendes, es geht um Razz (Ist eine Pokervariante). Dabei gewinnt der mit der "schlechtesten" Hand. Diese ist

A2345

die nächst "schlechteren" Hände ist dann

A2346
A2356
A2456

usw.



Da die Kartenfarbe (Pik, Herz, Karo, Kreuz) keine Rolle spielt kann man die Rangfolge wie folgt aufzeichnen.
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
A23456789TJQK
+++++
++++ +
+++ ++
++ +++
+ ++++
 +++++
++++  +
+++ + +
++ ++ +
+ +++ +
 ++++ +
+++  ++
++ + ++
+ ++ ++
 +++ ++
++  +++
+ + +++
 ++ +++
+  ++++
 + ++++
  +++++

usw.


Wie man recht gut erkennen kann handelt es sich um ein Muster, welches man relativ leicht rekursiv herbeiführen kann. Sehr ähnlich zu den Türmen von Hanoi, wenn nicht sogar dergleiche, nur mit fünf Türmen, anstatt dreien ?!?

Was ich nun gerne hätte, wäre idealerweise eine Formel in die ich fünf Karten quasi als Variablen reinstecke und dann die Position als Zahl zurückbekommen.

Jemand eine Idee, oder die Formel zufällig im Kopf?

_________________
mfg. Joel
Hoermi93
Hält's aus hier
Beiträge: 6

Win 7
Delphi XE
BeitragVerfasst: Di 30.10.12 18:03 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
var
  lTeilString : String;
  I, Punkte: Integer;
begin
 Punkte := 0;
 for I := 0 to 4 do
 begin
  lTeilString := copy(Edit1.Text, i + 1,1 );
  case AnsiIndexText(lTeilString, ['A','2','3','4','5','6','7','8','9','T','J','Q','K'])  of
   0: inc(Punkte, 0);
   1: inc(Punkte, 1);
   2: inc(Punkte, 2);
   3: inc(Punkte, 3);
   4: inc(Punkte, 4);
   5: inc(Punkte, 5);
   6: inc(Punkte, 6);
   7: inc(Punkte, 7);
   8: inc(Punkte, 8);
   9: inc(Punkte, 9);
   10: inc(Punkte, 10);
   11: inc(Punkte, 11);
   12: inc(Punkte, 12);
  end;
 end;
 ShowMessage(IntToStr(Punkte));
end;

ich würd das vielleicht so lösen dann bekomms immer den geringsten Wert zurück
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: Di 30.10.12 19:12 
Wenn du Punkte vergibst, würde ich das exponentiell machen.

Alternativ lässt sich dein Muster generieren, wenn du einfach alle natürlichen Zahlen hochzählst und dann immer nur genau die nimmst, die 5 einsen im Bitmuster haben.
Musst nur gucken wegen dem least-significant-bit (bei deinem Beispiel ist das nämlich links...)

Wenn du also nur vergleichen möchtest, welche Hand besser ist, kannst du mit Gewichten von 1, 2, 4, 8, 16, 32, ... arbeiten oder das ganze zu einem Integer verwursten und vergleichen.

Hier mal der Beispielcode, mit dem ich das überprüft habe:
ausblenden PHP-Quelltext
1:
2:
3:
4:
5:
6:
7:
function Result = NextCombination(x)
a = bin2dec(fliplr(x))+1;
while sum(dec2bin(a)-'0') ~= 5 % Einsen zählen
    a = a+1;
end
Result = fliplr(dec2bin(a));
end

Ist jetzt leider in matlab, aber ich hoffe die Funktion geht hervor. fliplr kehrt den String um, damit das LSB rechts zum liegen kommt. Ausgehend von einer gegebenen Kombination wird also immer eine 1 addiert und geguckt ob das Bitmuster genau 5 Einsen enthält. Sobald das der Fall ist, sind wir fertig und der Wert kann für die Darstellung wieder umgewandelt werden.

Um eine Punktefunktion in Delphi zu implementieren würde ich folgendermaßen vorgehen:
Definiere ein konstantes Array mit einem Char als Index. Dieses kannst du nun vorbelegen mit den passenden Werten. ('A'=$01, '2'=$02, '3'=$04, '4'=$08, '5'=$10) usw.
Danach kannst du für jedes Blatt den Score berechnen indem du die Werte der einzelnen Buchstaben mit bitweisem or verknüpfst.