Introduction
This tip shows how to encapsulate a memcache for Texas hold'em. I will explain how the
encapsulation makes the game logic easier. I can't give the source of the memcache, so
I will explain some logical code to compensate.
Using the code
For packet:
#pragma once
#ifndef ES_TCP_MAX_BUFFER
# define ES_TCP_MAX_BUFFER 1024*16
#endif
#ifndef _WINDEF_
typedef unsigned char BYTE;
#endif
#include <string>
#include <queue>
#include <vector>
#include <deque>
#include <list>
#include <iostream>
#include <sstream>
#include <map>
#include <arpa/inet.h>
#include <iomanip>
using namespace std;
#if WIN32
typedef long long int64_t;
#endif
#ifndef WIN32
# define _atoi64 atoll
#endif
#define SERVER_PACEKTVER 1
#define PROTOL_HEADER_SIZE 8
typedef unsigned long long __u64;
#define de_htonll(x) \
({ \
__u64 __x = (x); \
((__u64)( \
(__u64)(((__u64)(__x) & (__u64)0x00000000000000ffULL) << 56) | \
(__u64)(((__u64)(__x) & (__u64)0x000000000000ff00ULL) << 40) | \
(__u64)(((__u64)(__x) & (__u64)0x0000000000ff0000ULL) << 24) | \
(__u64)(((__u64)(__x) & (__u64)0x00000000ff000000ULL) << 8) | \
(__u64)(((__u64)(__x) & (__u64)0x000000ff00000000ULL) >> 8) | \
(__u64)(((__u64)(__x) & (__u64)0x0000ff0000000000ULL) >> 24) | \
(__u64)(((__u64)(__x) & (__u64)0x00ff000000000000ULL) >> 40) | \
(__u64)(((__u64)(__x) & (__u64)0xff00000000000000ULL) >> 56) )); \
})
inline long long htonll(long long hvalue)
{
short i=20;
if( htons(i) == i )
{
return hvalue;
}
else
{
return (long long)de_htonll(hvalue);
}
}
inline long long ntohll(long long nvalue)
{
short i=20;
if( htons(i) == i )
{
return nvalue;
}
else
{
return (long long)de_htonll(nvalue);
}
}
inline string ESHexDumpImp(const void *pdata, unsigned int len)
{
string outstr;
if(pdata == 0 || len == 0)
{
return "";
}
int cnt = 0;
int n = 0;
int cnt2 = 0;
stringstream sstr;
const char *data = (const char *)pdata;
sstr<<"Address Hexadecimal values Printable\n";
sstr<<"------- ----------------------------------------------- -------------\n";
unsigned char buffer[20];
unsigned int rpos = 0;
while ( 1 )
{
if(len <= rpos)
{
break;
}
if(len >= rpos + 16)
{
memcpy(buffer, data + rpos, 16);
rpos += 16;
cnt = 16;
}
else
{
memcpy(buffer, data + rpos, len - rpos);
cnt = len - rpos;
rpos = len;
}
if(cnt <= 0)
{
outstr = sstr.str();
return outstr;
}
sstr << setw(7) << ( int ) rpos << " ";
cnt2 = 0;
for ( n = 0; n < 16; n++ )
{
cnt2 = cnt2 + 1;
if ( cnt2 <= cnt )
{
sstr << hex << setw(2) << setfill ( '0' ) <<
(unsigned int)buffer[n];
}
else
{
sstr << " ";
}
sstr << " ";
}
sstr << setfill ( ' ' );
sstr << " ";
cnt2 = 0;
for ( n = 0; n < 16; n++ )
{
cnt2 = cnt2 + 1;
if ( cnt2 <= cnt )
{
if ( buffer[n] < 32 || 126 < buffer[n] )
{
sstr << '.';
}
else
{
sstr << buffer[n];
}
}
}
sstr << "\n";
sstr << dec;
}
outstr = sstr.str();
return outstr;
}
template <unsigned _buffer_size, unsigned _header_size>
class PacketBase
{
public:
char *packet_buf(void) {return m_strBuf;}
unsigned packet_size(void) {return m_nPacketSize;}
protected:
PacketBase(void){}
~PacketBase(void){}
enum
{
PACKET_HEADER_SIZE = _header_size,
PACKET_BUFFER_SIZE = _buffer_size
};
unsigned m_nPacketSize ;
unsigned m_nBufPos;
char m_strBuf[PACKET_BUFFER_SIZE];
protected:
bool _copy(const void *pInBuf, unsigned nLen)
{
if(NULL==pInBuf || nLen > PACKET_BUFFER_SIZE){
return false;
}
_reset();
memcpy(m_strBuf, pInBuf, nLen);
m_nPacketSize = nLen;
return true;
}
void _begin(short nCmdType, short cVersion)
{
_reset();
_writeHeader("ES", sizeof(char)*2, 0);
short cmdType = htons(nCmdType);
_writeHeader((char*)&cmdType, sizeof(short), 2);
short version = htons(cVersion);
_writeHeader((char*)&version, sizeof(short), 4);
}
void _SetBegin(short nCmdType)
{
short cmdType = htons(nCmdType);
_writeHeader((char*)&cmdType, sizeof(short), 2);
}
public:
short GetCmdType(void)
{
short nCmdType;
_readHeader((char*)&nCmdType, sizeof(short), 2);
return ntohs(nCmdType);
}
short GetVersion(void)
{
short c;
_readHeader((char *)&c, sizeof(short), 4);
return ntohs(c);
}
short GetBodyLength(void)
{
short nLen;
_readHeader((char*)&nLen, sizeof(short), 6);
return ntohs(nLen);
}
protected:
void _end(unsigned *sequence* = 0)
{
short nBody = m_nPacketSize - PACKET_HEADER_SIZE;
short bodyLen = htons(nBody);
_writeHeader((char*)&bodyLen, sizeof(short), 6);
}
void _reset(void)
{
memset(m_strBuf, 0, PACKET_BUFFER_SIZE);
m_nBufPos = PACKET_HEADER_SIZE;
m_nPacketSize = PACKET_HEADER_SIZE;
}
bool _Read(char *pOut, unsigned nLen)
{
if((nLen + m_nBufPos) > m_nPacketSize )
return false ;
memcpy(pOut, m_strBuf + m_nBufPos, nLen);
m_nBufPos += nLen;
return true;
}
bool _ReadDel(char *pOut, unsigned nLen)
{
if(!_Read(pOut, nLen)){
return false;
}
memcpy(m_strBuf + m_nBufPos - nLen, m_strBuf +
m_nBufPos, PACKET_BUFFER_SIZE - m_nBufPos);
m_nBufPos -= nLen;
m_nPacketSize -= nLen;
_end();
return true;
}
void _readundo(unsigned nLen)
{
m_nBufPos -= nLen;
}
char *_readpoint(unsigned nLen)
{
if((nLen + m_nBufPos) > m_nPacketSize){
return NULL;
}
char *p = &m_strBuf[m_nBufPos];
m_nBufPos += nLen;
return p;
}
bool _Write(const char *pIn, unsigned nLen)
{
if( (nLen + m_nPacketSize) > PACKET_BUFFER_SIZE){
return false ;
}
memcpy(m_strBuf+m_nPacketSize, pIn, nLen);
m_nPacketSize += nLen;
return true;
}
bool _Insert(const char *pIn, unsigned nLen)
{
if((nLen + m_nPacketSize) > PACKET_BUFFER_SIZE){
return false;
}
memcpy(m_strBuf+PACKET_HEADER_SIZE+nLen,
m_strBuf+PACKET_HEADER_SIZE, m_nPacketSize-PACKET_HEADER_SIZE);
memcpy(m_strBuf+PACKET_HEADER_SIZE, pIn, nLen);
m_nPacketSize += nLen;
_end();
return true;
}
bool _writezero(void)
{
if((m_nPacketSize + 1) > PACKET_BUFFER_SIZE){
return false ;
}
memset(m_strBuf+m_nPacketSize, '\0', sizeof(char)) ;
m_nPacketSize ++;
return true;
}
void _readHeader(char *pOut, unsigned nLen, unsigned nPos)
{
if( nPos+nLen <= PACKET_HEADER_SIZE)
{
memcpy(pOut, m_strBuf+nPos, nLen) ;
}
}
void _writeHeader(char *pIn, unsigned nLen, unsigned nPos)
{
if( nPos+nLen <= PACKET_HEADER_SIZE)
{
memcpy(m_strBuf+nPos, pIn, nLen) ;
}
}
};
template <unsigned BUFFER_SIZE, unsigned HEADER_SIZE=PROTOL_HEADER_SIZE>
class InputPacket: public PacketBase<BUFFER_SIZE, HEADER_SIZE>
{
public:
typedef PacketBase<BUFFER_SIZE, HEADER_SIZE> base;
int ReadInt(void)
{
int nValue = -1;
base::_Read((char*)&nValue, sizeof(int));
return ntohl(nValue);
}
short ReadShort(void)
{
short nValue = -1;
base::_Read((char*)&nValue, sizeof(short));
return ntohs(nValue);
}
BYTE ReadByte(void)
{
BYTE nValue = -1;
base::_Read((char*)&nValue, sizeof(BYTE));
return nValue;
}
int64_t ReadInt64(void)
{
int64_t nValue = -1;
base::_Read((char*)&nValue, sizeof(int64_t));
return ntohll(nValue);
}
bool ReadString(char *pOutString, unsigned nMaxLen)
{
int nLen = ReadInt();
if(nLen == -1){
return false;
}
if(nLen > nMaxLen || nLen+base::m_nBufPos>base::m_nPacketSize )
{
base::_readundo(sizeof(unsigned));
return false;
}
return base::_Read(pOutString, nLen);
}
char *ReadChar(void)
{
unsigned nLen = ReadInt();
if(nLen == (unsigned)-1 || nLen+base::m_nBufPos>base::m_nPacketSize) {
base::_readundo(sizeof(unsigned));
return NULL;
}
return base::_readpoint(nLen);
}
bool ReadString(string &str)
{
char *p = ReadChar();
str = (p == NULL ? "" : p);
return p != NULL;
}
int ReadBinary(char *pBuf, unsigned nMaxLen)
{
unsigned nLen = ReadInt();
if(nLen == (unsigned)-1 || nLen > nMaxLen ||
nLen+base::m_nBufPos>base::m_nPacketSize )
{
base::_readundo(sizeof(unsigned));
return -1;
}
if(base::_Read(pBuf, nLen)){
return nLen ;
}
return 0;
}
void Reset(void)
{
base::_reset();
}
bool Copy(const void *pInBuf, unsigned nLen)
{
return base::_copy(pInBuf, nLen);
}
};
template <unsigned BUFFER_SIZE, unsigned HEADER_SIZE=PROTOL_HEADER_SIZE>
class OutputPacket: public PacketBase<BUFFER_SIZE, HEADER_SIZE>
{
public:
OutputPacket(void){}
public:
typedef PacketBase<BUFFER_SIZE, HEADER_SIZE> base;
bool WriteInt(int nValue)
{
int value = htonl(nValue);
return base::_Write((char*)&value, sizeof(int));
}
bool WriteInt64(int64_t nValue)
{
int64_t value = htonll(nValue);
return base::_Write((char*)&value, sizeof(int64_t));
}
bool WriteByte(BYTE nValue)
{
return base::_Write((char*)&nValue, sizeof(BYTE));
}
bool WriteShort(short nValue)
{
short value = htons(nValue);
return base::_Write((char*)&value, sizeof(short));
}
bool InsertInt(int nValue)
{
int value = htonl(nValue);
return base::_Insert((char*)&value, sizeof(int));
}
bool InsertByte(BYTE nValue)
{
return base::_Insert((char*)&nValue, sizeof(BYTE));
}
bool WriteString(const char *pString)
{
int nLen = (int)strlen(pString) ;
WriteInt(nLen + 1) ;
return base::_Write(pString, nLen) && base::_writezero();
}
bool WriteString(const string &strDate)
{
int nLen = strDate.size();
WriteInt(nLen + 1) ;
return base::_Write(strDate.c_str(), nLen) && base::_writezero();
}
bool WriteBinary(const char *pBuf, unsigned nLen)
{
WriteInt(nLen) ;
return base::_Write(pBuf, nLen) ;
}
bool Copy(const void *pInBuf, unsigned nLen)
{
return base::_copy(pInBuf, nLen);
}
void Begin(short nCommand, char cVersion = SERVER_PACEKTVER)
{
base::_begin(nCommand, cVersion);
}
void End(void)
{
base::_end();
}
void SetBegin(short nCommand)
{
base::_SetBegin(nCommand);
}
};
typedef InputPacket<ES_TCP_MAX_BUFFER> ESInputPacket;
typedef OutputPacket<ES_TCP_MAX_BUFFER> ESOutputPacket;
And this is for memcache:
#include "ESMemcache.h"
using namespace std;
ESMemcache::ESMemcache(void)
{
}
ESMemcache::~ESMemcache(void)
{
}
int ESMemcache::setTimeOut(int msec)
{
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, msec);
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, msec);
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, msec);
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, -1);
return 0;
}
bool ESMemcache::Init(char* pIPPort, int msec)
{
memc = memcached_create(NULL);
int nPort = 0;
char * pszPort = strchr(pIPPort, ':');
if (pszPort) {
nPort = atoi(pszPort + 1);
*pszPort = 0;
}
setTimeOut(msec);
rc = memcached_server_add(memc, pIPPort, nPort);
if(rc != MEMCACHED_SUCCESS)
return false;
return rc == MEMCACHED_SUCCESS;
}
bool ESMemcache::SetRecord(char* key, const char* value,
const size_t bytes, const time_t expire)
{
rc = memcached_set(memc, key, strlen(key), value, bytes, expire, 0);
return rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED;
}
bool ESMemcache::Replace(char* key, const char* value, const size_t bytes, const time_t expire)
{
rc = memcached_replace(memc, key, strlen(key), value, bytes, expire, 0);
return rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED;
}
void ESMemcache::GetRecord(const char* key, std::string &value)
{
size_t value_length = 0;
uint32_t flags = 0;
char *val = memcached_get(memc, key, strlen(key), &value_length, &flags, &rc);
if(val !=NULL)
{
value = val;
free(val);
}
else
{
value.clear();
}
}
bool ESMemcache::DeleteRecord(const char* key)
{
rc = memcached_delete(memc, key, strlen(key), 0);
return rc == MEMCACHED_SUCCESS;
}
bool ESMemcache::Increment(const char *key, int offset, uint64_t &value)
{
rc = memcached_increment(memc, key, strlen(key), offset, &value);
return rc == MEMCACHED_SUCCESS;
}
bool ESMemcache::Decrement(const char *key, int offset, uint64_t &value)
{
rc = memcached_decrement(memc, key, strlen(key), offset, &value);
return rc == MEMCACHED_SUCCESS;
}
bool ESMemcache::IsKeyExist(const char *key)
{
size_t value_length = 0;
uint32_t flags = 0;
memcached_get(memc, key, strlen(key), &value_length, &flags, &rc);
if (rc == MEMCACHED_NOTFOUND) {
return false;
}
return true;
}
Some game logic:
#pragma once
#include "PokerGlobal.h"
class CPokerHands
{
public:
CPokerHands(void)
{
Initialize();
};
private:
POKERCARD m_Cards[TOTAL_OF_CARDS];
POKERCARD *m_pHands;
SAME_CARDS_COUNT m_SameCards[3];
UCHAR m_ColorCount[4];
UCHAR m_nFlushColor;
UCHAR m_nSameCount;
UCHAR m_nPairCount ;
UCHAR m_nThreeKindCount;
UCHAR m_nTypeHands ;
public:
int GetHandsType(void) {return m_nTypeHands;};
void CheckHandsType(POKERCARD *pHand)
{
assert(m_Cards[0].p_card != 0);
m_pHands = pHand;
}
void Initialize(void)
{
m_pHands = NULL;
memset(m_Cards, 0, sizeof(m_Cards));
memset(m_ColorCount, 0, sizeof(m_ColorCount));
memset(m_SameCards, 0, sizeof(m_SameCards));
}
void SetHands(USHORT c1, USHORT c2, USHORT *pBoardCard)
{
m_Cards[0].p_card = c1;
m_Cards[1].p_card = c2;
m_Cards[2].p_card = pBoardCard[0];
m_Cards[3].p_card = pBoardCard[1];
m_Cards[4].p_card = pBoardCard[2];
m_Cards[5].p_card = pBoardCard[3];
m_Cards[6].p_card = pBoardCard[4];
}
void SetHands(UCHAR *hands)
{
for(int i = 0; i < TOTAL_OF_CARDS; i ++)
{
m_Cards[i].p_color = hands[i*2];
m_Cards[i].p_value = hands[i*2+1];
assert(m_Cards[i].p_value >= 2 && m_Cards[i].p_value <= 14);
assert(m_Cards[i].p_color >= 1 && m_Cards[i].p_color <= 4);
}
}
private:
void SortCards(void)
{
USHORT temp, max;
for(int i = 0; i < TOTAL_OF_CARDS; i ++)
{
max = i;
for(int j = i + 1; j < TOTAL_OF_CARDS; j ++)
{
if((m_Cards[j].p_value > m_Cards[max].p_value))
max = j;
if(m_nFlushColor != 0 && m_Cards[j].p_value == m_Cards[max].p_value
&& m_Cards[j].p_color==m_nFlushColor)
max = j;
}
if(max != i)
{
temp = m_Cards[i].p_card;
m_Cards[i].p_card = m_Cards[max].p_card;
m_Cards[max].p_card = temp;
}
}
}
void CountFlush(void)
{
for(int i = 0; i < TOTAL_OF_CARDS; i ++)
{
if(++m_ColorCount[m_Cards[i].p_color-1] >= TOTAL_OF_HANDS)
{
m_nFlushColor = m_Cards[i].p_color;
}
}
}
void CountSameCards(void)
{
int i, nCount = 0;
UCHAR start = 0;
for(i = 1; i < TOTAL_OF_CARDS; i ++)
{
if(nCount == 0)
{
nCount = 1;
start = m_Cards[i-1].p_value;
}
if(start == m_Cards[i].p_value)
nCount++;
else
{
if(nCount >= 2)
set_same_cards(i, nCount);
nCount = 0;
}
}
if(nCount >= 2)
set_same_cards(i, nCount);
}
void set_same_cards(int nPos, int nCount)
{
m_SameCards[m_nSameCount].count = nCount;
switch(nCount)
{
case 2:
break;
case 3:
break;
};
}
int IsStraight(bool bFlush = true)
{
int i = 0, nCount = 0 ;
UCHAR pos = 0;
while(i ++ < TOTAL_OF_CARDS-1)
{
if(nCount == 0)
{
if(bFlush && m_Cards[i-1].p_color != m_nFlushColor)
nCount = 1;
pos = m_Cards[i-1].p_value;
}
continue;
if(pos == m_Cards[i].p_value + nCount)
{
if(++nCount == 4 && pos == 5 && m_Cards[0].p_value == 14)
{
if(!bFlush || m_Cards[0].p_color == m_nFlushColor)
return 100 + i;
}
if(nCount >= TOTAL_OF_HANDS) return i;
}else
{
if(m_Cards[i].p_value != m_Cards[i-1].p_value)
nCount = 0;
}
}
return -1;
}
private:
void FilterStraight(int nPos, bool bFlush = true)
{
if(nPos > 100)
{
nPos -= 100;
int nAcePos = 0;
{
for(int i = 0; i < 2; i ++)
{
if(m_Cards[i].p_color == m_nFlushColor)
{
nAcePos = i;
break;
}
}
}
m_pHands[handpos--].p_card = m_Cards[nAcePos].p_card;
}
while(handpos >= 0)
{
{
{
nPos --;
continue;
}
{
if(handpos < TOTAL_OF_HANDS - 1 &&
m_pHands[handpos+1].p_value == m_Cards[nPos].p_value)
{
nPos --;
continue;
}
}
m_pHands[handpos--].p_card = m_Cards[nPos--].p_card;
}
if(bFlush && m_pHands[0].p_value == 14)
m_nTypeHands = TYPE_ROYAL_FLUSH;
}
void FilterFourCard(int nPos)
{
m_pHands[0].p_card = m_Cards[nPos].p_card ;
m_pHands[1].p_card = m_Cards[nPos+1].p_card ;
m_pHands[2].p_card = m_Cards[nPos+2].p_card ;
m_pHands[3].p_card = m_Cards[nPos+3].p_card ;
nPos = nPos == 0 ? 4 : 0;
m_pHands[4].p_card = m_Cards[nPos].p_card;
}
void FilterFirstThreeCard(void)
{
int nPos = -1;
for(int i = 0; i < m_nSameCount; i ++)
{
if(m_SameCards[i].count == 3)
{
nPos = m_SameCards[i].pos;
break;
}
}
assert(nPos != -1);
for(int i = 0; i < 3; i ++)
m_pHands[i].p_card = m_Cards[nPos+i].p_card;
}
void FilterFullHouse(void)
{
int nPos = 0;
FilterFirstThreeCard();
if(m_nThreeKindCount > 1)
{
nPos = m_SameCards[1].pos;
m_pHands[3].p_card = m_Cards[nPos].p_card;
m_pHands[4].p_card = m_Cards[nPos+1].p_card;
}else
{
for(int i = 0; i < m_nSameCount; i ++)
{
if(m_SameCards[i].count == 2)
{
nPos = m_SameCards[i].pos;
break;
}
}
m_pHands[3].p_card = m_Cards[nPos].p_card;
m_pHands[4].p_card = m_Cards[nPos+1].p_card;
}
}
void FilterFlush(void)
{
int nPos = 0;
for(int i = 0; i < TOTAL_OF_CARDS && nPos < TOTAL_OF_HANDS; i ++)
if(m_Cards[i].p_color == m_nFlushColor)
m_pHands[nPos++].p_card = m_Cards[i].p_card;
}
void FilterThreeCard(void)
{
FilterFirstThreeCard();
UCHAR ch = m_pHands[0].p_value;
for(int i = 0, n = 3; i < TOTAL_OF_CARDS && n < TOTAL_OF_HANDS; i ++)
if(ch != m_Cards[i].p_value)
m_pHands[n++].p_card = m_Cards[i].p_card;
}
void FilterTwoPair(void)
{
assert(m_SameCards[0].count == 2);
assert(m_SameCards[1].count == 2);
int nPos = m_SameCards[0].pos;
m_pHands[0].p_card = m_Cards[nPos].p_card;
m_pHands[1].p_card = m_Cards[nPos+1].p_card;
nPos = m_SameCards[1].pos;
m_pHands[2].p_card = m_Cards[nPos].p_card;
m_pHands[3].p_card = m_Cards[nPos+1].p_card;
for(int i = 0; i < TOTAL_OF_CARDS; i ++)
{
if(m_Cards[i].p_value != m_pHands[0].p_value && m_Cards[i].p_value != m_pHands[2].p_value)
{
m_pHands[4].p_card = m_Cards[i].p_card;
break;
}
}
}
void FilterPair(void)
{
assert(m_SameCards[0].count == 2);
int nPos = m_SameCards[0].pos;
m_pHands[0].p_card = m_Cards[nPos].p_card;
m_pHands[1].p_card = m_Cards[nPos+1].p_card;
for(int i = 0, n = 2; i < TOTAL_OF_CARDS && n < TOTAL_OF_HANDS; i ++)
{
if(m_Cards[i].p_value != m_pHands[0].p_value)
m_pHands[n++].p_card = m_Cards[i].p_card;
}
}
void FilterHighCard(void)
{
for(int i = 0; i < TOTAL_OF_HANDS; i ++)
m_pHands[i].p_card = m_Cards[i].p_card;
if(m_pHands[0].p_value < 11)
m_nTypeHands = TYPE_PIE_CARD;
}
private:
bool CheckStraightFlush(void)
{
if(m_nFlushColor == 0)
return false;
int nPos = IsStraight(true);
if(nPos != -1)
{
m_nTypeHands = TYPE_STRAIGHT_FLUSH;
FilterStraight(nPos, true);
return true;
}
return false;
}
bool CheckFourCard(void)
{
for(int i = 0; i < m_nSameCount; i ++)
{
if(m_SameCards[i].count == 4)
{
m_nTypeHands = TYPE_FOUR_KIND;
return true;
}
}
return false;
}
bool CheckFullHouse(void)
{
if(m_nThreeKindCount < 1)
if(m_nThreeKindCount == 1 && m_nPairCount < 1)
m_nTypeHands = TYPE_FULL_HOUSE;
FilterFullHouse();
return true;
}
bool CheckFlush(void)
{
if(m_nFlushColor == 0)
return false;
m_nTypeHands = TYPE_FLUSH;
FilterFlush();
return true;
}
bool CheckStraight(void)
{
int nPos = IsStraight(false);
if(nPos != -1)
{
m_nTypeHands = TYPE_STRAIGHT;
FilterStraight(nPos, false);
return true;
}
return false;
}
bool CheckThreeCard(void)
{
if(m_nThreeKindCount < 1)
return false;
m_nTypeHands = TYPE_THREE_KIND;
FilterThreeCard();
return true;
}
bool CheckTwoPair(void)
{
if(m_nPairCount < 2)
return false;
m_nTypeHands = TYPE_TWO_PAIRS;
FilterTwoPair();
return true;
}
bool CheckPair(void)
{
if(m_nPairCount < 1)
return false;
m_nTypeHands = TYPE_PAIR;
FilterPair();
return true;
}
bool CheckHighCard(void)
{
m_nTypeHands = TYPE_HIGH_CARD;
FilterHighCard();
return true;
}
};
If you are interested in it, you can download the attachment.
Points of Interest
If I add an adoptor, this API can work with almost no
SQL. That is cool.
History
Alpha version.
Todo
- An adopter
- Auto serialization and deserialization