2066 lines
50 KiB
C++
2066 lines
50 KiB
C++
//---------------------------------------------------------------------------
|
|
#include <System.StrUtils.hpp>
|
|
#include "GameUnit.h"
|
|
#include "GlobalUnit.h"
|
|
#include "UtilityUnit.h"
|
|
|
|
#pragma hdrstop
|
|
|
|
//---------------------------------------------------------------------------
|
|
#pragma package(smart_init)
|
|
|
|
TSettings g_settings; //基本设置
|
|
TGameArray g_aGames;
|
|
|
|
int g_iRoad = 0; //全局路单/默认为六珠路
|
|
double g_fBalance = 0; //账户余额
|
|
bool g_bSimulate = true,
|
|
g_bShowSetting = true,
|
|
g_bGameOn = false,
|
|
g_bDeadPause = false, //全局爆缆暂停
|
|
g_bBetPause = false; //总体止赢止损暂停
|
|
|
|
int g_MinOnBet = 20, //最小注码
|
|
g_MaxOnBet = 50000; //最大注码
|
|
|
|
int g_nRBReport = 0; //实打流水上报
|
|
|
|
vector<TDot> g_aDots[4]; //资金图表数据 总赢利/模拟本金/账户余额
|
|
TIPGameArray g_aIPGames;
|
|
|
|
//---------------------------------------------------------------------------
|
|
int __fastcall Vid2Gid(String vid)
|
|
{
|
|
int id = 0;
|
|
|
|
if(g_iPlatform==PF_PA){
|
|
String sNum = vid.SubString(2,vid.Length()-1);
|
|
TryStrToInt(sNum, id);
|
|
|
|
if(id>0){
|
|
if(vid[1]=='D') id += 100;
|
|
else if(vid[1]=='M') id += 200;
|
|
else if(vid[1]=='P') id += 300;
|
|
else if(vid[1]=='E') id += 400;
|
|
else if(vid[1]!='N') id += (vid[1]-'A'+5) * 100;
|
|
}
|
|
}
|
|
else{
|
|
id = vid.ToInt();
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// TRankChip
|
|
TRankChip::TRankChip()
|
|
{
|
|
bWait = iType = 0;
|
|
pPolicy = NULL;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TRankChip::SetPolicy(TChipPolicy* pCP)
|
|
{
|
|
if(pPolicy!=pCP){
|
|
pPolicy = pCP;
|
|
Reset();
|
|
}
|
|
}
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// TTierChip
|
|
TTierChip::TTierChip()
|
|
{
|
|
iType = KIND_CHIP_HAN;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TTierChip::Reset()
|
|
{
|
|
if(pPolicy){
|
|
TTierRow* pRow = (TTierRow*)pPolicy->aRows[0];
|
|
nRnkChip = pRow->chip;
|
|
nCount = pRow->hands;
|
|
iRank = nWLDiff = nAccChip = nLos = 0;
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
int __fastcall TTierChip::HandleResult(int res, double wl)
|
|
{
|
|
if(res==1){
|
|
nWLDiff++;
|
|
nLos -= nRnkChip;
|
|
}
|
|
else if(res==2){
|
|
nWLDiff--;
|
|
nLos += nRnkChip;
|
|
}
|
|
else return iRank;
|
|
|
|
if(((TTierPolicy*)pPolicy)->bTierWinRet && iRank>0 && nWLDiff>0){ //高层赢回基
|
|
Reset();
|
|
}
|
|
else{
|
|
nCount--;
|
|
|
|
if(nCount==0){
|
|
TTierRow* pRow = (TTierRow*)pPolicy->aRows[iRank];
|
|
if(nWLDiff==0){//输赢平手 重打
|
|
nWLDiff = nLos = 0;
|
|
nCount = pRow->hands;
|
|
nRnkChip = nAccChip + pRow->chip;
|
|
return iRank;
|
|
}
|
|
|
|
if(nWLDiff>0){ //赢走向
|
|
iRank = pRow->iWin - 1;
|
|
nAccChip = 0; //净输累计清零
|
|
}
|
|
else{ //输走向
|
|
iRank = pRow->iLos - 1;
|
|
if(iRank>=0 && ((TTierPolicy*)pPolicy)->bTierAccChip){
|
|
if(iRank==0)
|
|
nAccChip = 0;
|
|
else{
|
|
nAccChip += nLos; //净输累加到下一层
|
|
if(nAccChip<0)
|
|
nAccChip = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(iRank>=0){
|
|
pRow = (TTierRow*)pPolicy->aRows[iRank];
|
|
nRnkChip = nAccChip + pRow->chip;
|
|
nCount = pRow->hands;
|
|
nWLDiff = nLos = 0;
|
|
}
|
|
}
|
|
else if(((TTierPolicy*)pPolicy)->bTierLos0){
|
|
if(nWLDiff<0) //输打0
|
|
nRnkChip = 0;
|
|
else{
|
|
TTierRow* pRow = (TTierRow*)pPolicy->aRows[iRank];
|
|
nRnkChip = nAccChip + pRow->chip;
|
|
}
|
|
}
|
|
}
|
|
|
|
return iRank;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// TLevelChip
|
|
TLevelChip::TLevelChip(bool bG)
|
|
{
|
|
iType = KIND_CHIP_LEV;
|
|
bGlobal = bG;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TLevelChip::CalcChip()
|
|
{
|
|
TLevelRow* pRow = (TLevelRow*)pPolicy->aRows[iRank];
|
|
nRnkChip = pRow->chip;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TLevelChip::Reset()
|
|
{
|
|
if(pPolicy){
|
|
bWait = fWLDiff = iRank = 0;
|
|
CalcChip();
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
int __fastcall TLevelChip::HandleResult(int res, double wl)
|
|
{
|
|
if(iRank<0 || res==3 && !bWait)
|
|
return iRank;
|
|
|
|
fWLDiff += wl;
|
|
|
|
bool bLevel = false;
|
|
TLevelRow* pRow = (TLevelRow*)pPolicy->aRows[iRank];
|
|
if(bGlobal && !g_aGames.bFloat && !((TLevelPolicy*)pPolicy)->bInstant){//非立即升降
|
|
if(fWLDiff >= pRow->nCondWin || fWLDiff <= -pRow->nCondLos){ //达到升降条件
|
|
g_aGames.AllBetOff();
|
|
bWait = g_aGames.nBetted[2]>0; //等待结算
|
|
DebugPrint("wait count: %d", g_aGames.nBetted[2]);
|
|
}
|
|
else if(bWait){
|
|
bWait = false;
|
|
DebugPrint("恢复下注 %.2f", fWLDiff);
|
|
}
|
|
}
|
|
|
|
if(!bWait){
|
|
if(fWLDiff >= pRow->nCondWin){ //赢走向
|
|
iRank = pRow->iWin - 1;
|
|
bLevel = true;
|
|
}
|
|
else if(fWLDiff <= -pRow->nCondLos){ //输走向
|
|
iRank = pRow->iLos - 1;
|
|
bLevel = true;
|
|
}
|
|
}
|
|
else{
|
|
DebugPrint("等待结算 %.2f", fWLDiff);
|
|
}
|
|
|
|
if(bLevel && bGlobal && !g_aGames.bFloat && ((TLevelPolicy*)pPolicy)->bInstant)
|
|
g_aGames.AllBetOff();
|
|
|
|
CalcLevelChip(bLevel, res);
|
|
|
|
return iRank;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TLevelChip::CalcLevelChip(bool bLevel, int res)
|
|
{
|
|
if(bLevel && iRank>=0){
|
|
fWLDiff = 0;
|
|
CalcChip();
|
|
|
|
if(bGlobal && !g_aGames.bFloat){
|
|
PostMessage(Application->MainFormHandle, UM_GLOBAL_BET, 0, 0);
|
|
DebugPrint("升降阶梯 %d", iRank);
|
|
}
|
|
}
|
|
}
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// TComboChip
|
|
TComboChip::TComboChip(bool bG)
|
|
{
|
|
iType = KIND_CHIP_COM;
|
|
pRnkPolicy = NULL;
|
|
bGlobal = bG;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TComboChip::CalcChip()
|
|
{
|
|
int nBaseChip = 0;
|
|
if(pRnkPolicy->kind==KIND_CHIP_RAN){
|
|
int mi = g_RandomChip.minChip,
|
|
ma = g_RandomChip.maxChip+1; //包含最大值
|
|
nBaseChip = mi + Random(ma - mi);
|
|
}
|
|
else
|
|
nBaseChip = ((TChipRow*)pRnkPolicy->aRows[iRnkSeq])->chip;
|
|
|
|
nRnkChip = nBaseChip * nRnkMul;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TComboChip::Reset()
|
|
{
|
|
if(pPolicy){
|
|
bWait = false;
|
|
|
|
fWLDiff = iRank = iRnkSeq = 0;
|
|
|
|
TComboRow* pRow = (TComboRow*)pPolicy->aRows[iRank];
|
|
CheckComboRow(pRow);
|
|
|
|
pRnkPolicy = (TChipPolicy*)g_aChipPolicies[pRow->iPolicy];
|
|
|
|
nRnkMul = pRow->chip;
|
|
|
|
if(!bGlobal || g_aGames.bFloat)
|
|
CalcChip();
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TComboChip::CalcLevelChip(bool bLevel, int res)
|
|
{
|
|
if(bLevel){
|
|
if(iRank>=0){
|
|
TComboRow* pRow = (TComboRow*)pPolicy->aRows[iRank];
|
|
CheckComboRow(pRow);
|
|
|
|
pRnkPolicy = (TChipPolicy*)g_aChipPolicies[pRow->iPolicy];
|
|
|
|
nRnkMul = pRow->chip;
|
|
fWLDiff = iRnkSeq = 0;
|
|
|
|
if(bGlobal && !g_aGames.bFloat){
|
|
g_aGames.ResetRankSeq();
|
|
PostMessage(Application->MainFormHandle, UM_GLOBAL_BET, 0, 0);
|
|
DebugPrint("升降阶梯 %d", iRank);
|
|
}
|
|
else{
|
|
CalcChip();
|
|
}
|
|
}
|
|
}
|
|
else if(!bGlobal || g_aGames.bFloat){
|
|
if(pRnkPolicy->kind!=KIND_CHIP_RAN){
|
|
TChipRow* pCR = (TChipRow*)pRnkPolicy->aRows[iRnkSeq];
|
|
if(res==1)
|
|
iRnkSeq = pCR->iWin - 1;
|
|
else if(res==2)
|
|
iRnkSeq = pCR->iLos - 1;
|
|
|
|
if(iRnkSeq<0) //立即重置
|
|
iRnkSeq = 0;
|
|
}
|
|
|
|
CalcChip();
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
int __fastcall TComboChip::GetComboChip(int& iRnk, int& iSeq)
|
|
{
|
|
if(bWait || iRank<0)
|
|
return -1;
|
|
|
|
if(iRnk!=iRank){
|
|
iRnk = iRank;
|
|
iSeq = 0;
|
|
}
|
|
|
|
int nBaseChip = 0;
|
|
if(pRnkPolicy->kind==KIND_CHIP_RAN){
|
|
int mi = g_RandomChip.minChip,
|
|
ma = g_RandomChip.maxChip+1; //包含最大值
|
|
nBaseChip = mi + Random(ma - mi);
|
|
}
|
|
else
|
|
nBaseChip = ((TChipRow*)pRnkPolicy->aRows[iSeq])->chip;
|
|
|
|
return nBaseChip * nRnkMul;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
int __fastcall TComboChip::GetRankSeq(int res, int iRnk, int iSeq)
|
|
{
|
|
if(res!=3 && iRnk==iRank && pRnkPolicy->kind!=KIND_CHIP_RAN){
|
|
TChipRow* pCR = (TChipRow*)pRnkPolicy->aRows[iSeq];
|
|
if(res==1)
|
|
iSeq = pCR->iWin - 1;
|
|
else
|
|
iSeq = pCR->iLos - 1;
|
|
|
|
if(iSeq<0) //立即重置
|
|
iSeq = 0;
|
|
}
|
|
|
|
return iSeq;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// TWLDiffChip
|
|
TWLDiffChip::TWLDiffChip(bool bG)
|
|
{
|
|
iType = KIND_CHIP_WLD;
|
|
bGlobal = bG;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TWLDiffChip::CalcChip()
|
|
{
|
|
TLevelRow* pRow = (TLevelRow*)pPolicy->aRows[iRank];
|
|
nRnkChip = pRow->chip;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TWLDiffChip::Reset()
|
|
{
|
|
if(pPolicy){
|
|
bWait = nWLDiff = iRank = 0;
|
|
CalcChip();
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
int __fastcall TWLDiffChip::HandleResult(int res, double wl)
|
|
{
|
|
if(iRank<0 || res==3 && !bWait)
|
|
return iRank;
|
|
|
|
if(res==1)
|
|
nWLDiff++;
|
|
else if(res==2)
|
|
nWLDiff--;
|
|
|
|
bool bLevel = false;
|
|
TLevelRow* pRow = (TLevelRow*)pPolicy->aRows[iRank];
|
|
if(bGlobal && !g_aGames.bFloat && !((TLevelPolicy*)pPolicy)->bInstant){//非立即升降
|
|
if(nWLDiff >= pRow->nCondWin || nWLDiff <= pRow->nCondLos){ //达到升降条件
|
|
g_aGames.AllBetOff();
|
|
bWait = g_aGames.nBetted[2]>0; //等待结算
|
|
DebugPrint("wait count: %d", g_aGames.nBetted[2]);
|
|
}
|
|
else if(bWait){
|
|
bWait = false;
|
|
DebugPrint("恢复下注 %d", nWLDiff);
|
|
}
|
|
}
|
|
|
|
if(!bWait){
|
|
if(nWLDiff >= pRow->nCondWin){ //赢走向
|
|
iRank = pRow->iWin - 1;
|
|
bLevel = true;
|
|
}
|
|
else if(nWLDiff <= pRow->nCondLos){ //输走向
|
|
iRank = pRow->iLos - 1;
|
|
bLevel = true;
|
|
}
|
|
}
|
|
else{
|
|
DebugPrint("等待结算 %d", nWLDiff);
|
|
}
|
|
|
|
if(bLevel){
|
|
if(bGlobal && !g_aGames.bFloat && ((TLevelPolicy*)pPolicy)->bInstant)
|
|
g_aGames.AllBetOff();
|
|
|
|
if(iRank>=0){
|
|
if(((TWLDiffPolicy*)pPolicy)->bIndie) //立即清零
|
|
nWLDiff = 0;
|
|
|
|
CalcChip();
|
|
|
|
if(bGlobal && !g_aGames.bFloat){
|
|
PostMessage(Application->MainFormHandle, UM_GLOBAL_BET, 0, 0);
|
|
DebugPrint("升降层级 %d", iRank);
|
|
}
|
|
}
|
|
}
|
|
|
|
return iRank;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// TGame
|
|
TGame::TGame(int iG)
|
|
{
|
|
iGame = iG;
|
|
hTable = NULL;
|
|
pRankChip = NULL;
|
|
|
|
Reset();
|
|
|
|
char name[16];
|
|
sprintf(name, "%04d", iG);
|
|
pSema = new CSema(name, 1);
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
TGame::~TGame()
|
|
{
|
|
for(int i=0; i<4; i++)
|
|
aMap[i].Clear();
|
|
|
|
ClearRankChip();
|
|
delete pSema;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TGame::ClearRankChip()
|
|
{
|
|
if(pRankChip){
|
|
delete pRankChip;
|
|
pRankChip = NULL;
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
TRankChip* __fastcall TGame::GetRankChip(int type)
|
|
{
|
|
if(pRankChip && !pRankChip->IsTypeOf(type))
|
|
ClearRankChip();
|
|
|
|
if(!pRankChip){
|
|
pRankChip = type==KIND_CHIP_HAN ? (TRankChip*)new TTierChip
|
|
: type==KIND_CHIP_LEV ? (TRankChip*)new TLevelChip
|
|
: type==KIND_CHIP_WLD ? (TRankChip*)new TWLDiffChip
|
|
: (TRankChip*)new TComboChip;
|
|
}
|
|
|
|
return pRankChip;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TGame::ClearResults()
|
|
{
|
|
aRes.clear();
|
|
|
|
for(int i=0; i<4; i++){
|
|
aRoad[i].clear();
|
|
lastRoad[i] = 0;
|
|
aMap[i].Clear(); //清理图数据
|
|
}
|
|
memset(winCount, 0, sizeof(winCount));
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGame::Reset()
|
|
{
|
|
profit = iState = iBet = nChip = iBetSeq = iChipSeq = 0;
|
|
gmstatus = timeout = countdown = 0;
|
|
bcard = pcard = "";
|
|
memset(seqCount, 0, sizeof(seqCount));
|
|
|
|
ClearResults();
|
|
aManBets.clear();
|
|
|
|
bRun = bRev = bReset = bBreak = bPause
|
|
= bReal = bIndPolicy = false;
|
|
nChipMul = iRoad = iBetPolicy = iChipPolicy = -1;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGame::ResetBet()
|
|
{
|
|
ClearBets();
|
|
|
|
iState = iBet = nChip = iBetSeq = iChipSeq = 0;
|
|
bReal = bReset = false;
|
|
aBets.clear();
|
|
|
|
if(pRankChip)
|
|
pRankChip->Reset();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
int __fastcall TGame::Color2Bet(TBetPolicy* pBP, char clr)
|
|
{
|
|
int bet = 0;
|
|
|
|
int s0 = aRoad[0].back(), //大路最后1列个数(假设为断)
|
|
sR = aRoad[0][aRoad[0].size() - pBP->road];
|
|
char c = s0==sR ? 1 : 2; //齐脚跳红
|
|
if(c==clr) //此处为红蓝
|
|
bet = lastRoad[0] ^ 0x3; //大路断
|
|
else
|
|
bet = lastRoad[0]; //大路连
|
|
|
|
return bet;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGame::CalcBet()
|
|
{
|
|
iBet = nChip = 0; //默认不下注
|
|
|
|
int iBP = iBetPolicy>=0 ? iBetPolicy : g_iBetPolicy;
|
|
TBetPolicy* pBP = (TBetPolicy*)g_aBetPolicies[iBP];
|
|
|
|
int uBP = iBetSeq >> 16,
|
|
uSeq = 0;
|
|
if(uBP!=pBP->id){ //改用ID判断避免方案删除带来问题
|
|
uBP = pBP->id;
|
|
aBets.clear();
|
|
}
|
|
|
|
if(!aBets.empty()){ //连续下注项
|
|
if(aBets[0]==0 || aBets[0]==4){
|
|
iBet = aBets[0];
|
|
}
|
|
else if(pBP->road<=1 || aBets[0]==3){ //珠盘/大路或打和
|
|
iBet = aBets[0]; //此处为庄闲和
|
|
}
|
|
else if(aRoad[0].size() >= pBP->road){//下三路
|
|
iBet = Color2Bet(pBP, aBets[0]);
|
|
}
|
|
}
|
|
else if(pBP->road==0){ //珠盘路
|
|
if(aRes.empty())
|
|
return;
|
|
|
|
if(pBP->kind==KIND_BET_DIF){ //庄闲差
|
|
int diff = winCount[0] - winCount[1];
|
|
int i = diff>=g_BPDiffBet.diff[0] ? 0
|
|
: diff<=-g_BPDiffBet.diff[1] ? 1
|
|
: -1;
|
|
if(i>=0){
|
|
vector<char> bets = TBetPolicy::ParseBet(g_BPDiffBet.bets[i]);
|
|
|
|
iBet = bets[0];
|
|
if(bets.size()>1){
|
|
for(int j=0; j<bets.size(); j++)
|
|
aBets.push_back(bets[j]);
|
|
}
|
|
}
|
|
}
|
|
else{
|
|
for(int i=0; i<pBP->aRows.size(); i++){ //按从上往下的顺序匹配
|
|
TBetRow* pRow = (TBetRow*)pBP->aRows[i];
|
|
|
|
bool bAllMatched = true;
|
|
int pos = aRes.size()-1; //最后一个位置开始
|
|
for(int j=pRow->cond.size()-1; j>=0; j--){ //从后往前匹配
|
|
int item = pRow->cond[j];
|
|
bool up = item & 0x80;
|
|
char ch = item & 0x3;
|
|
int num = (item & 0x7C) >> 2;
|
|
|
|
if(pos<0 || ch!=aRes[pos--]){ //个数不足或颜色不匹配
|
|
bAllMatched = false;
|
|
break;
|
|
}
|
|
|
|
bool bMatched = true;
|
|
for(int k=1; k<num; k++){
|
|
if(pos<0 || ch!=aRes[pos--]){//个数不足或颜色不匹配
|
|
bMatched = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(!bMatched){
|
|
bAllMatched = false;
|
|
break;
|
|
}
|
|
|
|
if(up){ //不定长
|
|
while(ch==aRes[pos]) pos--; //一直找到不同颜色
|
|
}
|
|
}
|
|
|
|
if(bAllMatched){ //匹配成功
|
|
iBet = pRow->bets[0];
|
|
if(pRow->bets.size()>1){
|
|
for(int j=0; j<pRow->bets.size(); j++)
|
|
aBets.push_back(pRow->bets[j]);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else{
|
|
vector<char>& road = aRoad[pBP->road-1];
|
|
if(road.empty())
|
|
return;
|
|
|
|
if(pBP->kind==KIND_BET_ASK){ //庄闲问路
|
|
int size0 = aRoad[0].size();
|
|
if(size0<4) return; //不够列数
|
|
|
|
if(size0>=4){
|
|
char cl[3], sR,
|
|
s0 = aRoad[0].back(); //大路最后1列个数(假设为断)
|
|
for(int i=0; i<3; i++){
|
|
sR = aRoad[0][size0 - i - 2];
|
|
cl[i] = s0==sR ? 1 : 2;
|
|
}
|
|
|
|
if(cl[0]!=cl[1] || cl[1]!=cl[2]) //不同色
|
|
return;
|
|
|
|
if(lastRoad[0]==2 && cl[0]==1 || lastRoad[0]==1 && cl[0]==2) //庄全红/闲全蓝
|
|
iBet = g_BPAskBet.bet[0];
|
|
else if(lastRoad[0]==1 && cl[0]==1 || lastRoad[0]==2 && cl[0]==2) //闲全红/庄全蓝
|
|
iBet = g_BPAskBet.bet[1];
|
|
}
|
|
}
|
|
else{
|
|
for(int i=0; i<pBP->aRows.size(); i++){ //按从上往下的顺序匹配
|
|
TBetRow* pRow = (TBetRow*)pBP->aRows[i];
|
|
if(road.size()<pRow->cond.size()) //列数不足
|
|
continue;
|
|
|
|
bool bAllMatched = true;
|
|
char last = lastRoad[pBP->road-1];
|
|
int col = road.size()-1; //最后一列开始
|
|
for(int j=pRow->cond.size()-1; j>=0 && bAllMatched; j--){ //从后往前匹配
|
|
int item = pRow->cond[j];
|
|
bool up = item & 0x80;
|
|
char ch = item & 0x3;
|
|
int num = (item & 0x7C) >> 2;
|
|
|
|
if(ch==last && (up && road[col]>=num || !up && road[col]==num)){ //该列成功
|
|
col--; //匹配下一列
|
|
last ^= 0x3; //下一列的颜色
|
|
}
|
|
else
|
|
bAllMatched = false;;
|
|
}
|
|
|
|
if(bAllMatched){ //匹配成功
|
|
if(pRow->bets[0]==0 || pRow->bets[0]==4){
|
|
iBet = pRow->bets[0];
|
|
}
|
|
if(pBP->road==1 || pRow->bets[0]==3){
|
|
iBet = pRow->bets[0]; //此处为庄闲和
|
|
}
|
|
else if(aRoad[0].size() >= pBP->road){//下三路
|
|
iBet = Color2Bet(pBP, pRow->bets[0]);
|
|
}
|
|
|
|
if(pRow->bets.size()>1){
|
|
for(int j=0; j<pRow->bets.size(); j++)
|
|
aBets.push_back(pRow->bets[j]);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
iBetSeq = (uBP<<16) + aRes.size()+1;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGame::CalcChip()
|
|
{
|
|
int iCP = iChipPolicy>=0 ? iChipPolicy : g_iChipPolicy;
|
|
TChipPolicy* pCP = (TChipPolicy*)g_aChipPolicies[iCP];
|
|
bool bGlobalChip = !bIndPolicy && (g_aGames.bFloat || pCP->kind>=KIND_CHIP_LEV
|
|
&& pCP->kind<=KIND_CHIP_WLD
|
|
&& ((TLevelPolicy*)pCP)->bTotalDiff);
|
|
int& iCS = !bIndPolicy && g_aGames.bFloat ? g_aGames.iChipSeq : iChipSeq;
|
|
|
|
int uCP = iCS >> 20,
|
|
uCRnk = (iCS & 0xFF000) >> 12,
|
|
uCSeq = iCS & 0xFFF;
|
|
if(uCP!=pCP->id){ //改用ID判断避免方案删除带来问题
|
|
uCRnk = uCSeq = 0;
|
|
iCS = (pCP->id<<20);
|
|
|
|
if(pCP->kind>=KIND_CHIP_HAN && pCP->kind<=KIND_CHIP_WLD){
|
|
TRankChip* pRC = bGlobalChip ? g_aGames.GetRankChip(pCP->kind)
|
|
: GetRankChip(pCP->kind);
|
|
pRC->SetPolicy(pCP);
|
|
}
|
|
else{
|
|
if(bGlobalChip && g_aGames.pRankChip)
|
|
g_aGames.ClearRankChip();
|
|
else
|
|
ClearRankChip();
|
|
}
|
|
}
|
|
|
|
if(pCP->kind>=KIND_CHIP_HAN && pCP->kind<=KIND_CHIP_WLD){
|
|
TRankChip* pRC = bGlobalChip ? g_aGames.GetRankChip(pCP->kind)
|
|
: GetRankChip(pCP->kind);
|
|
if(pCP->kind==KIND_CHIP_COM && bGlobalChip && !g_aGames.bFloat){
|
|
nChip = ((TComboChip*)pRC)->GetComboChip(uCRnk, uCSeq);
|
|
if(nChip>=0)
|
|
iCS = (pCP->id<<20) + (uCRnk<<12) + uCSeq;
|
|
}
|
|
else
|
|
nChip = pRC->GetChip();
|
|
|
|
if(nChip>0 && pCP->kind!=KIND_CHIP_COM)
|
|
nChip *= nChipMul<0 ? g_nChipMul : nChipMul;
|
|
}
|
|
else if(pCP->kind==KIND_CHIP_RAN){
|
|
int mi = g_RandomChip.minChip,
|
|
ma = g_RandomChip.maxChip+1; //包含最大值
|
|
nChip = mi + Random(ma - mi);
|
|
}
|
|
else{
|
|
TChipRow* pRow = (TChipRow*)pCP->aRows[uCSeq];
|
|
nChip = pRow->chip * (bIndPolicy ? nChipMul : g_nChipMul); //乘上倍数
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
int __fastcall TGame::CalcResult(int op)
|
|
{
|
|
int uBP = iBetSeq >> 16,
|
|
uBSeq = iBetSeq & 0xFFFF;
|
|
|
|
if(!iBet || !uBSeq)// || uBSeq>aRes.size() && op!=2)// || !nChip) 允许注码为0
|
|
return 0;
|
|
|
|
int dType = 0; //是否爆缆
|
|
int ret = 3;
|
|
double wl = 0;
|
|
|
|
if(op<2){ //非超时
|
|
int res = aRes[uBSeq-1];
|
|
|
|
if(!aBets.empty() && (!g_settings.bBetsNoTie || res!=3 || iBet==3) ){ //连续下注,不忽略和|结果非和|下注和,删除本项
|
|
aBets.erase(aBets.begin());
|
|
}
|
|
|
|
if(iBet==res){ //赢
|
|
ret = 1;
|
|
if(iBet==1)
|
|
wl = nChip * 0.95;
|
|
else if(iBet==2)
|
|
wl = nChip;
|
|
else
|
|
wl = nChip * 8;
|
|
}
|
|
else if(res!=3){ //输
|
|
ret = 2;
|
|
wl = -nChip;
|
|
}
|
|
else if(nChip>0){ //有效流水不计和
|
|
g_aGames.betData.amounts[0] -= nChip;
|
|
|
|
if(bReal){ //和 实打统计
|
|
g_aGames.betData.amounts[1] -= nChip; //实打流水
|
|
g_nRBReport -= nChip;
|
|
}
|
|
|
|
PostMessage(Application->MainFormHandle, UM_STATE_UPDATE, STATE_AMOUNT, 0);
|
|
}
|
|
|
|
TBetLog* pLog = NewBetLog();
|
|
pLog->ev = LOGEVT_RES;
|
|
pLog->op = ret;
|
|
pLog->num = wl;
|
|
SendMessage(Application->MainFormHandle, UM_LOG_UPDATE, 0, (long)pLog);
|
|
}
|
|
else if(op==3){//注单撤销
|
|
g_aGames.betData.amounts[0] -= nChip;
|
|
|
|
if(bReal){ //实打统计
|
|
g_aGames.betData.amounts[1] -= nChip; //实打流水
|
|
g_nRBReport -= nChip;
|
|
}
|
|
|
|
PostMessage(Application->MainFormHandle, UM_STATE_UPDATE, STATE_AMOUNT, 0);
|
|
|
|
TBetLog* pLog = NewBetLog();
|
|
pLog->ev = LOGEVT_QUASH;
|
|
SendMessage(Application->MainFormHandle, UM_LOG_UPDATE, 0, (long)pLog);
|
|
}
|
|
else if(op==2 && (g_aGames.bFloat || !g_aGames.pRankChip)){ //超时仅处理总体组合阶梯
|
|
return ret;
|
|
}
|
|
|
|
//处理注码步骤
|
|
int iCP = iChipPolicy>=0 ? iChipPolicy : g_iChipPolicy;
|
|
TChipPolicy* pCP = (TChipPolicy*)g_aChipPolicies[iCP];
|
|
bool bGlobalChip = !bIndPolicy && (g_aGames.bFloat || pCP->kind>=KIND_CHIP_LEV
|
|
&& pCP->kind<=KIND_CHIP_WLD
|
|
&& ((TLevelPolicy*)pCP)->bTotalDiff);
|
|
int& iCS = !bIndPolicy && g_aGames.bFloat ? g_aGames.iChipSeq : iChipSeq;
|
|
int uCP = iCS >> 20,
|
|
uCRnk = (iCS & 0xFF000) >> 12,
|
|
uCSeq = iCS & 0xFFF;
|
|
if(uCP!=pCP->id){
|
|
uCRnk = uCSeq = 0;
|
|
|
|
if(pCP->kind>=KIND_CHIP_HAN && pCP->kind<=KIND_CHIP_WLD){
|
|
TRankChip* pRC = bGlobalChip ? g_aGames.GetRankChip(pCP->kind)
|
|
: GetRankChip(pCP->kind);
|
|
pRC->SetPolicy(pCP);
|
|
}
|
|
else{
|
|
if(bGlobalChip && g_aGames.pRankChip)
|
|
g_aGames.ClearRankChip();
|
|
else
|
|
ClearRankChip();
|
|
}
|
|
}
|
|
else if(pCP->kind>=KIND_CHIP_HAN && pCP->kind<=KIND_CHIP_WLD){
|
|
TRankChip* pRC = bGlobalChip ? g_aGames.GetRankChip(pCP->kind) : GetRankChip(pCP->kind);
|
|
|
|
if(pCP->kind==KIND_CHIP_COM && bGlobalChip && !g_aGames.bFloat && op<2)
|
|
uCSeq = ((TComboChip*)pRC)->GetRankSeq(ret, uCRnk, uCSeq);
|
|
|
|
int rnk = (g_aGames.bFloat && g_aGames.iFloatGame!=iGame) ? uCRnk
|
|
: pRC->HandleResult(ret, wl);
|
|
if(rnk!=uCRnk){
|
|
uCRnk = rnk;
|
|
uCSeq = 0;
|
|
}
|
|
}
|
|
else if(pCP->kind==KIND_CHIP_NOR && (!g_aGames.bFloat || g_aGames.iFloatGame==iGame)){
|
|
TChipRow* pRow = (TChipRow*)pCP->aRows[uCSeq];
|
|
if(ret==1)
|
|
uCSeq = pRow->iWin - 1;
|
|
else if(ret==2)
|
|
uCSeq = pRow->iLos - 1;
|
|
}
|
|
|
|
if(uCSeq<0 || uCRnk<0){
|
|
dType = pCP->dead + 1;
|
|
uCRnk = uCSeq = 0;
|
|
|
|
g_aGames.betData.dead++;
|
|
|
|
if(!bGlobalChip){
|
|
TBetLog* pLog = NewBetLog();
|
|
pLog->ev = LOGEVT_DEAD;
|
|
pLog->op = pCP->dead;
|
|
pLog->num = pCP->deadPause;
|
|
SendMessage(Application->MainFormHandle, UM_LOG_UPDATE, 0, (long)pLog);
|
|
}
|
|
|
|
PostMessage(Application->MainFormHandle, UM_STATE_UPDATE, STATE_MISC, 0);
|
|
}
|
|
|
|
if(op<=2) //撤销不更新iCS
|
|
iCS = (pCP->id<<20) + (uCRnk<<12) + uCSeq;
|
|
|
|
if(wl!=0){
|
|
profit += wl;
|
|
|
|
//模拟实打赢利统计
|
|
if(bReal){
|
|
g_aGames.betData.profits[4] += wl;
|
|
g_aGames.betData.profits[7] += wl;
|
|
}
|
|
else
|
|
g_aGames.betData.profits[6] += wl;
|
|
|
|
//当期赢利
|
|
g_aGames.betData.profits[3] += wl;
|
|
|
|
if(wl>0 && g_aGames.fCurrProfitPeak < g_aGames.betData.profits[3]) //更新当期赢利峰值
|
|
g_aGames.fCurrProfitPeak = g_aGames.betData.profits[3];
|
|
|
|
//总赢利及峰谷值
|
|
double profit = g_aGames.betData.profits[0] + wl;
|
|
g_aGames.betData.profits[0] = profit;
|
|
if(profit>g_aGames.betData.profits[1]){
|
|
g_aGames.betData.profits[1] = profit;
|
|
PostMessage(Application->MainFormHandle, UM_STATE_UPDATE, STATE_PEAK, 1);
|
|
}
|
|
else if(profit<g_aGames.betData.profits[2]){
|
|
g_aGames.betData.profits[2] = profit;
|
|
PostMessage(Application->MainFormHandle, UM_STATE_UPDATE, STATE_PEAK, 2);
|
|
}
|
|
}
|
|
|
|
if(op!=2 && wl>=0 && nChip>0){
|
|
if(g_settings.bSimAccOn){
|
|
bool bUpdate = false;
|
|
if(!bReal || g_settings.bSyncReal){ //赢跟和都要加本金
|
|
g_settings.fSimAcc += wl + nChip;
|
|
bUpdate = true;
|
|
}
|
|
|
|
if(bReal && g_bTesting){
|
|
g_fBalance += wl + nChip;
|
|
bUpdate = true;
|
|
}
|
|
|
|
if(bUpdate)
|
|
PostMessage(Application->MainFormHandle, UM_STATE_UPDATE, STATE_BALANCE, 0);
|
|
}
|
|
}
|
|
|
|
if(ret==1){
|
|
g_aGames.betData.counts[0]++;
|
|
PostMessage(Application->MainFormHandle, UM_STATE_UPDATE, STATE_COUNT, 0);
|
|
|
|
int* seq = g_aGames.bFloat ? g_aGames.seqCount : seqCount;
|
|
seq[0]++;
|
|
if(seq[0] > g_aGames.betData.counts[2]){
|
|
g_aGames.betData.counts[2] = seq[0];
|
|
PostMessage(Application->MainFormHandle, UM_STATE_UPDATE, STATE_COUNT, 2);
|
|
}
|
|
seq[1] = 0;//连输终止
|
|
}
|
|
else if(ret==2){
|
|
g_aGames.betData.counts[1]++;
|
|
PostMessage(Application->MainFormHandle, UM_STATE_UPDATE, STATE_COUNT, 1);
|
|
|
|
int* seq = g_aGames.bFloat ? g_aGames.seqCount : seqCount;
|
|
seq[1]++;
|
|
if(seq[1] > g_aGames.betData.counts[3]){
|
|
g_aGames.betData.counts[3] = seq[1];
|
|
PostMessage(Application->MainFormHandle, UM_STATE_UPDATE, STATE_COUNT, 3);
|
|
}
|
|
seq[0] = 0;//连赢终止
|
|
}
|
|
|
|
if(wl!=0)
|
|
PostMessage(Application->MainFormHandle, UM_STATE_UPDATE, STATE_BET_R, ret);
|
|
|
|
if(dType) ret += dType<<16;
|
|
return ret;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGame::HandleResult(int op)
|
|
{
|
|
timeout = 0;
|
|
|
|
if(!aManBets.empty()){ //处理手工下注
|
|
if(op==0){ //正常结算
|
|
int res = aRes.back();
|
|
double wl = 0;
|
|
for(int i=aManBets.size()-1; i>=0; i--){
|
|
TManBet& rMB = aManBets[i];
|
|
if(rMB.state==ST_BETTED){
|
|
if(res==1)
|
|
wl += rMB.chips[0] * 0.95 - rMB.chips[1] - rMB.chips[2];
|
|
else if(res==2)
|
|
wl += rMB.chips[1] - rMB.chips[0] - rMB.chips[2];
|
|
else if(res==3){ //和
|
|
wl += rMB.chips[2] * 8; // - rMB.chips[0] - rMB.chips[1];
|
|
|
|
int refund = rMB.chips[0] + rMB.chips[1]; //有效投注不计和
|
|
if(refund){
|
|
g_nRBReport -= refund;
|
|
g_aGames.betData.amounts[2] -= refund; //手工流水
|
|
PostMessage(Application->MainFormHandle, UM_STATE_UPDATE, STATE_MAN, 1);
|
|
}
|
|
}
|
|
}
|
|
aManBets.pop_back();
|
|
}
|
|
|
|
if(hTable) PostMessage(hTable, UM_TAB_UPDATE, UPDATE_MANRES, wl);
|
|
|
|
if(wl!=0){
|
|
g_aGames.betData.profits[5] += wl;
|
|
PostMessage(Application->MainFormHandle, UM_STATE_UPDATE, STATE_MAN, 0);
|
|
}
|
|
}
|
|
else if(op==1){ //数据异常
|
|
aManBets.clear();
|
|
}
|
|
else if(op==3){ //注单撤销
|
|
for(int i=aManBets.size()-1; i>=0; i--){
|
|
TManBet& rMB = aManBets[i];
|
|
if(rMB.state==ST_BETTED){
|
|
int refund = rMB.chips[0] + rMB.chips[1] + rMB.chips[2]; //有效投注不计和
|
|
if(refund){
|
|
g_nRBReport -= refund;
|
|
g_aGames.betData.amounts[2] -= refund; //手工流水
|
|
PostMessage(Application->MainFormHandle, UM_STATE_UPDATE, STATE_MAN, 1);
|
|
}
|
|
}
|
|
aManBets.pop_back();
|
|
}
|
|
}
|
|
}
|
|
|
|
if((iState==ST_BETTED || iState==ST_EXPIRED) && ((iBetSeq & 0xFFFF)<=aRes.size() || op>=2)){
|
|
if(iState==ST_BETTED){
|
|
if(g_aGames.nBetted[bReal]>0)
|
|
g_aGames.nBetted[bReal]--; //减少下注个数
|
|
if(!bIndPolicy && g_aGames.nBetted[2]>0)
|
|
g_aGames.nBetted[2]--; //全局计算下注个数
|
|
}
|
|
|
|
if(op==2)
|
|
iState = ST_EXPIRED;
|
|
else if(op==3)
|
|
iState = ST_QUASH;
|
|
else
|
|
iState = ST_PAID;
|
|
|
|
int ret = CalcResult(op);
|
|
|
|
if(g_bGameOn){
|
|
int dead = ret >> 16;
|
|
|
|
if(bRun && (op<2 || dead)){
|
|
int wl = ret & 0xFF;
|
|
|
|
//止赢止损
|
|
bool stop = false;
|
|
if(wl==1 && g_settings.bTableStopWin && profit>=g_settings.nTableStopWin //单桌止赢
|
|
|| wl==2 && g_settings.bTableStopLos && profit<=-g_settings.nTableStopLos){ //单桌止赢
|
|
stop = true;
|
|
|
|
TBetLog* pLog = NewBetLog();
|
|
pLog->ev = wl==1 ? LOGEVT_STOPWIN : LOGEVT_STOPLOS;
|
|
pLog->op = wl==1 ? g_settings.iTableWinOp : g_settings.iTableLosOp;
|
|
pLog->num = wl==1 ? g_settings.nTableWinPause : g_settings.nTableLosPause;
|
|
SendMessage(Application->MainFormHandle, UM_LOG_UPDATE, 0, (long)pLog);
|
|
}
|
|
|
|
//处理游台
|
|
bool bFloat = false;
|
|
if(g_aGames.bFloat && g_aGames.iFloatGame==iGame){
|
|
if((g_settings.iFloatMode & 1) && aBets.empty() //连续下注项结束换台
|
|
|| (g_settings.iFloatMode & 4) && wl==2 //输换台
|
|
|| (g_settings.iFloatMode & 8) && wl==1 //赢换台
|
|
|| (g_settings.iFloatMode & 16) && wl==3 //和换台
|
|
|| g_settings.bHaltBet && aRes.size()>=g_settings.nHaltBet){//开局X手后停止下注
|
|
aBets.clear();
|
|
g_aGames.SetSwitchable(true, iGame);
|
|
bFloat = true;
|
|
}
|
|
|
|
if(dead && g_bGameOn){
|
|
int pause = dead==3 ? ((TChipPolicy*)g_aChipPolicies[g_iChipPolicy])->deadPause : 0;
|
|
SendMessage(Application->MainFormHandle, UM_FLOAT_DEAD, dead-1, pause);
|
|
}
|
|
}
|
|
|
|
//处理爆缆
|
|
if(dead && (bIndPolicy || !g_aGames.bFloat)){
|
|
if(!bIndPolicy && g_aGames.pRankChip){
|
|
// DebugPrint("总体阶梯爆缆");
|
|
int pause = dead==3 ? ((TChipPolicy*)g_aChipPolicies[g_iChipPolicy])->deadPause : 0;
|
|
SendMessage(Application->MainFormHandle, UM_GLOBAL_DEAD, dead-1, pause);
|
|
}
|
|
else{
|
|
bReset = true;
|
|
if(dead==2) //新局重启
|
|
bBreak = true;
|
|
}
|
|
}
|
|
|
|
//处理止盈止损
|
|
if(stop){
|
|
bReset = true;
|
|
|
|
int iOp = wl==1 ? g_settings.iTableWinOp : g_settings.iTableLosOp;
|
|
ret += (iOp+1)<<24;
|
|
if(iOp==1) //新局重启
|
|
bBreak = true;
|
|
}
|
|
|
|
if(bFloat && !dead)
|
|
PostMessage(Application->MainFormHandle, UM_FLOAT_BET, 0, 0);
|
|
}
|
|
else if(g_aGames.bFloat && g_aGames.iFloatGame==iGame){
|
|
g_aGames.SetSwitchable(true, 0); //非强制换台
|
|
PostMessage(Application->MainFormHandle, UM_FLOAT_BET, 0, 0);
|
|
}
|
|
}
|
|
|
|
if(op!=2)
|
|
if(hTable) PostMessage(hTable, UM_LOG_UPDATE, iState, ret);
|
|
}
|
|
else if(iState==ST_PAID || iState==ST_NOBET){
|
|
iState = ST_INIT;
|
|
if(hTable) PostMessage(hTable, UM_LOG_UPDATE, iState, 0);
|
|
}
|
|
|
|
if(op<2){
|
|
iBetSeq &= 0xFFFF0000;
|
|
|
|
if(hTable) PostMessage(hTable, UM_TAB_UPDATE, UPDATE_ROAD, 0);
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGame::ClearBets()
|
|
{
|
|
aManBets.clear();
|
|
|
|
if(iState==ST_BETTED || iState==ST_EXPIRED){
|
|
if(iState==ST_BETTED){
|
|
if(g_aGames.nBetted[bReal]>0)
|
|
g_aGames.nBetted[bReal]--; //减少下注个数
|
|
if(!bIndPolicy && g_aGames.nBetted[2]>0)
|
|
g_aGames.nBetted[2]--; //全局计算下注个数
|
|
}
|
|
|
|
iState = iBetSeq = 0;
|
|
timeout = 0;
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
bool __fastcall TGame::CanBet()
|
|
{
|
|
return bRun && g_bGameOn && !bPause && !g_bBetPause && (bIndPolicy || !g_bDeadPause);
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGame::GameOn()
|
|
{
|
|
if(g_settings.bInitBetChipByStart || g_aGames.bFloat) //挂机初始化/游台也要初始化
|
|
bReset = true;
|
|
|
|
if(g_settings.bInitTabProfitByStart){ //开始挂机重置台桌赢利
|
|
profit = 0;
|
|
PostMessage(hTable, UM_TAB_UPDATE, UPDATE_RESET, 0);
|
|
}
|
|
|
|
if(g_settings.bInitClearTabLog) //开始挂机清空台桌下注记录
|
|
SendMessage(hTable, UM_LOG_UPDATE, -1, 0);
|
|
|
|
if(g_settings.bWaitNew && aRes.size()>0){ //挂机等待新局
|
|
bBreak = true;
|
|
}
|
|
else{
|
|
bBreak = false;
|
|
|
|
if(bRun && gmstatus==1 && timeout>4)
|
|
AutoBetOn();
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGame::GameOff()
|
|
{
|
|
AutoBetOff();
|
|
bReset = bBreak = false;
|
|
|
|
if(bPause){
|
|
bPause = false;
|
|
PostMessage(hTable, UM_TAB_UPDATE, UPDATE_RESET, 3);
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGame::AutoBetOn(bool bR)
|
|
{
|
|
CMutexLock mutex(pSema);
|
|
|
|
if(iState>=ST_NOBET && iState<=ST_BETTED) //已下注
|
|
return;
|
|
|
|
if((iState==ST_PAID || iState==ST_QUASH) && gmstatus!=0 && gmstatus!=2){
|
|
iState = ST_INIT;
|
|
if(hTable) PostMessage(hTable, UM_LOG_UPDATE, iState, 0);
|
|
}
|
|
|
|
if(bR) bReset = true;
|
|
|
|
if(aRes.empty() && bRun && g_bGameOn && (gmstatus==1 || gmstatus==12)){ //新局上报,不受暂停影响
|
|
bBreak = false;
|
|
|
|
if(iState!=ST_ROUND){
|
|
iState = ST_ROUND;
|
|
if(hTable) PostMessage(hTable, UM_LOG_UPDATE, iState, 0);
|
|
TBetLog* pLog = NewBetLog();
|
|
pLog->ev = LOGEVT_ROUND;
|
|
SendMessage(Application->MainFormHandle, UM_LOG_UPDATE, 0, (long)pLog);
|
|
|
|
if(g_settings.bInitBetByGame){ //新局重置打法
|
|
iBet = iBetSeq = 0;
|
|
aBets.clear();
|
|
}
|
|
|
|
if(g_settings.bInitChipByGame){ //新局重置注码
|
|
nChip = iChipSeq = 0;
|
|
}
|
|
|
|
if(g_settings.bInitProfitByGame && profit!=0 //新局重置赢利
|
|
|| g_settings.bTableStopWin && profit>=g_settings.nTableStopWin //止赢重置
|
|
|| g_settings.bTableStopLos && profit<=-g_settings.nTableStopLos){ //止损重置
|
|
profit = 0;
|
|
PostMessage(hTable, UM_TAB_UPDATE, UPDATE_RESET, 0);
|
|
}
|
|
}
|
|
|
|
if(aBets.empty()) //连续下注可从新局开始
|
|
return;
|
|
}
|
|
|
|
if(bBreak || gmstatus!=1 || !CanBet() || !g_bSimulate && timeout<3){ //非下注状态/暂停中/实打时间太短,放弃
|
|
return;
|
|
}
|
|
|
|
if(g_settings.bHoldBet && aRes.size()<g_settings.nHoldBet //开局X手后开始下注
|
|
|| g_settings.bHaltBet && aRes.size()>=g_settings.nHaltBet){ //开局X手后停止下注
|
|
return;
|
|
}
|
|
|
|
if(g_aGames.bFloat && !bIndPolicy && !g_aGames.CanFloatBet(iGame)){//游台是否能下注
|
|
return;
|
|
}
|
|
|
|
if(bReset)
|
|
ResetBet();
|
|
CalcBet();
|
|
|
|
if(g_aGames.bFloat && !bIndPolicy){
|
|
if(!g_aGames.CanFloatBet(iGame)){ //游台是否能下注
|
|
iBet = iBetSeq = bBreak = 0;
|
|
aBets.clear();
|
|
}
|
|
else if(iBet>0 && iBet<4){
|
|
g_aGames.SetSwitchable(false, iGame); //游台下注
|
|
}
|
|
else if(!g_aGames.bSwitchable && g_aGames.iFloatGame==iGame
|
|
&& aBets.size()==1 && (g_settings.iFloatMode & 1)){ //最后一项不打,强制换台
|
|
g_aGames.SetSwitchable(true, iGame);
|
|
}
|
|
}
|
|
|
|
if(iBet==0 || iBet==4){
|
|
if(!aBets.empty()){//连续下注 不打/局停不可取消
|
|
aBets.erase(aBets.begin()); //删除本项
|
|
|
|
iState = ST_NOBET;
|
|
if(hTable) PostMessage(hTable, UM_LOG_UPDATE, iState, 0);
|
|
|
|
// TBetLog* pLog = NewBetLog();
|
|
// pLog->ev = LOGEVT_BET;
|
|
// pLog->op = iBet;
|
|
// SendMessage(Application->MainFormHandle, UM_LOG_UPDATE, 0, (long)pLog);
|
|
}
|
|
|
|
if(iBet==4)
|
|
bBreak = true;
|
|
|
|
return;
|
|
}
|
|
|
|
CalcChip();
|
|
if(nChip>=0){
|
|
iState = ST_BETSET;
|
|
if(hTable) PostMessage(hTable, UM_LOG_UPDATE, iState, 0);
|
|
PostMessage(Application->MainFormHandle, UM_SETBET, iGame, 0);
|
|
|
|
if(nChip>g_aGames.betData.maxChip){ //最大下注金额
|
|
g_aGames.betData.maxChip = nChip;
|
|
PostMessage(Application->MainFormHandle, UM_STATE_UPDATE, STATE_MISC, 0);
|
|
}
|
|
}
|
|
|
|
//止赢止损后需重置赢利
|
|
if(g_settings.bTableStopWin && profit>=g_settings.nTableStopWin
|
|
|| g_settings.bTableStopLos && profit<=-g_settings.nTableStopLos){
|
|
profit = 0;
|
|
PostMessage(hTable, UM_TAB_UPDATE, UPDATE_RESET, 0);
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGame::AutoBetOff(bool bB)
|
|
{
|
|
CMutexLock mutex(pSema);
|
|
|
|
if(iState==ST_BETSET || iState==ST_BETTING){ //下注超时或取消
|
|
iState = ST_CANCELED;
|
|
iBet = nChip = 0;
|
|
// iBetSeq &= 0xFFFF0000;
|
|
|
|
// aBets.clear();
|
|
if(hTable) PostMessage(hTable, UM_LOG_UPDATE, iState, 0);
|
|
}
|
|
// else if(!bRun)
|
|
// aBets.clear();
|
|
|
|
if(iState!=ST_BETTED && g_bGameOn && g_aGames.bFloat && !g_aGames.bSwitchable
|
|
&& g_aGames.iFloatGame==iGame){ //游台取消下注标志,以免阻塞下注
|
|
if(!bRun || (g_settings.iFloatMode & 1) && aBets.empty()){ //每注换台或本台停止
|
|
g_aGames.SetSwitchable(true, 0); //非强制换台
|
|
PostMessage(Application->MainFormHandle, UM_FLOAT_BET, 0, 0);
|
|
}
|
|
}
|
|
|
|
// if(iState==ST_NOBET){
|
|
// iState = ST_INIT;
|
|
// if(hTable) PostMessage(hTable, UM_LOG_UPDATE, iState, 0);
|
|
// }
|
|
|
|
if(bB && aRes.size()>0) bBreak = true;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGame::BetResp(int res, int chips[])
|
|
{
|
|
if(chips){ //ABThread返回时仅手工下注会携带chips
|
|
for(int i=aManBets.size()-1; i>=0; i--){ //先匹配手工下注
|
|
TManBet& rMB = aManBets[i];
|
|
|
|
if(rMB.state==ST_BETTING){
|
|
if(g_iPlatform==PF_DB && res){ //DB平台下注失败无法匹配金额
|
|
bool bMatch = true;
|
|
if(chips[0] || chips[1] || chips[2]){
|
|
for(int c=0; c<3; c++){
|
|
if(!chips[c] && rMB.chips[c] || chips[c] && !rMB.chips[c]){
|
|
bMatch = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!bMatch)
|
|
continue;
|
|
}
|
|
else if(memcmp(chips, rMB.chips, sizeof(rMB.chips))) //非DB平台或下注成功 需确认金额匹配
|
|
continue;
|
|
|
|
if(res==0){
|
|
rMB.state = ST_BETTED;
|
|
|
|
int amo = chips[0] + chips[1] + chips[2];
|
|
g_aGames.betData.amounts[2] += amo; //手工流水
|
|
g_nRBReport += amo;
|
|
|
|
PostMessage(Application->MainFormHandle, UM_STATE_UPDATE, STATE_MAN, 1);
|
|
}
|
|
else
|
|
aManBets.erase(aManBets.begin()+i); //失败删除
|
|
|
|
if(hTable) PostMessage(hTable, UM_TAB_UPDATE, UPDATE_MANBET, res);
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
//未匹配到手工下注,再处理自动下注
|
|
if(iState==ST_BETTING){
|
|
iState = res==0 ? ST_BETTED : ST_FAILED;
|
|
if(hTable) PostMessage(hTable, UM_LOG_UPDATE, iState, res);
|
|
|
|
if(res==0){
|
|
g_aGames.nBetted[bReal]++; //增加下注个数
|
|
if(!bIndPolicy)
|
|
g_aGames.nBetted[2]++; //全局计算下注
|
|
|
|
TBetLog* pLog = NewBetLog();
|
|
pLog->ev = LOGEVT_BET;
|
|
pLog->op = iBet;
|
|
pLog->num = nChip;
|
|
SendMessage(Application->MainFormHandle, UM_LOG_UPDATE, 0, (long)pLog);
|
|
|
|
if(nChip>0){
|
|
g_aGames.betData.amounts[0] += nChip;
|
|
|
|
if(bReal){
|
|
g_aGames.betData.amounts[1] += nChip; //实打流水
|
|
g_nRBReport += nChip;
|
|
}
|
|
|
|
if(g_settings.bSimAccOn){
|
|
bool bUpdate = false;
|
|
if(!bReal || g_settings.bSyncReal){
|
|
g_settings.fSimAcc -= nChip;
|
|
bUpdate = true;
|
|
}
|
|
|
|
if(bReal && g_bTesting){
|
|
g_fBalance -= nChip;
|
|
bUpdate = true;
|
|
}
|
|
|
|
if(bUpdate)
|
|
PostMessage(Application->MainFormHandle, UM_STATE_UPDATE, STATE_BALANCE, 0);
|
|
}
|
|
|
|
PostMessage(Application->MainFormHandle, UM_STATE_UPDATE, STATE_AMOUNT, 0);
|
|
}
|
|
}
|
|
else{
|
|
if(g_bGameOn && g_aGames.bFloat && g_aGames.iFloatGame==iGame){ //游台取消下注标志,以免阻塞下注
|
|
g_aGames.SetSwitchable(true, 0); //非强制换台
|
|
PostMessage(Application->MainFormHandle, UM_FLOAT_BET, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGame::Shuffle()
|
|
{
|
|
ClearResults();
|
|
|
|
bBreak = false;
|
|
|
|
if(bReset)
|
|
ResetBet();
|
|
else{
|
|
if(g_settings.bInitBetByGame){ //新局重置打法
|
|
iBet = iBetSeq = 0;
|
|
aBets.clear();
|
|
}
|
|
if(g_settings.bInitChipByGame){ //新局重置注码
|
|
nChip = iChipSeq = 0;
|
|
}
|
|
|
|
iState = ST_INIT;
|
|
}
|
|
|
|
if(g_settings.bInitProfitByGame && profit!=0 //新局重置赢利
|
|
|| g_settings.bTableStopWin && profit>=g_settings.nTableStopWin //止赢重置
|
|
|| g_settings.bTableStopLos && profit<=-g_settings.nTableStopLos){ //止损重置
|
|
profit = 0;
|
|
PostMessage(hTable, UM_TAB_UPDATE, UPDATE_RESET, 0);
|
|
}
|
|
|
|
if(hTable){
|
|
PostMessage(hTable, UM_TAB_UPDATE, UPDATE_ROAD, 0);
|
|
PostMessage(hTable, UM_LOG_UPDATE, iState, 0);
|
|
}
|
|
|
|
if(g_bGameOn && g_aGames.bFloat && g_aGames.iFloatGame==iGame
|
|
&& ((g_settings.iFloatMode & 2) //洗牌换台
|
|
|| (g_settings.iFloatMode & 1) && aBets.empty())){ //连注完换台被重置
|
|
aBets.clear();
|
|
g_aGames.SetSwitchable(true, iGame);
|
|
PostMessage(Application->MainFormHandle, UM_FLOAT_BET, 0, 0);
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
int __fastcall TGame::ParseCard(int c)
|
|
{
|
|
if(!c) return -1;
|
|
|
|
int n = c & 15;
|
|
if( n>=10 ) n = 0;
|
|
return n;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGame::BuildRoadmap(char wt)
|
|
{
|
|
//大路
|
|
int size0 = aRoad[0].size();
|
|
if(wt!=3){
|
|
if(lastRoad[0]!=wt){ aRoad[0].push_back(1); size0++;}
|
|
else aRoad[0].back()++;
|
|
}
|
|
|
|
aMap[0].DrawMap(wt, lastRoad[0]);
|
|
|
|
if(wt!=3)
|
|
lastRoad[0] = wt;
|
|
else
|
|
return;
|
|
|
|
//下三路
|
|
int rc[5];
|
|
rc[0] = aRoad[0].back(); //最后1列个数
|
|
for(int i=1; i<5; i++)
|
|
rc[i] = size0>i ? aRoad[0][size0-i-1] : 0;
|
|
|
|
for(int i=1; i<4; i++){
|
|
if(!rc[i] || rc[0]==1 && !rc[i+1]) return;
|
|
|
|
char cl = rc[0]==1 ? (rc[1]==rc[i+1] ? 1 : 2) //齐脚跳画红、突脚跳画蓝
|
|
: (rc[0]<=rc[i] || rc[0]>=rc[i]+2 ? 1 : 2); //有对画红、无对画蓝、突脚连画红
|
|
if(lastRoad[i]!=cl) aRoad[i].push_back(1), size0++;
|
|
else aRoad[i].back()++;
|
|
aMap[i].DrawMap(cl, lastRoad[i]);
|
|
lastRoad[i] = cl;
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
TBetLog* __fastcall TGame::NewBetLog()
|
|
{
|
|
TBetLog* pLog = new TBetLog;
|
|
pLog->ts = DateTimeToUnix(Now(), false);
|
|
strcpy(pLog->tno, ((AnsiString)vid).c_str());
|
|
return pLog;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGame::ManualBetOn(int chips[])
|
|
{
|
|
TManBet mb;
|
|
memcpy(mb.chips, chips, sizeof(mb.chips));
|
|
aManBets.push_back(mb);
|
|
|
|
PostMessage(Application->MainFormHandle, UM_SETBET, iGame, 0);
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGame::ManualBetOff()
|
|
{
|
|
for(int i=aManBets.size()-1; i>=0; i--){
|
|
TManBet& mb = aManBets[i];
|
|
if(mb.state!=ST_BETTED){
|
|
aManBets.erase(aManBets.begin()+i);
|
|
}
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGame::ResetIP()
|
|
{
|
|
if(bIndPolicy){
|
|
bIndPolicy = false;
|
|
nChipMul = iRoad = iBetPolicy = iChipPolicy = -1;
|
|
|
|
if(hTable)
|
|
PostMessage(hTable, UM_TAB_UPDATE, UPDATE_IP, 0);
|
|
|
|
// g_aIPGames.DelGame(this);
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//TRoadmap
|
|
TRoadmap::TRoadmap()
|
|
{
|
|
Clear();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TRoadmap::Clear()
|
|
{
|
|
for(int i=0; i<aCols.size(); i++)
|
|
delete aCols[i];
|
|
aCols.clear();
|
|
|
|
iRoot = iRow = iCol = -1;
|
|
bBend = false;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TRoadmap::CheckColumn()
|
|
{
|
|
if(iCol==aCols.size()){
|
|
char* col = new char[6];
|
|
memset(col, 0, 6);
|
|
aCols.push_back(col);
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TRoadmap::DrawMap(char curr, char last)
|
|
{
|
|
bool bCheck = false;
|
|
if(curr==3){
|
|
if(iRoot<0){
|
|
iRoot = iCol = iRow = 0;
|
|
curr = 0x04;
|
|
bCheck = true;
|
|
}
|
|
else
|
|
curr = aCols[iCol][iRow] + 0x04;
|
|
}
|
|
else if(!last && iRoot>=0){ //前面只有和
|
|
curr += aCols[iCol][iRow];
|
|
}
|
|
else if(curr!=last){ //新列
|
|
++iRoot;
|
|
if(iCol<iRoot)
|
|
bCheck = true;
|
|
|
|
iCol = iRoot;
|
|
iRow = 0;
|
|
bBend = false;
|
|
}
|
|
else{
|
|
if(bBend){ //继续横向绘制
|
|
++iCol;
|
|
bCheck = true;
|
|
}
|
|
else{
|
|
if(iRow==5 || aCols[iCol][iRow+1]){ //转为横向绘制
|
|
++iCol;
|
|
bBend = true;
|
|
bCheck = true;
|
|
}
|
|
else
|
|
++iRow;
|
|
}
|
|
}
|
|
|
|
if(bCheck)
|
|
CheckColumn();
|
|
|
|
aCols[iCol][iRow] = curr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//TGameArray
|
|
TGameArray::TGameArray()
|
|
{
|
|
bFloat = iFloatGame = iChipSeq = runTime = 0;
|
|
fCurrProfitPeak = -1E20;
|
|
bSwitchable = true;
|
|
memset(seqCount, 0, sizeof(seqCount));
|
|
memset(nBetted, 0, sizeof(nBetted));
|
|
|
|
pRankChip = NULL;
|
|
pSema = new CSema("GameArray", 1);
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
TGameArray::~TGameArray()
|
|
{
|
|
ClearAllGames();
|
|
ClearRankChip();
|
|
delete pSema;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGameArray::ClearAllGames()
|
|
{
|
|
if(!empty()){
|
|
int s = size();
|
|
for( int i=0; i<s; i++ ){
|
|
delete at(i);
|
|
}
|
|
clear();
|
|
}
|
|
|
|
memset(nBetted, 0, sizeof(nBetted));
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TGameArray::ClearRankChip()
|
|
{
|
|
CMutexLock mutex(pSema);
|
|
|
|
if(pRankChip){
|
|
delete pRankChip;
|
|
pRankChip = NULL;
|
|
}
|
|
|
|
iChipSeq = 0;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
TRankChip* __fastcall TGameArray::GetRankChip(int type)
|
|
{
|
|
CMutexLock mutex(pSema);
|
|
|
|
if(pRankChip && !pRankChip->IsTypeOf(type)){
|
|
delete pRankChip;
|
|
pRankChip = NULL;
|
|
}
|
|
|
|
if(!pRankChip){
|
|
pRankChip = type==KIND_CHIP_HAN ? (TRankChip*)new TTierChip
|
|
: type==KIND_CHIP_LEV ? (TRankChip*)new TLevelChip(true)
|
|
: type==KIND_CHIP_WLD ? (TRankChip*)new TWLDiffChip(true)
|
|
: (TRankChip*)new TComboChip(true);
|
|
}
|
|
|
|
return pRankChip;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TGameArray::Reset()
|
|
{
|
|
int s = size();
|
|
for( int i=0; i<s; i++ ){
|
|
at(i)->Reset();
|
|
}
|
|
|
|
betData.Reset();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGameArray::GameOn()
|
|
{
|
|
if(g_settings.bInitCurProfitByStart)//重置当期赢利
|
|
fCurrProfitPeak = betData.profits[3] = betData.profits[6] = betData.profits[7] = 0;
|
|
else if(fCurrProfitPeak < betData.profits[3]) //重置当期赢利峰值
|
|
fCurrProfitPeak = betData.profits[3];
|
|
|
|
if(bFloat = g_settings.iFloatMode>0){
|
|
bSwitchable = true;
|
|
iChipSeq = iFloatGame = 0;
|
|
memset(seqCount, 0, sizeof(seqCount));
|
|
|
|
TChipPolicy* pCP = (TChipPolicy*)g_aChipPolicies[g_iChipPolicy];
|
|
if(pCP->kind>=KIND_CHIP_HAN && pCP->kind<=KIND_CHIP_WLD){
|
|
GetRankChip(pCP->kind)->SetPolicy(pCP);
|
|
|
|
if(g_settings.bInitBetChipByStart)
|
|
pRankChip->Reset();
|
|
}
|
|
}
|
|
else if(g_settings.bInitBetChipByStart){
|
|
ClearRankChip();
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGameArray::GameOff()
|
|
{
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGameArray::AllBetOff()
|
|
{
|
|
int s = size();
|
|
for( int i=0; i<s; i++ ){
|
|
TGame* pG = at(i);
|
|
if(pG->bRun && !pG->bIndPolicy)
|
|
pG->AutoBetOff();
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGameArray::ResetRankSeq()
|
|
{
|
|
int s = size();
|
|
for( int i=0; i<s; i++ ){
|
|
TGame* pG = at(i);
|
|
if(pG->bRun && !pG->bIndPolicy)
|
|
pG->iChipSeq &= 0xFFFFF000;
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGameArray::ResetRankChip()
|
|
{
|
|
iChipSeq = 0;
|
|
|
|
if(pRankChip){
|
|
pRankChip->Reset();
|
|
|
|
if(!bFloat)
|
|
ResetRankSeq();
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGameArray::ResetFloat()
|
|
{
|
|
bFloat = g_settings.iFloatMode>0;
|
|
iChipSeq = iFloatGame = 0;
|
|
bSwitchable = true;
|
|
memset(seqCount, 0, sizeof(seqCount));
|
|
|
|
if(pRankChip)
|
|
pRankChip->Reset();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGameArray::SetSwitchable(bool bS, int iG)
|
|
{
|
|
CMutexLock mutex(pSema);
|
|
|
|
bSwitchable = bS;
|
|
iFloatGame = iG;
|
|
|
|
//检查是否仅一台在运行
|
|
if(bS && iG){
|
|
int nRun = 0;
|
|
for(int i=0; i<size(); i++){
|
|
if(!at(i)->bIndPolicy && at(i)->bRun){
|
|
nRun++;
|
|
if(nRun>=2)
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(nRun<2) //只有一台,则允许下注
|
|
iFloatGame = 0;
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
bool __fastcall TGameArray::CanFloatBet(int iG)
|
|
{
|
|
CMutexLock mutex(pSema);
|
|
|
|
return bSwitchable && iFloatGame!=iG //可换台非强制
|
|
|| !bSwitchable && iFloatGame==iG; //不可换台当前台
|
|
};
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGameArray::Init(String sRooms)
|
|
{
|
|
ClearAllGames();
|
|
|
|
TStringDynArray arr = SplitString( sRooms, ";" );
|
|
|
|
for( int i=0; i<arr.Length; i++ ){
|
|
if(!arr[i].Length()) continue;
|
|
|
|
TStringDynArray subs = SplitString( arr[i], "," );
|
|
|
|
int iG = Vid2Gid(subs[0]);
|
|
if( iG>0 ){
|
|
TGame* pG = NULL;
|
|
int ind = FindGame(iG, pG );
|
|
if( !pG ){
|
|
pG = NewGame(iG, subs[g_iPlatform==PF_PA ? 0 : 1], ind);
|
|
|
|
pG->gmcode = subs[2];
|
|
pG->gmstatus = subs[3].ToInt(); //先设为结算,避免重复
|
|
if(pG->gmstatus==1)
|
|
pG->gmstatus = 2;
|
|
// else if(pG->gmstatus==2)
|
|
// pG->gmstatus = 0;
|
|
|
|
for(int i=1; i<=subs[4].Length(); i++){
|
|
int wt = subs[4][i]-'0';
|
|
if(wt==0) wt = 3;
|
|
pG->aRes.push_back(wt);
|
|
pG->winCount[wt-1]++;
|
|
pG->BuildRoadmap(wt);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
TGame* __fastcall TGameArray::NewGame(int iG, String vid, int ind)
|
|
{
|
|
CMutexLock mutex(pSema);
|
|
|
|
TGame* pGame = new TGame(iG);
|
|
pGame->vid = vid;
|
|
|
|
if(g_aIPGames.iPlatform!=g_iPlatform){
|
|
g_aIPGames.ClearAll();
|
|
}
|
|
else{
|
|
TIPGame* pIG = NULL;
|
|
g_aIPGames.FindGame(vid, pIG);
|
|
|
|
if(pIG){
|
|
pGame->bIndPolicy = true;
|
|
pGame->iBetPolicy = pIG->iBetPolicy;
|
|
pGame->iChipPolicy = pIG->iChipPolicy;
|
|
pGame->nChipMul = pIG->nChipMul;
|
|
pGame->iRoad = ((TBetPolicy*)g_aBetPolicies[pIG->iBetPolicy])->road;
|
|
pIG->pGame = pGame;
|
|
}
|
|
}
|
|
|
|
insert( begin()+ind, pGame );
|
|
|
|
return pGame;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TGameArray::SetCountDown(String s)
|
|
{
|
|
TStringDynArray arr = SplitString( s, ";" );
|
|
|
|
for( int i=0; i<arr.Length; i++ ){
|
|
if(arr[i].IsEmpty()) continue;
|
|
|
|
TStringDynArray subs = SplitString( arr[i], "," );
|
|
|
|
int iG = subs[0].ToInt();
|
|
int cd = subs[1].ToInt();
|
|
if( iG>0 && cd>=0 ){
|
|
TGame* pG = NULL;
|
|
int ind = FindGame(iG, pG );
|
|
if(pG){
|
|
int st = subs[2].ToInt();
|
|
if(pG->countdown<st){
|
|
pG->countdown = st;
|
|
|
|
if(pG->gmstatus==1){
|
|
pG->timeout = cd ? cd + 2 : 0;
|
|
if(pG->hTable) PostMessage(pG->hTable, UM_TAB_UPDATE, UPDATE_TIME, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
TGame* __fastcall TGameArray::GetGame(int iG)
|
|
{
|
|
TGame * pG = NULL;
|
|
|
|
FindGame( iG, pG );
|
|
|
|
return pG;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
int __fastcall TGameArray::FindGame(int iG, TGame*& pGame)
|
|
{
|
|
CMutexLock mutex(pSema);
|
|
|
|
int middle, front=0, rear=size()-1;
|
|
int index = -1;
|
|
|
|
while( front<=rear ){
|
|
if( at(front)->iGame == iG ){
|
|
index = front;
|
|
pGame = at(front);
|
|
break;
|
|
}
|
|
if( at(rear)->iGame == iG ){
|
|
index = rear;
|
|
pGame = at(rear);
|
|
break;
|
|
}
|
|
|
|
middle = (front+rear)/2;
|
|
if( at(middle)->iGame == iG ){
|
|
index = middle;
|
|
pGame = at(middle);
|
|
break;
|
|
}
|
|
else if( at(middle)->iGame < iG )
|
|
front=middle+1;
|
|
else
|
|
rear=middle-1;
|
|
}
|
|
|
|
if( front>rear )
|
|
index = front;
|
|
|
|
return index;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//TIPGameArray
|
|
TIPGameArray::~TIPGameArray()
|
|
{
|
|
ClearAll();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TIPGameArray::ClearAll()
|
|
{
|
|
if(!empty()){
|
|
int s = size();
|
|
for( int i=0; i<s; i++ ){
|
|
delete at(i);
|
|
}
|
|
clear();
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
int __fastcall TIPGameArray::FindGame(String vid, TIPGame*& pIG)
|
|
{
|
|
int middle, front=0, rear=size()-1;
|
|
int index = -1;
|
|
|
|
while( front<=rear ){
|
|
if( at(front)->vid == vid ){
|
|
index = front;
|
|
pIG = at(front);
|
|
break;
|
|
}
|
|
if( at(rear)->vid == vid ){
|
|
index = rear;
|
|
pIG = at(rear);
|
|
break;
|
|
}
|
|
|
|
middle = (front+rear)/2;
|
|
if( at(middle)->vid == vid ){
|
|
index = middle;
|
|
pIG = at(middle);
|
|
break;
|
|
}
|
|
else if( at(middle)->vid < vid )
|
|
front=middle+1;
|
|
else
|
|
rear=middle-1;
|
|
}
|
|
|
|
if( front>rear )
|
|
index = front;
|
|
|
|
return index;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TIPGameArray::AddGame(TGame* pG)
|
|
{
|
|
if(iPlatform!=g_iPlatform)
|
|
iPlatform = g_iPlatform;
|
|
|
|
TIPGame* pIG = NULL;
|
|
int ind = FindGame(pG->vid, pIG);
|
|
if(!pIG){
|
|
insert(begin()+ind, new TIPGame(pG));
|
|
}
|
|
else{
|
|
pIG->iBetPolicy = pG->iBetPolicy;
|
|
pIG->iChipPolicy = pG->iChipPolicy;
|
|
pIG->nChipMul = pG->nChipMul;
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TIPGameArray::DelGame(TGame* pG)
|
|
{
|
|
TIPGame* pIG = NULL;
|
|
int ind = FindGame(pG->vid, pIG);
|
|
if(pIG){
|
|
delete pIG;
|
|
erase(begin()+ind);
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TIPGameArray::AddIPGame(String v, int b, int c, int m)
|
|
{
|
|
if(iPlatform!=g_iPlatform)
|
|
iPlatform = g_iPlatform;
|
|
|
|
TIPGame* pIG = NULL;
|
|
int ind = FindGame(v, pIG);
|
|
if(!pIG){
|
|
insert(begin()+ind, new TIPGame(v, b, c, m));
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|