// u_TPokerRule.pas
unit u_TPokerRule;
interface
uses
Windows, Classes, SysUtils,
StdCtrls,
ch_LogMessages,
u_TList,
u_TDeck,
u_TexasHoldConst;
type
//******************************************************************************
// 類別名稱:TuPokerRule
// 功 能:分析牌型
//******************************************************************************
TuPokerRule = class
private
m_PokerRuleMessToFiles : TLogMessToFiles;
m_nPokerRule : integer; // 牌型
// 計算每個花色的牌有幾張
m_aCategory : array[0..3] of integer;
// 記錄 每種 數字 有幾張
m_aSumIndex: array[0..CARD_INDEX_LIMIT] of integer;
// 記錄有幾種牌型
m_aSumRules: array[0..POKER_RULES_LIMIT - 1]of integer;
// 暫存要分析的撲克
m_TempPokerList : TuList; // type TCardData.nListIndex;
m_CardDataList: TuList; // type TCardData;
m_MaxRulePoker : TuList; // type TCardData; 最大的五張牌
m_pDeck : TuDeck;
function _GetFlushIndex(): Integer; // 抓同花是那一個花色
function _GetMaxRules : Integer; // 取最大的牌型
procedure _OnRanderMaxPoker( nRuleType:Integer ); // 依牌型抓最大的五張
procedure _OnMaxPokerZilch; // 抓 最大的五張
procedure _OnMaxPokerOnePair; // 抓 一對 最大的五張
procedure _OnMaxPokerTwoPair; // 抓 兩對 最大的五張
procedure _OnMaxPokerThreeKind; // 抓 三條 最大的五張
procedure _OnMaxPokerStraight; // 抓 順子 最大的五張
procedure _OnMaxPokerFlush; // 抓 同花 最大的五張
procedure _OnMaxPokerFullHouse; // 抓 葫蘆 最大的五張
procedure _OnMaxPokerFourKind; // 抓 鐵支 最大的五張
procedure _OnMaxPokerStraightFlush; // 抓 同花順 最大的五張
function _PokerRulesTwoPair:Integer; // 檢查有沒有 兩對
function _PokerRulesStraight : Integer; // 檢查有沒有 順子
function _PokerRulesFlush :Integer; // 檢查有沒有 同花
function _PokerRulesFullHouse: Integer; // 檢查有沒有 葫蘆
function _PokerRulesStraightFlush():Integer; // 檢查有沒有 同花順
function _PokerRulesRoyalFlush():Integer; // 檢查有沒有 同花順
procedure _debug_LogPoker;// 將 牌 匯出
public
constructor Create(var pDeck: TuDeck);
destructor Destroy(); override;
procedure Init();
procedure OnAddCard(nIndex:Integer); // 將牌加入
function GetPokerRule(): Integer; // 取出最大的牌型
procedure GetMaxRulePoker(var MaxPoker:TuList); // 將最大的五張牌寫入 MaxPoker
end;
//******************************************************************************
// 類別名稱:TuUITextPokerRule
// 功 能:牌型顯示 文字版本
//******************************************************************************
TuTextPokerRule = class
private
//m_uiText : TuUIText;
m_strPokerRule : string; // 轉換完成的字串
m_AToKTextList : TStringList; // A 到 K 的文字 字串
m_PokerRulesFormat : TStringList; //
public
constructor Create();
destructor Destroy(); override;
procedure OnProcess(PokerRules: Word; var CardDataList : TuList ); // 牌型 五張牌
property Text: string read m_strPokerRule;
end;
implementation
// { TuUITextPokerRule }
constructor TuTextPokerRule.Create;
begin
m_AToKTextList := TStringList.Create();
if( Assigned( m_AToKTextList ) = True ) then begin
m_AToKTextList.LoadFromFile( INI_DATA_PATH + 'AToKText_en.ini' );
end;
m_PokerRulesFormat := TStringList.Create();
if( Assigned( m_PokerRulesFormat ) = True ) then begin
m_PokerRulesFormat.LoadFromFile( INI_DATA_PATH + 'PokerRulesTextFormat_en.ini' );
end;
end;
destructor TuTextPokerRule.Destroy;
begin
m_PokerRulesFormat.Free;
m_AToKTextList.Free;
inherited;
end;
procedure TuTextPokerRule.OnProcess(PokerRules: Word;
var CardDataList: TuList);
var
strP1:string;
strP2:string;
TmpCardData : TCardData;
TmpCardDataList : TuList;
nIndex : Integer;
begin
if CardDataList.Count = 0 then
exit;
strP1 := '';
strP2 := '';
// 牌型
case PokerRules of
POKER_RULES_ZILCH: begin
TmpCardData := CardDataList.GetItems(0);
nIndex := TmpCardData.Index - 1;
strP1 := m_AToKTextList.Strings[ nIndex ];
end;
POKER_RULES_ONE_PAIR: begin
TmpCardData := CardDataList.GetItems(0);
nIndex := TmpCardData.Index - 1;
strP1 := Format('%ss',[m_AToKTextList.Strings[ nIndex ]]);
end;
POKER_RULES_TWO_PAIRS: begin
TmpCardData := CardDataList.GetItems(0);
nIndex := TmpCardData.Index - 1;
strP1 := Format('%ss',[m_AToKTextList.Strings[ nIndex ]]);
TmpCardData := CardDataList.GetItems(3);
nIndex := TmpCardData.Index - 1;
strP2 := Format('%ss',[m_AToKTextList.Strings[ nIndex ]]);
end;
POKER_RULES_THREE_KIND: begin
TmpCardData := CardDataList.GetItems(0);
nIndex := TmpCardData.Index - 1;
strP1 := Format('%ss',[m_AToKTextList.Strings[ nIndex ]]);
end;
POKER_RULES_STRAIGHT: begin
TmpCardData := CardDataList.GetItems(4);
nIndex := TmpCardData.Index - 1;
strP1 := m_AToKTextList.Strings[ nIndex ];
TmpCardData := CardDataList.GetItems(0);
nIndex := TmpCardData.Index - 1;
strP2 := m_AToKTextList.Strings[ nIndex ];
end;
POKER_RULES_FLUSH: begin
TmpCardData := CardDataList.GetItems(0);
nIndex := TmpCardData.Index - 1;
strP1 := m_AToKTextList.Strings[ nIndex ];
end;
POKER_RULES_FULLHOUSE: begin
TmpCardData := CardDataList.GetItems(0);
nIndex := TmpCardData.Index - 1;
strP1 := Format('%ss',[m_AToKTextList.Strings[ nIndex ]]);
TmpCardData := CardDataList.GetItems(3);
nIndex := TmpCardData.Index - 1;
strP2 := Format('%ss',[m_AToKTextList.Strings[ nIndex ]]);
end;
POKER_RULES_FOUR_KIND: begin
TmpCardData := CardDataList.GetItems(0);
nIndex := TmpCardData.Index - 1;
strP1 := Format('%ss',[m_AToKTextList.Strings[ nIndex ]]);
end;
POKER_RULES_STRAIGHT_FLUSH: begin
TmpCardData := CardDataList.GetItems(4);
nIndex := TmpCardData.Index - 1;
strP1 := m_AToKTextList.Strings[ nIndex ];
TmpCardData := CardDataList.GetItems(0);
nIndex := TmpCardData.Index - 1;
strP2 := m_AToKTextList.Strings[ nIndex ];
end;
// POKER_RULES_STRAIGHT_FLUSH: begin
// TmpCardData := CardDataList.GetItems(0);
// nIndex := TmpCardData.Index - 1;
// strP1 := m_AToKTextList.Strings[ nIndex ];
//
// TmpCardData := CardDataList.GetItems(4);
// nIndex := TmpCardData.Index - 1;
// strP2 := m_AToKTextList.Strings[ nIndex ];
// end;
end;
m_strPokerRule := Format(m_PokerRulesFormat.Strings[PokerRules], [strP1, strP2]);
end;
constructor TuPokerRule.Create(var pDeck: TuDeck);
begin
m_pDeck := pDeck;
m_TempPokerList := TuList.Create();
m_MaxRulePoker := TuList.Create();
m_CardDataList := TuList.Create();
m_PokerRuleMessToFiles := TLogMessToFiles.Create('PokerRuleMessage.txt');
end;
destructor TuPokerRule.Destroy;
begin
m_PokerRuleMessToFiles.Free;
m_TempPokerList.Free;
m_MaxRulePoker.Free;
m_CardDataList.Free;
end;
//******************************************************************************
// 函式名稱:Init
// 功 能:使用TuPokerRule 之前要先呼叫Init 用來清除所有資料
//******************************************************************************
procedure TuPokerRule.Init;
var
i:integer;
begin
// 初始化 PokerRules 記錄
m_nPokerRule := POKER_RULES_ZILCH;
// 清除花色記錄器
for i := 0 to High(m_aCategory) do begin
m_aCategory[i] := 0;
end;
// 清除牌數字記錄器
for i := 0 to High(m_aSumIndex) do begin
m_aSumIndex[i] := 0;
end;
// 清除牌數字記錄器
for i := 0 to High(m_aSumRules) do begin
m_aSumRules[i] := 0;
end;
// 清除暫存陣列
m_TempPokerList.Clear();
m_MaxRulePoker.Clear();
m_CardDataList.Clear();
end;
//******************************************************************************
// 函式名稱:OnAddCard
// 功 能:將要運牌的牌加入TuPokerRule
//******************************************************************************
procedure TuPokerRule.OnAddCard(nIndex:Integer);
begin
if( nIndex = - 1 ) then begin
exit;
end;
m_TempPokerList.Add(Pointer(nIndex));
m_CardDataList.Add(m_pDeck.Items(nIndex));
end;
//******************************************************************************
// 函式名稱:GetPokerRule
// 功 能:TuPokerRule 最主要的函式 計算牌型 計算最大的五張牌
//******************************************************************************
function TuPokerRule.GetPokerRule():Integer ;
var
i: integer;
nNum: integer;
nListIndex: integer;
nCategory : integer;
// 有幾對
nPairCount : integer;
nThreeCount : integer;
begin
try
if m_TempPokerList.Count = 0 then // 沒有牌不用處理
exit;
m_CardDataList.Sort(compareByPoker);
for i := 0 to m_TempPokerList.Count - 1 do begin
nListIndex := Integer(m_TempPokerList.GetItems(i));
nCategory := m_pDeck.Category(nListIndex);
nNum := m_pDeck.Index(nListIndex);
// 計數每種花色有幾張
m_aCategory[nCategory] := m_aCategory[nCategory] + 1;
// 計數 同樣數字的撲克牌有幾張
m_aSumIndex[nNum] := m_aSumIndex[nNum] + 1;
if nNum = 13 then
m_aSumIndex[0] := m_aSumIndex[0] + 1;
end;
for i := 1 to High(m_aSumIndex) do begin
case m_aSumIndex[i] of
2: m_aSumRules[POKER_RULES_ONE_PAIR] := m_aSumRules[POKER_RULES_ONE_PAIR] + 1; // 計數對子
3: m_aSumRules[POKER_RULES_THREE_KIND] := m_aSumRules[POKER_RULES_THREE_KIND] + 1; // 計數三條
4: m_aSumRules[POKER_RULES_FOUR_KIND] := m_aSumRules[POKER_RULES_FOUR_KIND] + 1; // 計數四隻
end;
end;
// 這裡有牌型是互斥的 可以使用 if else 作區分加快計算
m_aSumRules[POKER_RULES_TWO_PAIRS] := _PokerRulesTwoPair(); // 檢查 兩對
m_aSumRules[POKER_RULES_STRAIGHT] := _PokerRulesStraight(); // 檢查 順子
m_aSumRules[POKER_RULES_FLUSH] := _PokerRulesFlush(); // 檢查 同花
m_aSumRules[POKER_RULES_FULLHOUSE] := _PokerRulesFullHouse(); // 檢查 葫蘆
m_aSumRules[POKER_RULES_STRAIGHT_FLUSH] := _PokerRulesStraightFlush();// 檢查 同花順
m_aSumRules[POKER_RULES_ROYAL_FLUSH] := _PokerRulesRoyalFlush(); // 檢查 大同花順
Result := _GetMaxRules();
_OnRanderMaxPoker(Result);
except
m_PokerRuleMessToFiles.m_WriteTXTOne('GetPokerRule', 1);
end;
end;
//******************************************************************************
// 函式名稱:_OnRanderMaxPoker
// 功 能:依牌型種類 抓出最大的五張牌
//******************************************************************************
procedure TuPokerRule._OnRanderMaxPoker(nRuleType: Integer);
begin
case nRuleType of
POKER_RULES_ZILCH: _OnMaxPokerZilch; // 沒有
POKER_RULES_ONE_PAIR: _OnMaxPokerOnePair; // 一對
POKER_RULES_TWO_PAIRS: _OnMaxPokerTwoPair; // 兩對
POKER_RULES_THREE_KIND: _OnMaxPokerThreeKind; // 三條
// POKER_RULES_SMALL_STRAIGHT: // 小順子
POKER_RULES_STRAIGHT: _OnMaxPokerStraight; // 順子
POKER_RULES_FLUSH: _OnMaxPokerFlush; // 同花
POKER_RULES_FULLHOUSE: _OnMaxPokerFullHouse; // 葫蘆
POKER_RULES_FOUR_KIND: _OnMaxPokerFourKind; // 鐵支
POKER_RULES_STRAIGHT_FLUSH:_OnMaxPokerStraightFlush; // 同花順
POKER_RULES_ROYAL_FLUSH: _OnMaxPokerStraightFlush; // 大同花順
end;
end;
//******************************************************************************
// 函式名稱:_GetMaxRules
// 功 能:選出 最大的牌型
//******************************************************************************
function TuPokerRule._GetMaxRules() : Integer;
var
i : Integer;
begin
for i := POKER_RULES_LIMIT - 1 downto POKER_RULES_ZILCH do begin
if( m_aSumRules[i] > 0 ) then begin
m_nPokerRule := i;
break;
end;
end;
Result := m_nPokerRule;
end;
//******************************************************************************
// 函式名稱:PokerRulesTwoPair
// 功 能:檢查有沒有兩對
//******************************************************************************
function TuPokerRule._PokerRulesTwoPair():integer;
begin
if m_aSumRules[POKER_RULES_ONE_PAIR] < 2 then
begin
Result := 0;
exit;
end;
Result := 1;
end;
//******************************************************************************
// 函式名稱:PokerRulesStraight
// 功 能:檢查牌型 順子 & 順便檢查是不是最小順
//******************************************************************************
function TuPokerRule._PokerRulesStraight : integer;
var
i : integer;
nCountStraight : integer;
nMaxCountStraight : integer;
begin
nCountStraight := 0;
nMaxCountStraight := 0;
Result := 0;
for i := High(m_aSumIndex) downto 0 do begin
if m_aSumIndex[i] = 0 then
nCountStraight := 0;
if m_aSumIndex[i] > 0 then
nCountStraight := nCountStraight + 1;
if nMaxCountStraight < nCountStraight then
nMaxCountStraight := nCountStraight;
end;
// 有超過5張連續的牌 代表有順子
if nMaxCountStraight >= 5 then begin
Result := 1;
end;
// 這裡要另外檢查 是否為最小順 A 2 3 4 5
if( m_aSumIndex[1] > 0) And
( m_aSumIndex[2] > 0) And
( m_aSumIndex[3] > 0) And
( m_aSumIndex[4] > 0) And
( m_aSumIndex[0] > 0) then begin
if nMaxCountStraight = 5 then begin
m_aSumRules[POKER_RULES_SMALL_STRAIGHT] := 1;
end;
Result := 1;
end;
end;
//******************************************************************************
// 函式名稱:PokerRulesFlush
// 功 能:檢查牌型 同花
//******************************************************************************
function TuPokerRule._PokerRulesFlush :integer;
var
i : integer;
nListIndex : integer;
nNum : integer;
nCategory : integer;
begin
Result := 0;
// 檢查是否有五張的花色
for i := 0 to High(m_aCategory) do begin
if( m_aCategory[i] >= 5 ) then begin
m_nPokerRule := POKER_RULES_FLUSH;
Result := 1;
end;
end;
end;
//******************************************************************************
// 函式名稱:PokerRulesFullHouse
// 功 能:檢查牌型 葫蘆
//******************************************************************************
function TuPokerRule._PokerRulesFullHouse: integer;
begin
Result := 0;
case m_aSumRules[POKER_RULES_THREE_KIND] of
// 有兩組三條
2: Result := 1;
// 有一組三條 + 一組對子
1:
begin
if(m_aSumRules[POKER_RULES_ONE_PAIR] > 0 ) then
Result := 1;
end;
end;
end;
// 加入了 m_CardDataList 找時間改寫..
//******************************************************************************
// 函式名稱:PokerRulesStraightFlush
// 功 能:檢查牌型 同花順
//******************************************************************************
function TuPokerRule._PokerRulesStraightFlush():Integer ;
var
i : Integer;
nA : Integer;
nTemp : Integer;
nCategoryIndex: Integer;
nCategory2Index: Integer;
nCategory3Index: Integer;
nSum: Integer;
nMaxSum : Integer;
aArray : TuList;
str : String;
strFileName :string;
begin
Result := 0;
// 沒有同花 跟 順子 就不用檢查 同花順
if ( m_aSumRules[POKER_RULES_STRAIGHT] = 0 ) Or
(m_aSumRules[POKER_RULES_FLUSH] = 0) then
exit;
aArray := TuList.Create();
for i := 0 to m_TempPokerList.Count - 1 do begin
aArray.Add(m_TempPokerList.GetItems(i));
end;
aArray.Sort(compareByInteger);
nCategoryIndex := _GetFlushIndex();
// 檢查有沒有連續的順子
nSum := 0;
nMaxSum := 0;
for i := 0 to m_TempPokerList.Count - 2 do
begin
nCategory2Index := m_pDeck.Category(Integer(aArray.GetItems(i + 1)));
nCategory3Index := m_pDeck.Category(Integer(aArray.GetItems(i)));
if( Integer(aArray.GetItems(i + 1)) - Integer(aArray.GetItems( i )) = 1 ) And
( nCategory2Index = nCategory3Index ) then
begin
nSum := nSum + 1;
if( nMaxSum < nSum ) then
nMaxSum := nMaxSum + 1;
end
else
begin
nSum := 0;
end;
end;
if( nMaxSum >= 4 ) then
begin
Result := 1;
aArray.Free();
exit;
end;
// 如果有小順 要另外檢查 只要檢查 有沒有同花色A 就行了
if( nMaxSum <> 3 ) Or
(m_aSumRules[POKER_RULES_SMALL_STRAIGHT] = 0 )then begin
aArray.Free();
exit;
end;
// 計算同花色的A 的索引值
nA := nCategoryIndex * 13 + 12 ;
for i := 0 to m_TempPokerList.Count -1 do
begin
//nTemp := aArray[i];
if Integer(aArray.GetItems(i)) = nA then
begin
Result := 1;
break;
end;
end;
aArray.Free();
end;
//******************************************************************************
// 函式名稱:_PokerRulesRoyalFlush
// 功 能:檢查牌型 大同花順
//******************************************************************************
function TuPokerRule._PokerRulesRoyalFlush: Integer;
var
i:Integer;
j:integer;
TmpCardData : TCardData;
nCategory:integer;
nCardIndex:integer;
begin
Result := 0;
// 沒有同花順 就不用檢查 大同花順
if ( m_aSumRules[POKER_RULES_STRAIGHT_FLUSH] = 0 ) then
exit;
nCategory := _GetFlushIndex();
nCardIndex := 13;
// 抓滿五張
j := m_CardDataList.Count - 1;
for i := 0 to 4 do begin
TmpCardData := m_CardDataList.GetItems(j);
if (TmpCardData.Index <> nCardIndex) Or
(TmpCardData.Category <> nCategory) then begin
Result := 0;
exit;
end;
j := j - 1;
nCardIndex := nCardIndex - 1;
end;
Result := 1;
end;
//******************************************************************************
// 函式名稱:GetMaxRulePoker
// 功 能:計算最大的牌型
//******************************************************************************
procedure TuPokerRule.GetMaxRulePoker(var MaxPoker: TuList);
var
i : integer;
begin
MaxPoker.Clear();
for i := 0 to m_MaxRulePoker.Count -1 do begin
MaxPoker.Add(m_MaxRulePoker.GetItems(i));
end;
end;
//******************************************************************************
// 函式名稱:_OnMaxPokerOnePair
// 功 能:將沒有任何牌形 的最大五張牌抓出來
//******************************************************************************
procedure TuPokerRule._OnMaxPokerZilch;
var
i: integer;
j: integer;
TmpCardData : TCardData;
begin
// 抓五張
for j := m_CardDataList.Count - 1 downto 0 do begin
TmpCardData := m_CardDataList.GetItems(j);
m_MaxRulePoker.Add(TmpCardData);
if m_MaxRulePoker.Count = 5 then begin
Break;
end;
end;
end;
//******************************************************************************
// 函式名稱:_OnMaxPokerOnePair
// 功 能:將牌形一對 的最大五張牌抓出來
//******************************************************************************
procedure TuPokerRule._OnMaxPokerOnePair;
var
i: integer;
j: integer;
nNum: integer;
TmpCardData : TCardData;
begin
// 抓最大的一對牌
for i := High(m_aSumIndex) downto 1 do begin
if m_aSumIndex[i] = 2 then begin
for j := 0 to m_CardDataList.Count - 1 do begin
TmpCardData := m_CardDataList.GetItems(j);
//nListIndex := TmpCardData.ListIndex;
nNum := TmpCardData.Index;
if nNum = i then begin
m_MaxRulePoker.Add(TmpCardData);
end;
end;
Break;
end;
end;
// 抓剩下的三張
for j := m_CardDataList.Count - 1 downto 0 do begin
TmpCardData := m_CardDataList.GetItems(j);
if m_aSumIndex[TmpCardData.Index] = 2 then begin
Continue;
end;
m_MaxRulePoker.Add(TmpCardData);
if m_MaxRulePoker.Count = 5 then begin
Break;
end;
end;
end;
//******************************************************************************
// 函式名稱:_OnMaxPokerTwoPair
// 功 能:將牌形兩對 的最大五張牌抓出來
//******************************************************************************
procedure TuPokerRule._OnMaxPokerTwoPair;
var
i: integer;
j: integer;
nNum: integer;
nListIndex: integer;
nPairCount: integer;
TmpCardData : TCardData;
begin
// 抓最大的兩對牌
nPairCount := 0;
for i := High(m_aSumIndex) downto 1 do begin
if m_aSumIndex[i] = 2 then begin
nPairCount := nPairCount + 1;
for j := 0 to m_CardDataList.Count - 1 do begin
TmpCardData := m_CardDataList.GetItems(j);
//nListIndex := TmpCardData.ListIndex;
nNum := TmpCardData.Index;
if nNum = i then begin
m_MaxRulePoker.Add(TmpCardData);
end;
end;
if nPairCount = 2 then begin
break;
end;
end;
end;
// 抓第五張
nPairCount := 0;
for j := m_CardDataList.Count - 1 downto 0 do begin
TmpCardData := m_CardDataList.GetItems(j);
if m_aSumIndex[TmpCardData.Index] = 2 then begin
nPairCount := nPairCount + 1;
if nPairCount <= 4 then begin
Continue;
end;
end;
m_MaxRulePoker.Add(TmpCardData);
break;
end;
end;
//******************************************************************************
// 函式名稱:_OnMaxPokerThreeKind
// 功 能:將牌形三條 的最大五張牌抓出來
//******************************************************************************
procedure TuPokerRule._OnMaxPokerThreeKind;
var
i: integer;
j: integer;
nNum: integer;
TmpCardData : TCardData;
begin
// 抓三條
for i := High(m_aSumIndex) downto 1 do begin
if m_aSumIndex[i] = 3 then begin
for j := 0 to m_CardDataList.Count - 1 do begin
TmpCardData := m_CardDataList.GetItems(j);
//nListIndex := TmpCardData.ListIndex;
nNum := TmpCardData.Index;
if nNum = i then begin
m_MaxRulePoker.Add(TmpCardData);
end;
end;
Break;
end;
end;
// 抓滿五張
for j := m_CardDataList.Count - 1 downto 0 do begin
TmpCardData := m_CardDataList.GetItems(j);
if m_aSumIndex[TmpCardData.Index] = 3 then begin
Continue;
end;
m_MaxRulePoker.Add(TmpCardData);
if m_MaxRulePoker.Count = 5 then begin
Break;
end;
end;
end;
//******************************************************************************
// 函式名稱:_OnMaxPokerStraight
// 功 能:將牌形 順子 的最大五張牌抓出來
//******************************************************************************
procedure TuPokerRule._OnMaxPokerStraight;
var
i : integer;
nCardDataIndex : integer;
nCardDataNextIndex : Integer;
nCountStraight : integer;
nMaxCountStraight : integer;
TmpCardData : TCardData;
TmpCardDataNext : TCardData;
begin
_debug_LogPoker();
nCountStraight := 0;
nMaxCountStraight := 0;
nCardDataIndex := m_CardDataList.Count - 1;
nCardDataNextIndex := nCardDataIndex - 1;
for i := m_CardDataList.Count - 1 downto 1 do begin
TmpCardData := m_CardDataList.GetItems(nCardDataIndex);
TmpCardDataNext := m_CardDataList.GetItems(nCardDataNextIndex);
// 先加入第一張牌
if m_MaxRulePoker.Count = 0 then
m_MaxRulePoker.Add(TmpCardData);
// 如果 兩張牌面數字一樣 換下一張
while (nCardDataNextIndex > 0) And
(TmpCardData.Index = (TmpCardDataNext.Index )) do begin
nCardDataNextIndex := nCardDataNextIndex - 1;
TmpCardDataNext := m_CardDataList.GetItems(nCardDataNextIndex);
end;
// 下一張是不是比前一張少一
if TmpCardData.Index = (TmpCardDataNext.Index + 1) then begin
m_MaxRulePoker.Add(TmpCardDataNext);
end else begin
m_MaxRulePoker.Clear;
end;
// 超過五張
if m_MaxRulePoker.Count = 5 then
Break;
nCardDataIndex := nCardDataNextIndex;
nCardDataNextIndex := nCardDataNextIndex - 1;
if nCardDataIndex = 0 then begin
Break;
end;
end;
// 如果是小順 要另外處理A
if m_aSumRules[POKER_RULES_SMALL_STRAIGHT] <> 0 then begin
for i := m_CardDataList.Count - 1 downto 0 do begin
TmpCardData := m_CardDataList.GetItems(i);
if TmpCardData.Index = 13 then begin
m_MaxRulePoker.Add(TmpCardData);
break;
end;
end;
end;
end;
//******************************************************************************
// 函式名稱:_OnMaxPokerFlush
// 功 能:將牌形 同花 的最大五張牌抓出來
//******************************************************************************
procedure TuPokerRule._OnMaxPokerFlush;
var
i : integer;
nListIndex : integer;
nNum : integer;
nCategory : integer;
TmpCardData : TCardData;
begin
nCategory := _GetFlushIndex();
for i := m_CardDataList.Count - 1 downto 0 do begin
TmpCardData := m_CardDataList.GetItems(i);
if TmpCardData.Category = nCategory then begin
m_MaxRulePoker.Add(TmpCardData);
end;
if m_MaxRulePoker.Count = 5 then
Break;
end;
end;
//******************************************************************************
// 函式名稱:_OnMaxPokerFullHouse
// 功 能:將牌形 葫蘆 的最大五張牌抓出來
//******************************************************************************
procedure TuPokerRule._OnMaxPokerFullHouse;
var
i: integer;
j: integer;
nMaxThreeKind : integer;
TmpCardData : TCardData;
begin
// 抓最大的三條
for i := High(m_aSumIndex) downto 1 do begin
if m_aSumIndex[i] = 3 then begin
for j := m_CardDataList.Count - 1 downto 0 do begin
TmpCardData := m_CardDataList.GetItems(j);
if TmpCardData.Index = i then begin
m_MaxRulePoker.Add(TmpCardData);
end;
if m_MaxRulePoker.Count = 3 then
Break;
end;
nMaxThreeKind := i;
Break;
end;
end;
// 抓最大的對子
for i := High(m_aSumIndex) downto 1 do begin
if m_aSumIndex[i] >= 2 then begin
if i = nMaxThreeKind then begin
continue;
end;
for j := m_CardDataList.Count - 1 downto 0 do begin
TmpCardData := m_CardDataList.GetItems(j);
if TmpCardData.Index = i then begin
m_MaxRulePoker.Add(TmpCardData);
end;
if m_MaxRulePoker.Count = 5 then begin
Exit;
end;
end;
end;
end;
end;
//******************************************************************************
// 函式名稱:_OnMaxPokerFourKind
// 功 能:將牌形 鐵支 的最大五張牌抓出來
//******************************************************************************
procedure TuPokerRule._OnMaxPokerFourKind;
var
i: integer;
j: integer;
nMaxFourKind : integer;
TmpCardData : TCardData;
begin
// 抓最大的鐵支四張
for i := High(m_aSumIndex) downto 1 do begin
if m_aSumIndex[i] = 4 then begin
for j := m_CardDataList.Count - 1 downto 0 do begin
TmpCardData := m_CardDataList.GetItems(j);
if TmpCardData.Index = i then begin
m_MaxRulePoker.Add(TmpCardData);
end;
if m_MaxRulePoker.Count = 4 then
Break;
end;
nMaxFourKind := i;
Break;
end;
end;
// 抓滿五張
for j := m_CardDataList.Count - 1 downto 0 do begin
TmpCardData := m_CardDataList.GetItems(j);
if TmpCardData.Index = nMaxFourKind then begin
Continue;
end;
m_MaxRulePoker.Add(TmpCardData);
if m_MaxRulePoker.Count = 5 then begin
Break;
end;
end;
end;
//******************************************************************************
// 函式名稱:_OnMaxPokerStraightFlush
// 功 能:將牌形 同花順 的最大五張牌抓出來
//******************************************************************************
procedure TuPokerRule._OnMaxPokerStraightFlush;
var
i : integer;
nCardDataIndex : integer;
nCardDataNextIndex : Integer;
nCountStraight : integer;
nMaxCountStraight : integer;
TmpCardData : TCardData;
TmpCardDataNext : TCardData;
nCategory : integer;
begin
_debug_LogPoker();
nCategory := _GetFlushIndex();
nCountStraight := 0;
nMaxCountStraight := 0;
nCardDataIndex := m_CardDataList.Count - 1;
for i := m_CardDataList.Count - 1 downto 1 do begin
TmpCardData := m_CardDataList.GetItems(nCardDataIndex);
while TmpCardData.Category <> nCategory do begin
nCardDataIndex := nCardDataIndex - 1;
TmpCardData := m_CardDataList.GetItems(nCardDataIndex);
end;
nCardDataNextIndex := nCardDataIndex - 1;
TmpCardDataNext := m_CardDataList.GetItems(nCardDataNextIndex);
while (nCardDataNextIndex > 0 ) And
(TmpCardDataNext.Category <> nCategory) do begin
nCardDataNextIndex := nCardDataNextIndex - 1;
TmpCardDataNext := m_CardDataList.GetItems(nCardDataNextIndex);
end;
// 先加入第一張牌
if m_MaxRulePoker.Count = 0 then
m_MaxRulePoker.Add(TmpCardData);
// 同樣花色不可能數字一樣 // 如果 兩張牌面數字一樣 換下一張
// while TmpCardData.Index = (TmpCardDataNext.Index ) do begin
// nCardDataNextIndex := nCardDataNextIndex - 1;
// TmpCardDataNext := m_CardDataList[nCardDataNextIndex];
// end;
// 下一張是不是比前一張少一
if TmpCardData.Index = (TmpCardDataNext.Index + 1) then begin
m_MaxRulePoker.Add(TmpCardDataNext);
end else begin
m_MaxRulePoker.Clear;
end;
// 超過五張
if m_MaxRulePoker.Count = 5 then
Break;
nCardDataIndex := nCardDataNextIndex;
// nCardDataNextIndex := nCardDataNextIndex - 1;
if nCardDataIndex = 0 then begin
Break;
end;
end;
// 如果是小順 要另外處理A
if m_aSumRules[POKER_RULES_SMALL_STRAIGHT] <> 0 then begin
for i := m_CardDataList.Count - 1 downto 0 do begin
TmpCardData := m_CardDataList.GetItems(i);
if TmpCardData.Index = 13 then begin
m_MaxRulePoker.Add(TmpCardData);
break;
end;
end;
end;
end;
//******************************************************************************
// 函式名稱:_GetFlushIndex
// 功 能:傳回同花的花色索引
//******************************************************************************
function TuPokerRule._GetFlushIndex: Integer;
var
i:integer;
begin
Result := -1 ;
// 查一下什麼同花
for i := 0 to High(m_aCategory) do
begin
if( m_aCategory[i] >= 5 ) then
begin
Result := i;
break;
end;
end;
if Result = -1 then begin
Result := 0;
end;
end;
procedure TuPokerRule._debug_LogPoker;
var
i:Integer;
str:String;
strPoker:string;
TmpCardData : TCardData;
begin
exit;
str := '';
strPoker := '';
for i := m_CardDataList.Count -1 downto 0 do begin
TmpCardData := m_CardDataList.GetItems(i);
str := Format('%d ', [TmpCardData.Index] );
strPoker := strPoker + str;
end;
m_PokerRuleMessToFiles.m_WriteTXTOne(strPoker, 1);
end;
end.
應該感受的出來這一份代碼表現的緊張, 在時間壓力下寫出來的代碼實在是慘無人道丫!
在接下來的C++版時會大力的改善 Switch 實在是個使用多型的好地方!
沒有留言:
張貼留言