诸暨麻将添加redis
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 
 
 

433 行
15 KiB

  1. #ifndef TABLE_FRAME_SINK_HEAD_FILE_DSC
  2. #define TABLE_FRAME_SINK_HEAD_FILE_DSC
  3. #pragma once
  4. #include "Stdafx.h"
  5. #include "GameLogic_dcs.h"
  6. #include "ReplayRecordManager.h"
  7. #include "data.h"
  8. #include "../俱乐部/Source/MessageDef/Pb_RecordPacket.pb.h"
  9. struct CanDcsSt{
  10. BYTE MagicCard;
  11. BYTE MagicCardNext;
  12. BYTE nTai;
  13. bool bDuCanHu;
  14. };
  15. struct CanMadeMagic{
  16. BYTE firstIndex;
  17. BYTE SecIndex;
  18. CanMadeMagic(){
  19. firstIndex = MAX_INDEX;
  20. SecIndex = MAX_INDEX;
  21. }
  22. };
  23. struct CaiCards{
  24. BYTE firstCardIndex;
  25. BYTE secCardIndex;
  26. };
  27. #define DingDuGao2 0x0
  28. #define DingRightGao2 0x40
  29. #define DingLeftGao2 0x80
  30. #define DingLeftAndRightGao2 0xC0
  31. #define DingMagicMinTai 3
  32. #define TowMjNullseat 1
  33. //游戏桌子类
  34. class CTableFrameSink_dcs : public ITableFrameSink, public ITableUserAction
  35. {
  36. enum MagicCount
  37. {
  38. MagicZero = 0,
  39. MagicOne,
  40. MagicTwo,
  41. };
  42. //游戏变量
  43. public:
  44. UINT32 m_startTime; //游戏开始时间
  45. BYTE LianXuHuPai[GAME_PLAYER]; //连续胡牌次数,用来记录老庄的
  46. LONG m_lSiceCount; //骰子点数
  47. WORD m_wBankerUser; //庄家用户,庄家用户是老庄高8位为1,否则就是平常的
  48. WORD m_wNextBankerUser; //下一个庄家
  49. int m_lGameScore[GAME_PLAYER]; //单局游戏得分
  50. int m_lGameTatolScore[GAME_PLAYER]; //单轮积分计算 拥有计分
  51. BYTE m_HuPai[GAME_PLAYER]; //玩家胡牌次数
  52. int m_HuPaiLiuShui[16*GAME_PLAYER]; //流水详情
  53. BYTE m_cbCardIndex[GAME_PLAYER][MAX_INDEX]; //用户扑克
  54. BYTE m_bTrustee[GAME_PLAYER]; //是否托管
  55. BYTE m_bReading[GAME_PLAYER]; //是否准备
  56. BYTE m_cbMagicFirstData; //癞子皮(两个财神牌)
  57. BYTE m_cbMagicSecondData; //癞子
  58. BYTE m_cbQiangGangCardData[GAME_PLAYER]; //抢杠的牌
  59. bool m_bPlayStatus[GAME_PLAYER]; //玩家状态
  60. std::list<DWORD> m_offlineUsers; //掉线的玩家
  61. //BYTE m_OutLastLaiZiData; //最后杠牌数据
  62. BYTE m_PaiQuan[GAME_PLAYER]; //1表示 当前不是自己的牌权,但是已经听了
  63. BYTE m_TabbOutCardCout[GAME_PLAYER]; //可以打出的牌就听牌的个数 255表示 当前不是自己的牌权,但是已经听了
  64. BYTE m_TabbOutCardData[GAME_PLAYER][MAX_COUNT]; //具体打哪几张牌 胡牌个数255 表示可以胡任意一个牌。
  65. BYTE m_TabbTingCardCount[GAME_PLAYER][MAX_COUNT]; //相对应打出牌可听牌个数,索引表示第几张,值是对应对应的听牌个数
  66. WORD m_TabbTingCardData[GAME_PLAYER][MAX_COUNT][MAX_TING]; //具体听牌数据,一维索引表示打出牌的第几个,二维索引表示听牌的第几个,值表示牌数据
  67. // m_TabbTingCardData[wChairID][0][m_cbTingParCount - 1]
  68. public:
  69. CMD_S_GameConfig m_gameConfig; //游戏配置
  70. bool m_isCanOutCard; //是否可以出牌
  71. bool m_bDelete; //是否解散房间
  72. bool bIsHuang; //是否黄庄
  73. //出牌信息
  74. private:
  75. WORD m_wOutCardUser; //出牌用户
  76. BYTE m_cbOutCardData; //出牌扑克
  77. BYTE m_cbOutCardCount; //出牌数目
  78. BYTE m_cbDiscardCount[GAME_PLAYER]; //丢弃数目
  79. BYTE m_cbDiscardCard[GAME_PLAYER][40]; //丢弃记录
  80. //记忆库记录的是每一次牌权到另一次牌权牌 就是从抓牌到下一次抓牌的记忆库
  81. BYTE m_cbLastDisCardData[GAME_PLAYER][MAX_COUNT];//每个玩家得记忆库,用于判断是否可以碰不
  82. BYTE m_cbLastDisCount[GAME_PLAYER]; //每个玩家记忆库得个数
  83. //发牌信息
  84. private:
  85. BYTE m_cbSendCardData; //发牌扑克
  86. BYTE m_cbSendCardCount; //发牌数目
  87. BYTE m_cbLeftCardCount; //剩余数目
  88. BYTE m_cbRepertoryCard[MAX_REPERTORY_ZJ]; //库存扑克
  89. BYTE m_cbShiJiLeftCardCount; //实际剩余数目
  90. BYTE m_cbGangCount; //记录杠的次数
  91. byte m_cbTotalCardCount; //玩法总牌数
  92. //运行变量
  93. private:
  94. WORD m_wResumeUser; //还原用户(下一个用户?)
  95. WORD m_wCurrentUser; //当前用户
  96. WORD m_wProvideUser; //供应用户
  97. BYTE m_cbProvideCard; //供应扑克
  98. //状态变量
  99. private:
  100. //bool m_bGangStatus; //杠上开花状态位
  101. bool m_bUsersGangStatus[GAME_PLAYER];//杠上开花状态位
  102. int m_bGangOption; // 用操作状态标示 是补杠 暗杠 还是明杠
  103. int m_GangPrivedUserID; //保存用户杠牌时 自己的补杠,暗杠,还是别人点的明杠
  104. bool m_bQiangGang; //抢杠胡标示位,当有补杠,且有胡为true
  105. //用户状态
  106. private:
  107. bool m_bResponse[GAME_PLAYER]; //响应标志
  108. INT m_cbUserAction[GAME_PLAYER]; //用户动作
  109. BYTE m_cbOperateCard[GAME_PLAYER]; //操作扑克
  110. BYTE m_cbOperateCaiCard[GAME_PLAYER][GAME_PLAYER];//财神牌操作扑克
  111. INT m_cbPerformAction[GAME_PLAYER]; //执行动作
  112. //组合扑克
  113. private:
  114. BYTE m_cbWeaveItemCount[GAME_PLAYER]; //组合数目
  115. tagWeaveItem m_WeaveItemArray[GAME_PLAYER][MAX_WEAVE];//组合扑克
  116. //组件变量
  117. private:
  118. CGameLogic_dcs m_GameLogic; //游戏逻辑
  119. ITableFrame * m_pITableFrame; //框架接口
  120. const tagGameServiceOption * m_pGameServiceOption; //配置参数
  121. bool m_bReplayRecordStart; //是否开始录像
  122. std::vector<RecordPacket::pb_GameRecordPacket> m_UserReplayRecord; //对四个位置用户的数据的记录,用于回放。
  123. //bool m_bReduceBean; //是否已扣房卡(游戏豆)
  124. //LONGLONG m_lUserTmpScore[GAME_PLAYER];
  125. CString mTableDatastrPath;//tabledata 所在路径
  126. BOOL mBWriteTableData;
  127. //游戏人数
  128. byte mPlayGameUserCount;
  129. BOOL m_bTwoPlayerFlag;
  130. //桌子ID int
  131. int mGameTableId;
  132. //函数定义
  133. public:
  134. //构造函数
  135. CTableFrameSink_dcs();
  136. //析构函数
  137. virtual ~CTableFrameSink_dcs();
  138. //void ReduceBean();
  139. //bool IsCanOutCard(); //是否可以出牌
  140. //基础接口
  141. public:
  142. //释放对象
  143. virtual VOID Release() { delete this; }
  144. //接口查询
  145. virtual void * QueryInterface(const IID & Guid, DWORD dwQueryVer);
  146. //管理接口
  147. public:
  148. //初始化
  149. virtual bool Initialization(IUnknownEx * pIUnknownEx);
  150. //复位桌子
  151. virtual VOID RepositionSink();
  152. //查询接口
  153. public:
  154. virtual void DeletePrivateTable(bool bSendState = false);
  155. virtual bool ConcludeGame(BYTE cbGameStatus, bool bSendState = false)
  156. {
  157. //结束记录回放数据
  158. auto dataPair = RepayRecordEnd();
  159. //结束游戏
  160. m_pITableFrame->ConcludeGame(cbGameStatus, bSendState);
  161. return true;
  162. }
  163. //查询限额
  164. virtual SCORE QueryConsumeQuota(IServerUserItem * pIServerUserItem){ return 0; };
  165. //最少积分
  166. virtual SCORE QueryLessEnterScore(WORD wChairID, IServerUserItem * pIServerUserItem){ return 0; };
  167. //查询是否扣服务费
  168. virtual bool QueryBuckleServiceCharge(WORD wChairID){return true;}
  169. //查询总得分
  170. virtual int QueryTatolScore(WORD wChairID){ if (wChairID >= GAME_PLAYER || wChairID<0) ASSERT(false); return m_lGameTatolScore[wChairID]; }
  171. //查询癞子数
  172. virtual int QueryTatolLaiGang(WORD wChairID){ if (wChairID >= GAME_PLAYER || wChairID < 0) ASSERT(false); return 0; }
  173. //查询是否使用临时积分
  174. virtual bool QueryUseTemporaryScore() {
  175. return (0!=lstrlen(m_gameConfig.sPrivateTableID)); //私有房间私用临时积分
  176. }
  177. //比赛接口
  178. public:
  179. //设置基数
  180. virtual void SetGameBaseScore(LONG lBaseScore){};
  181. //把房间的基本信息记录到类
  182. virtual void SetGameConfig(VOID * pDataBuffer, WORD wDataSize, std::wstring sPrivateRoomId);
  183. //游戏事件
  184. public:
  185. bool RepayRecordStart();
  186. bool RepayRecordEnd();
  187. bool RepayRecord(WORD wChairID, WORD wSubCmdId, void* pData, WORD wSize);
  188. // bool CheckGameConclude();
  189. public:
  190. //游戏开始
  191. virtual bool OnEventGameStart();
  192. //游戏结束
  193. virtual bool OnEventGameConclude(WORD wChairID, IServerUserItem * pIServerUserItem, BYTE cbReason, bool bSendState = false);
  194. //发送场景
  195. virtual bool OnEventSendGameScene(WORD wChiarID, IServerUserItem * pIServerUserItem, BYTE cbGameStatus, bool bSendSecret);
  196. //事件接口
  197. public:
  198. //定时器事件
  199. virtual bool OnTimerMessage(DWORD wTimerID, WPARAM wBindParam);
  200. //数据事件
  201. virtual bool OnDataBaseMessage(WORD wRequestID, VOID * pData, WORD wDataSize) { return false; }
  202. //积分事件
  203. virtual bool OnUserScroeNotify(WORD wChairID, IServerUserItem * pIServerUserItem, BYTE cbReason) { return false; }
  204. //网络接口
  205. public:
  206. //游戏消息处理
  207. virtual bool OnGameMessage(WORD wSubCmdID, VOID * pDataBuffer, WORD wDataSize, IServerUserItem * pIServerUserItem);
  208. //框架消息处理
  209. virtual bool OnFrameMessage(WORD wSubCmdID, VOID * pDataBuffer, WORD wDataSize, IServerUserItem * pIServerUserItem);
  210. //用户事件
  211. public:
  212. //用户断线
  213. virtual bool OnActionUserOffLine(WORD wChairID,IServerUserItem * pIServerUserItem) { return true; }
  214. //用户重入 需要处理重新发送指令
  215. virtual bool OnActionUserConnect(WORD wChairID, IServerUserItem * pIServerUserItem);
  216. //用户坐下
  217. virtual bool OnActionUserSitDown(WORD wChairID,IServerUserItem * pIServerUserItem, bool bLookonUser);
  218. //用户起立
  219. virtual bool OnActionUserStandUp(WORD wChairID,IServerUserItem * pIServerUserItem, bool bLookonUser);
  220. //用户同意
  221. virtual bool OnActionUserOnReady(WORD wChairID,IServerUserItem * pIServerUserItem, void * pData, WORD wDataSize) { return true; }
  222. //游戏中途旁观进入
  223. virtual bool PerformLookonLogin(IServerUserItem * pIServerUserItem);
  224. //游戏事件
  225. protected:
  226. //用户出牌
  227. bool OnUserOutCard(WORD wChairID, BYTE cbCardData);
  228. //用户操作
  229. bool OnUserOperateCard(WORD wChairID, int cbOperateCode, BYTE cbOperateCard, BYTE cbCaiShenCard[4]);
  230. //辅助函数
  231. protected:
  232. //发送操作
  233. bool SendOperateNotify();
  234. //派发扑克,默认false正常起牌,true末尾棋牌
  235. bool DispatchCardData(WORD wCurrentUser,bool bTail=false);
  236. //响应判断
  237. bool EstimateUserRespond(WORD wCenterUser, BYTE cbCenterCard, enEstimatKind EstimatKind);
  238. //返回胡牌牌型
  239. int bHuPaiType(CChiHuRight &CChiHuRight);
  240. //优先级判断
  241. bool OperatorPriority(WORD TmpwProvideUser, WORD &wOptUser, int &cbTargetAction);
  242. //广播操作扣手牌牌
  243. bool DeleteCaiShenCard(WORD wChairID, BYTE cbTargetCaiCard[4], int cbTargetAction, BYTE cbTargetCard);
  244. //自主操作扣财神牌
  245. bool DeleteCard(WORD wChairID, BYTE cbTargetCaiCard[4], int cbOperateCode, BYTE cbOperateCard);
  246. //获取剩余牌数
  247. BYTE RemainNum(WORD wChairId, const BYTE m_cbCard,BYTE cbOutCardIndex);
  248. //听牌数据函数
  249. bool TingCard(WORD wChairID);
  250. //打出牌时固定听牌数据
  251. bool OutTingCard(WORD wChairID, BYTE cardIndex);
  252. //发送听牌协议
  253. void HttpTingCard(WORD wChairID);
  254. //操作协议
  255. void HttpOperateResult(WORD wChairID, BYTE cbCaiShenCard[4], int cbOperateCode, BYTE cbOperateCard, int cbActionMask, WORD cbActionCard[6]);
  256. //////////////////////////////////////////////////////////////////////////
  257. //ZORO
  258. public:
  259. BYTE GetNextMagicCardData(BYTE cbMagicCardFirstIndex);
  260. BYTE GetLastMagicCardData(BYTE cbMagicCardFirstIndex);//获取财神的上一张牌
  261. int mMaxTaiNum;
  262. //包麻将相关
  263. //1 拥有包麻将权限的玩家ID
  264. //2 包牌类型 无财 单财 双财
  265. //3 财神index
  266. //4 包家 要几台
  267. public:
  268. void SetMagicType(int Type){
  269. mMagicType = Type;
  270. }
  271. int mMagicType;
  272. //BYTE mMjType; //0翻财神 1包麻将 2 3 4 后续扩展 血流之类的。
  273. BYTE mBaoTaiNum[GAME_PLAYER];
  274. BYTE mBaoUserInfo[GAME_PLAYER];
  275. int nCountOptBao;
  276. int mbStartBaoTai ; //0未开始 1 开始 2结束 3财神结束
  277. BYTE mCurrentBaoUser;//当前包台玩家
  278. BYTE mCurrentMinBaoTai;//当前最小包台
  279. //BaoEnum mMaxBaoNum;//保存前端传递过来的原始值-选包时
  280. bool mBaoCacleDZFB;
  281. //////////////////////////////////////////////////////////////////////////
  282. //计分 诸暨
  283. enum _WinWay_
  284. {
  285. Win_FangPao = 0,
  286. Win_ZiMo,
  287. win_DiHu,
  288. win_qianggang,
  289. };
  290. //胡牌 计算分数
  291. /*
  292. *WinChairID 胡牌玩家ID
  293. *nTai 胡牌台数
  294. *WinWay 胡牌方式
  295. *provideUserID 如果是放炮,谁放的
  296. *
  297. */
  298. void CaculationScore(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CChiHuRight chr, CMD_S_GangScore& cmd_Score);
  299. void FanMagicCaculation(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CChiHuRight chr, CMD_S_GangScore& cmd_Score);
  300. public:
  301. //void BaoMjCalculation(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CMD_S_GangScore& cmd_Score);
  302. void WinFanMagic_FangPao_Score(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CChiHuRight chr, CMD_S_GangScore& cmd_Score);
  303. void WinQiangGang_Score(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CChiHuRight chr, CMD_S_GangScore& cmd_Score);
  304. void WinFanMagic_ZiMo_Score(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CMD_S_GangScore& cmd_Score);
  305. void WinFanMagic_DiHu_Score(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CMD_S_GangScore& cmd_Score);
  306. // void WinBaoMagic_FangPao_Score(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CMD_S_GangScore& cmd_Score);
  307. // void WinBaoMagic_ZiMo_Score(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CMD_S_GangScore& cmd_Score);
  308. // void WinBaoMagic_DiHu_Score(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CMD_S_GangScore& cmd_Score);
  309. //void CalcDongZFB(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID);
  310. int mZFBBianScore[GAME_PLAYER];
  311. //////////////////////////////////////////////////////////////////////////
  312. //选择包
  313. // int mUserOptBaoTai[GAME_PLAYER];
  314. //bool SelectBaoTaiNum(WORD wChairID, BYTE nMagicTai);
  315. //bool SelectBaoMagic(WORD wChairID, BYTE cbMagicFirst,BYTE cbMagicSenced);
  316. // bool IsCanReturnResult();
  317. // int FindNextBaoJiaID(int CurrentId);
  318. //bool IsAddTaiNum(int nNextID);
  319. // bool IsNoBaoUser();
  320. // void NoHaveBaoUser();
  321. //////////////////////////////////////////////////////////////////////////
  322. void WritePaiCardData(TCHAR* TableId,int count);
  323. void ReadGameData();
  324. void PrintUsersScore(LPCTSTR strInfo);
  325. // bool mBLastBaoStart;
  326. //
  327. // bool HandleBaoMjZaHu(WORD wChairID, int cbOperateCode, BYTE cbOperateCard, BYTE cbCaiShenCard[4]);
  328. //
  329. // bool mBZaHu;
  330. //////////////////////////////////////////////////////////////////////////
  331. //订财
  332. bool UserDingMagicCard(WORD wChairID);
  333. bool GetOneWeaveItemCards(const tagWeaveItem WeaveItem[], BYTE cbWeaveCount, BYTE * cbCards, INT & CardsCount);
  334. bool CardInCardArray(BYTE cbCard, BYTE* cbCards, int nCount);
  335. bool GetLianXuCards(BYTE* CardsIndex,std::vector<CaiCards> &vCards);
  336. //获取14张手牌(包括落地牌),能够当作财神的牌,以及此牌当财神时胡的 台数
  337. bool GetMagicCardAndTaiNum(BYTE* cardsIndex, WORD wChairID, BYTE cbCenterCard, std::vector<CanDcsSt> &vCards,BOOL FindOneExit=FALSE);
  338. bool GetCanMadeMagicCards(BYTE* cardsIndex, std::vector<CanMadeMagic> &vCards,BYTE currentUserIndex);
  339. byte GetTaiNumFromCards(BYTE* cardsIndex, WORD wChairID, BYTE cbCenterCard, BYTE firstIndex, BYTE secIndex, bool bQiangGang = false);
  340. CMD_S_NOTIFY_QIANGGH mCmd_NotifyQianggh[4];
  341. BOOL IsCanTianhu();
  342. //特殊处理 抢杠胡时,玩家没有对应操作,但其他玩家 断线重连 导致显示的剩余牌不一样的问题。
  343. bool mBCanShowLeft;
  344. int mTempLeftCount;//为断线重连准备,只有当发牌后 断线重连才使用真正的剩余牌。否则 增加剩余牌
  345. BOOL GetCardCanHuWithAll(BYTE cbCard, std::vector<CanDcsSt> &vCards);
  346. BOOL CardInAll(BYTE CbCard, BYTE *pByte, int Count);
  347. //////////////////////////////////////////////////////////////////////////
  348. //保存可以做财神的牌,不可以做的为0 可以做的为4。
  349. //
  350. BYTE mCanDingCaiCardArray[GAME_PLAYER][MAX_INDEX];
  351. //根据所有用户落地派计算可以当财神的牌
  352. void CalculationMagicCards(BYTE CurrentUserIndex);
  353. void EnumAllWeave(BYTE CurrentUserIndex);
  354. };
  355. //////////////////////////////////////////////////////////////////////////
  356. #endif