当前位置:   article > 正文

扑克类游戏斗地主、蜘蛛纸牌源码_开源纸牌小游戏

开源纸牌小游戏

11号,硬着头皮吃水饺,不知道馅是什么肉做的,应该没有三会火腿肠好吧.....

这是移植自网上搜索到的两个扑克类游戏,原游戏是MFC做的,移植到了OpenGL中。两者的渲染方式不同,架构有所改变。总共没花几天时间,如果自己从头写估计至少要用几个月。

扑克类游戏主要是数据结构要列好,算法都是初级的入门算法,繁琐但是并不困难。

继续给游戏添加了联机和自动出牌功能,出牌智商有点弱。

抽象出一些基类PokerGame,PokerPlayer方便派生出多种类型的游戏。斗地主游戏PokerDouDiZhu或其它的出牌类游戏比如‘’红心大战‘’都可以继承自PokerGame类。斗地主玩家基类DouDizhuPlayer也继承自PokerPlayer。

还是原先的小游戏架构分三种类型的玩家: (Player、Robot、Role) 

DouDizhuPlayer             继承自PokerPlayer是斗地主玩家基类,只有被动出牌功能(只响应出牌消息,不主动发送出牌消息给主机和其它玩家)。

DouDizhuPlayerRobot   继承自DouDizhuPlayer是AI玩家类,具有自动出牌功能(主动发送出牌消息)。

DouDizhuPlayerRole     继承自DouDizhuPlayerRobot是实体玩家类,具有自动出牌功能的同时也可以手选出牌。

对于蜘蛛纸牌游戏,结构上和斗地主类出牌的游戏应该算是两种不同的类型了。这个蜘蛛纸牌游戏只加了提示出牌功能,没有做联机和自动出牌。

定义纸牌ID:

  1. //========================================================
  2. // @Date: 2016.05
  3. // @File: SourceDemoClient/Poker/PokerGame.h
  4. // @Brief: PokerGame
  5. // @Author: LouLei
  6. // @Email: twopointfive@163.com
  7. // @Copyright (Crapell) - All Rights Reserved
  8. //========================================================
  9. #if !defined(PokerCard_h__)
  10. #define PokerCard_h__
  11. //扑克牌ID
  12. enum CardID
  13. {
  14. MEIH2=0,
  15. MEIH3,
  16. MEIH4,
  17. MEIH5,
  18. MEIH6,
  19. MEIH7,
  20. MEIH8,
  21. MEIH9,
  22. MEIH10,
  23. MEIHJ,
  24. MEIHQ,
  25. MEIHK,
  26. MEIHA,
  27. FANGK2,
  28. FANGK3,
  29. FANGK4,
  30. FANGK5,
  31. FANGK6,
  32. FANGK7,
  33. FANGK8,
  34. FANGK9,
  35. FANGK10,
  36. FANGKJ,
  37. FANGKQ,
  38. FANGKK,
  39. FANGKA,
  40. HEIT2,
  41. HEIT3,
  42. HEIT4,
  43. HEIT5,
  44. HEIT6,
  45. HEIT7,
  46. HEIT8,
  47. HEIT9,
  48. HEIT10,
  49. HEITJ,
  50. HEITQ,
  51. HEITK,
  52. HEITA,
  53. HONGT2,
  54. HONGT3,
  55. HONGT4,
  56. HONGT5,
  57. HONGT6,
  58. HONGT7,
  59. HONGT8,
  60. HONGT9,
  61. HONGT10,
  62. HONGTJ,
  63. HONGTQ,
  64. HONGTK,
  65. HONGTA,
  66. JokerSmall,
  67. JokerBig,
  68. CardNum
  69. };
  70. //单张牌
  71. class Card
  72. {
  73. public:
  74. Card();
  75. int Color(); //牌的花色
  76. bool bClicked; //是否被左键选中待出牌
  77. int cardValue; //牌面值
  78. CardID cardID;
  79. };
  80. #endif

出牌型游戏基类:

  1. //========================================================
  2. // @Date: 2016.05
  3. // @File: SourceDemoClient/Poker/PokerGame.h
  4. // @Brief: PokerGame
  5. // @Author: LouLei
  6. // @Email: twopointfive@163.com
  7. // @Copyright (Crapell) - All Rights Reserved
  8. //========================================================
  9. #if !defined(PokerGame_h__)
  10. #define PokerGame_h__
  11. #include "Render/Texture.h"
  12. #include "Poker/PokerCard.h"
  13. #include "Rpg/MiniGame.h"
  14. #define MaxPlayerCard 20 //玩家最多持牌数
  15. #define RenderShiftX 20 //牌之间距离
  16. #define RenderShiftY 20
  17. #define RenderLeftRightSpace 10 //牌距离屏幕左右留空
  18. #define RenderUpDownSpace 10 //牌距离屏幕上下留空
  19. #define RenderUpDownDistance 25 //上下第二排牌距离第一排留空
  20. #define RenderClickedAddDistance 20 //点选后牌高出的长度
  21. #define Board2DCen (G_PokerGame->BoardRect2D.GetCen())
  22. //显示座位:不同的客户端看到的不一样(不是每个客户端都是坐北朝南)
  23. enum ChairPostion
  24. {
  25. SP_Down,
  26. SP_Right,
  27. SP_Up,
  28. SP_Left,
  29. };
  30. //网络消息
  31. enum MiniPokerCmd
  32. {
  33. CMD_ShuffleCard, //洗牌
  34. CMD_BeLord , //叫地主
  35. CMD_NotBeLord , //不叫地主
  36. CMD_OutCard , //出牌
  37. CMD_Pass , //
  38. CMD_GameOver , //结束
  39. CMD_Restart , //重新开始
  40. };
  41. const char* PokerCmdToString(int enumeration);
  42. class SoundChannel;
  43. class GuiMovieCtrl;
  44. class PokerGame;
  45. //玩家的数据结构
  46. class PokerPlayer:public MiniPlayer
  47. {
  48. public:
  49. PokerPlayer();
  50. virtual~PokerPlayer();
  51. virtual bool Start();
  52. virtual bool Stop();
  53. virtual void Update();
  54. virtual void Render();
  55. virtual void RecvCard(CardID cardID);
  56. virtual void SortCard(); //整牌
  57. //出牌
  58. virtual void OutCard();
  59. //张数
  60. int CountCard(int value);
  61. //
  62. int MinCard(int temp[], int num);
  63. //分析牌 各value值的张数
  64. void AnalyseCard();
  65. bool ClickCards(int cardValue[],int num); //改变牌状态,标记待出
  66. bool ClickCardsID(int cardID[],int num); //改变牌状态,标记待出
  67. int ClickCard(const vec2& pos);
  68. ChairPostion m_screenPos; //显示座位:上下左右
  69. bool m_workingWithAI;
  70. Card m_cards[MaxPlayerCard];
  71. int m_cardNum;
  72. int m_turn; //统一座位:东西南北
  73. int m_outNum; //出到桌面的牌数
  74. bool m_notOut; //不出牌的标记
  75. int ValueCount[18]; //value值的张数
  76. int m_totalScore; //记录总分
  77. int m_turnScore; //记录这回合得分
  78. int CardY; //south myplayer第一张牌左上角 xy
  79. int CardX;
  80. int m_clickedNum; //点击待出的牌数
  81. bool m_bBaoPai;
  82. PokerGame* m_game;
  83. SoundChannel* m_sound;
  84. GuiMovieCtrl* m_movieCtrl;
  85. };
  86. //准备要出的牌
  87. class ToOutCards
  88. {
  89. public:
  90. ToOutCards();
  91. Card m_cards[MaxPlayerCard];
  92. int m_cardNum;
  93. //张数
  94. int CountCard(int value);
  95. //最小的牌
  96. int MinCard();
  97. };
  98. //游戏状态
  99. enum PokerGameStatus
  100. {
  101. Waiting, //准备
  102. Dealing, //发牌
  103. Preparing,//叫地主中
  104. Playing, //进行中
  105. Resulting,//显示结果
  106. };
  107. //牌的状态
  108. enum CardFlag
  109. {
  110. NotDeal = 0,//未发的牌
  111. InHand, //已发牌未出的牌
  112. BeOut, //已出的牌
  113. };
  114. class PacketBase;
  115. class PokerGame
  116. {
  117. public:
  118. PokerGame();
  119. virtual ~PokerGame();
  120. virtual bool Start();
  121. virtual bool Stop();
  122. virtual bool Render();
  123. virtual bool Update();
  124. virtual bool Free();
  125. virtual bool CheckRoundEnd(); //回合结束判断
  126. virtual void FirstOut(); //游戏开始首次出牌
  127. virtual void StateDealCard(); //发牌
  128. virtual void SignCard(Card *card); //标记牌分值
  129. virtual void NextTurn();
  130. void ShuffleCard(); //洗牌
  131. virtual void OutCard(PokerPlayer*player); //出牌
  132. PokerPlayer* GetTurnPlayer();
  133. //处理游戏网络命令包
  134. virtual int ProcessPacketCmd(PacketBase* packet);
  135. //virtual const char* CmdToString(const char* stream,int len);
  136. PokerGameStatus m_gameStatus;
  137. CardFlag m_cardFlag[CardNum]; //出牌标记
  138. /*CardID*/char m_cardShuffle[CardNum]; //洗牌结果
  139. PokerPlayer* m_players[4];
  140. PokerPlayer* m_myPlayer;
  141. int m_playerNum;
  142. int m_turn; //出牌位置
  143. int m_lastOutTurn; //上次出牌位置
  144. float m_turnTime; //换手时间
  145. int m_dealCardNum;
  146. float m_dealAccumTime;
  147. int CardHeight; //牌长
  148. int CardWidth; //牌宽
  149. bool m_openPoker;
  150. bool m_bHost;
  151. TexturePtr m_texBack;
  152. TexturePtr m_cardTexture[CardNum];
  153. TexturePtr m_cardBackTexture;
  154. TexturePtr m_thinkTexture[4];
  155. TexturePtr m_passTexture[4];
  156. TexturePtr m_passButtonTexture;
  157. };
  158. #endif
  159. //========================================================
  160. // @Date: 2016.05
  161. // @File: SourceDemoClient/Poker/PokerGame.cpp
  162. // @Brief: PokerGame
  163. // @Author: LouLei
  164. // @Email: twopointfive@163.com
  165. // @Copyright (Crapell) - All Rights Reserved
  166. //========================================================
  167. #include "General/Pch.h"
  168. #include "General/Window.h"
  169. #include "General/Timer.h"
  170. #include "Poker/PokerGame.h"
  171. #include "Render/RendDriver.h"
  172. #include "Render/Texture.h"
  173. #include "Render/Font.h"
  174. #include "Packet/PacketMiniGame.h"
  175. #include "Sound/ChannelSound.h"
  176. #include "Rpg/MiniGame.h"
  177. #include <stdlib.h>
  178. #include "General/Pce.h"
  179. #include "MiniGamePoker.h"
  180. #include "Rpg/SyncGameInfo.h"
  181. PokerGame::PokerGame()
  182. {
  183. m_gameStatus = Dealing;
  184. m_openPoker = false;
  185. for (int i=0;i<4;i++)
  186. {
  187. m_players[i] = NULL;
  188. }
  189. }
  190. PokerGame::~PokerGame()
  191. {
  192. Free();
  193. }
  194. void PokerGame::StateDealCard()
  195. {
  196. }
  197. void PokerGame::OutCard(PokerPlayer*player)
  198. {
  199. G_PokerGame->PlaySound__("data/sound/step_foot.wav");
  200. for(int i = 0; i < player->m_cardNum; i++)
  201. {
  202. if(player->m_cards[i].bClicked == true)
  203. {
  204. m_cardFlag[player->m_cards[i].cardID] = BeOut;
  205. }
  206. }
  207. player->OutCard();
  208. }
  209. void PokerGame::FirstOut()
  210. {
  211. }
  212. bool PokerGame::CheckRoundEnd()
  213. {
  214. return false;
  215. }
  216. bool PokerGame::Render()
  217. {
  218. G_RendDriver->Color4f(1,1,1,1);
  219. G_RendDriver->SetRenderStateEnable(RS_BLEND,true);
  220. G_RendDriver->BlendFunc(Blend_Filter);
  221. //if(m_gameStatus == Playing)
  222. {
  223. for(int i = 0; i < m_playerNum; i++)
  224. {
  225. m_players[i]->Render();
  226. }
  227. }
  228. return true;
  229. }
  230. bool PokerGame::Start()
  231. {
  232. m_gameStatus = Dealing;
  233. m_dealCardNum = 0;
  234. m_dealAccumTime = 0;
  235. m_turn = 0;
  236. m_lastOutTurn = -1;
  237. for(int i = 0; i < CardNum; i++)
  238. m_cardFlag[i] = NotDeal;
  239. G_TextureMgr->AddTexture(m_texBack, "data/minigame/poker/back.png");
  240. const char* cardTexName[] =
  241. {
  242. "data/minigame/poker/mei2.png",
  243. "data/minigame/poker/mei3.png",
  244. "data/minigame/poker/mei4.png",
  245. "data/minigame/poker/mei5.png",
  246. "data/minigame/poker/mei6.png",
  247. "data/minigame/poker/mei7.png",
  248. "data/minigame/poker/mei8.png",
  249. "data/minigame/poker/mei9.png",
  250. "data/minigame/poker/mei10.png",
  251. "data/minigame/poker/meiJ.png",
  252. "data/minigame/poker/meiQ.png",
  253. "data/minigame/poker/meiK.png",
  254. "data/minigame/poker/meiA.png",
  255. "data/minigame/poker/fang2.png",
  256. "data/minigame/poker/fang3.png",
  257. "data/minigame/poker/fang4.png",
  258. "data/minigame/poker/fang5.png",
  259. "data/minigame/poker/fang6.png",
  260. "data/minigame/poker/fang7.png",
  261. "data/minigame/poker/fang8.png",
  262. "data/minigame/poker/fang9.png",
  263. "data/minigame/poker/fang10.png",
  264. "data/minigame/poker/fangJ.png",
  265. "data/minigame/poker/fangQ.png",
  266. "data/minigame/poker/fangK.png",
  267. "data/minigame/poker/fangA.png",
  268. "data/minigame/poker/hei2.png",
  269. "data/minigame/poker/hei3.png",
  270. "data/minigame/poker/hei4.png",
  271. "data/minigame/poker/hei5.png",
  272. "data/minigame/poker/hei6.png",
  273. "data/minigame/poker/hei7.png",
  274. "data/minigame/poker/hei8.png",
  275. "data/minigame/poker/hei9.png",
  276. "data/minigame/poker/hei10.png",
  277. "data/minigame/poker/heiJ.png",
  278. "data/minigame/poker/heiQ.png",
  279. "data/minigame/poker/heiK.png",
  280. "data/minigame/poker/heiA.png",
  281. "data/minigame/poker/hong2.png",
  282. "data/minigame/poker/hong3.png",
  283. "data/minigame/poker/hong4.png",
  284. "data/minigame/poker/hong5.png",
  285. "data/minigame/poker/hong6.png",
  286. "data/minigame/poker/hong7.png",
  287. "data/minigame/poker/hong8.png",
  288. "data/minigame/poker/hong9.png",
  289. "data/minigame/poker/hong10.png",
  290. "data/minigame/poker/hongJ.png",
  291. "data/minigame/poker/hongQ.png",
  292. "data/minigame/poker/hongK.png",
  293. "data/minigame/poker/hongA.png",
  294. "data/minigame/poker/xiaowang.png",
  295. "data/minigame/poker/dawang.png",
  296. };
  297. for (int i=0;i<CardNum;i++)
  298. {
  299. G_TextureMgr->AddTexture(m_cardTexture[i],cardTexName[i]);
  300. }
  301. G_TextureMgr->AddTexture(m_cardBackTexture,"data/minigame/poker/cardback01.png");
  302. G_TextureMgr->AddTexture(m_passTexture[0],"data/minigame/poker/donotout00.png");
  303. G_TextureMgr->AddTexture(m_passTexture[1],"data/minigame/poker/donotout01.png");
  304. G_TextureMgr->AddTexture(m_passTexture[2],"data/minigame/poker/donotout02.png");
  305. G_TextureMgr->AddTexture(m_passTexture[3],"data/minigame/poker/donotout03.png");
  306. G_TextureMgr->AddTexture(m_thinkTexture[0],"data/minigame/poker/think00.png");
  307. G_TextureMgr->AddTexture(m_thinkTexture[1],"data/minigame/poker/think01.png");
  308. G_TextureMgr->AddTexture(m_thinkTexture[2],"data/minigame/poker/think02.png");
  309. G_TextureMgr->AddTexture(m_thinkTexture[3],"data/minigame/poker/think03.png");
  310. G_TextureMgr->AddTexture(m_passButtonTexture,"data/minigame/poker/donotoutbutton.png");
  311. CardHeight = 96;
  312. CardWidth = 71;
  313. if (m_bHost)
  314. {
  315. ShuffleCard();
  316. C2SPacketMiniGameCmd packet;
  317. packet.WriteHeader();
  318. packet.WriteValue(CMD_ShuffleCard); //todo每个人只发各自的牌,地主牌叫过另发。防止外挂作弊。
  319. packet.WriteValue(m_cardShuffle); //seed即可
  320. G_MiniGame->SendPacketToOther(&packet);
  321. }
  322. else
  323. {
  324. for (int i = 0; i < CardNum; i++)
  325. {
  326. m_cardShuffle[i] = -1;
  327. }
  328. }
  329. return true;
  330. }
  331. bool PokerGame::Stop()
  332. {
  333. Free();
  334. return true;
  335. }
  336. PokerPlayer* PokerGame::GetTurnPlayer()
  337. {
  338. return m_players[m_turn];
  339. }
  340. void PokerGame::SignCard(Card *card)
  341. {
  342. }
  343. bool PokerGame::Update()
  344. {
  345. m_turnTime += G_Timer->GetStepTimeLimited();
  346. if (m_gameStatus == Preparing
  347. ||m_gameStatus == Playing)
  348. {
  349. GetTurnPlayer()->Update();
  350. }
  351. return true;
  352. }
  353. bool PokerGame::Free()
  354. {
  355. for (int i=0;i<4;i++)
  356. {
  357. SafeDelete(m_players[i]);
  358. }
  359. return true;
  360. }
  361. void PokerGame::NextTurn()
  362. {
  363. int nextTurn = (++m_turn) % m_playerNum;
  364. m_turn = nextTurn;
  365. m_players[nextTurn]->m_outNum = 0;
  366. m_players[nextTurn]->m_notOut = 0;
  367. //m_players[(1+m_turn) % m_playerNum]->m_notOut = 0;
  368. m_turnTime = 0;
  369. }
  370. void PokerGame::ShuffleCard() //洗牌
  371. {
  372. for (int i = 0; i < CardNum; i++)
  373. {
  374. m_cardShuffle[i] = (CardID)i;
  375. }
  376. // 随机i-1中的任意一个数与i交换
  377. for (int i = 2; i < CardNum; i++)
  378. {
  379. int ran = Rand()%i;
  380. char temp = m_cardShuffle[ran];
  381. m_cardShuffle[ran] = m_cardShuffle[i];
  382. m_cardShuffle[i] = temp;
  383. }
  384. }
  385. int PokerGame::ProcessPacketCmd(PacketBase* packet)
  386. {
  387. int cmd;
  388. packet->ReadValue(cmd);
  389. switch(cmd)
  390. {
  391. case CMD_ShuffleCard:
  392. {
  393. //todo 只发自己的牌
  394. packet->ReadValue(m_cardShuffle);
  395. }
  396. return 1;
  397. }
  398. return 0;
  399. }
  400. Card::Card()
  401. {
  402. bClicked = false;
  403. }
  404. int Card::Color()
  405. {
  406. if(cardID == JokerSmall)
  407. {
  408. return 4; //小王 黑桃&&梅花
  409. }
  410. else if(cardID == JokerBig)
  411. {
  412. return 5;
  413. }
  414. else if(cardID >= 0 && cardID < JokerSmall)
  415. {
  416. return cardID / 13;
  417. }
  418. return 0;
  419. }
  420. PokerPlayer::PokerPlayer()
  421. :m_workingWithAI(false)
  422. ,m_clickedNum(0)
  423. ,m_movieCtrl(NULL)
  424. {
  425. m_sound = new SoundChannel;
  426. }
  427. PokerPlayer::~PokerPlayer()
  428. {
  429. SafeDelete(m_sound);
  430. }
  431. void PokerPlayer::AnalyseCard()
  432. {
  433. for(int i = 0; i < 18; i++)
  434. {
  435. ValueCount[i] = CountCard(i);
  436. }
  437. }
  438. int PokerPlayer::MinCard(int temp[], int num)
  439. {
  440. int i, min = temp[0];
  441. for(i = 1; i < num; i++)
  442. {
  443. if(temp[i] < min)
  444. {
  445. min = temp[i];
  446. }
  447. }
  448. return min;
  449. }
  450. int PokerPlayer::CountCard(int value)
  451. {
  452. int n = 0;
  453. for(int i = 0 ; i < m_cardNum ; i++)
  454. {
  455. if(m_cards[i].cardValue == value)
  456. n++;
  457. }
  458. return n;
  459. }
  460. void PokerPlayer::RecvCard(CardID cardID)
  461. {
  462. m_cards[m_cardNum].cardID = cardID;
  463. m_cards[m_cardNum].bClicked = false;
  464. m_game->SignCard(&m_cards[m_cardNum]);
  465. m_cardNum++;
  466. m_sound->PlaySound__("data/sound/chess_duk.wav");
  467. }
  468. bool PokerPlayer::Start()
  469. {
  470. for(int j = 0; j < MaxPlayerCard; j++)
  471. {
  472. m_cards[j].cardID = (CardID)0;
  473. m_cards[j].cardValue = -1;
  474. m_cards[j].bClicked = false;
  475. }
  476. m_cardNum = 0;
  477. m_outNum = 0;
  478. m_screenPos = SP_Up;
  479. m_totalScore = 0;
  480. m_turnScore = 0;
  481. m_bBaoPai = false;
  482. return true;
  483. }
  484. bool PokerPlayer::Stop()
  485. {
  486. Free();
  487. return true;
  488. }
  489. void PokerPlayer::OutCard()
  490. {
  491. Card card;
  492. int outNum = 0;
  493. int i = 0;
  494. while(i < m_cardNum)
  495. {
  496. if(m_cards[i].bClicked == true)
  497. {
  498. card = m_cards[i];
  499. //把被选中的牌挪到最后(显示出牌用),后面依次前移
  500. for(int j = i; j < MaxPlayerCard; j++)
  501. m_cards[j] = m_cards[j+1];
  502. card.bClicked = false;
  503. m_cards[MaxPlayerCard - 1] = card;
  504. m_cardNum--;
  505. outNum++;
  506. }
  507. else
  508. i++;
  509. }
  510. m_outNum = outNum;
  511. m_clickedNum = 0;
  512. }
  513. void PokerPlayer::SortCard()
  514. {
  515. }
  516. void PokerPlayer::Update()
  517. {
  518. }
  519. void PokerPlayer::Render()
  520. {
  521. int CardHeight=m_game->CardHeight;
  522. int CardWidth=m_game->CardWidth;
  523. ///显示名字
  524. if (GetPlayerInfo())
  525. {
  526. if(m_screenPos == SP_Down)
  527. {
  528. G_FontMgr->TextAtPos(vec2(Board2DCen.x - 33, G_PokerGame->BoardRect2D.GetBottom()-RenderUpDownSpace), GetPlayerInfo()->playerName);
  529. }
  530. else if(m_screenPos == SP_Up)
  531. {
  532. G_FontMgr->TextAtPos(vec2(Board2DCen.x - 33, G_PokerGame->BoardRect2D.y+RenderUpDownSpace), GetPlayerInfo()->playerName);
  533. }
  534. else if(m_screenPos == SP_Right)
  535. {
  536. G_FontMgr->TextAtPos(vec2(G_Window->m_iWidth - 66 - 5, Board2DCen.y), GetPlayerInfo()->playerName);
  537. }
  538. else if(m_screenPos == SP_Left)
  539. {
  540. G_FontMgr->TextAtPos(vec2(5, Board2DCen.y), GetPlayerInfo()->playerName);
  541. }
  542. }
  543. G_RendDriver->Color3f(1,1,1);
  544. ///显示未出的牌
  545. bool canSee = m_game->m_openPoker;//明牌
  546. switch(m_screenPos)
  547. {
  548. case SP_Down:
  549. {
  550. CardX = Board2DCen.x - ((m_cardNum - 1) * RenderShiftX + CardWidth)/2;
  551. CardY = G_PokerGame->BoardRect2D.GetBottom()-RenderUpDownSpace - CardHeight;
  552. for(int i = 0; i < m_cardNum; i++)
  553. {
  554. if(m_cards[i].bClicked == false)
  555. {
  556. m_game->m_cardTexture[m_cards[i].cardID]->Bind();
  557. G_RendDriver->DrawTextureRect(RectF(CardX+i* RenderShiftX, CardY, CardWidth, CardHeight));
  558. }
  559. else
  560. {
  561. m_game->m_cardTexture[m_cards[i].cardID]->Bind();
  562. G_RendDriver->DrawTextureRect(RectF(CardX+i * RenderShiftX, CardY -RenderClickedAddDistance, CardWidth, CardHeight));
  563. }
  564. }
  565. }
  566. break;
  567. case SP_Right:
  568. {
  569. int x = G_PokerGame->BoardRect2D.GetRight() - RenderLeftRightSpace- CardWidth;
  570. int y = Board2DCen.y - (m_cardNum * RenderShiftY + CardHeight)/2;
  571. for(int i = 0; i < m_cardNum; i++)
  572. {
  573. if (canSee)
  574. m_game->m_cardTexture[m_cards[i].cardID]->Bind();
  575. else
  576. m_game->m_cardBackTexture->Bind();
  577. G_RendDriver->DrawTextureRect(RectF(x, y + i * RenderShiftY, CardWidth, CardHeight));
  578. }
  579. }
  580. break;
  581. case SP_Up:
  582. {
  583. int x = Board2DCen.x - ((m_cardNum - 1) * RenderShiftX + CardWidth)/2;
  584. int y = G_PokerGame->BoardRect2D.y + RenderUpDownSpace;
  585. for(int i = 0; i < m_cardNum; i++)
  586. {
  587. if (canSee)
  588. m_game->m_cardTexture[m_cards[i].cardID]->Bind();
  589. else
  590. m_game->m_cardBackTexture->Bind();
  591. G_RendDriver->DrawTextureRect(RectF(x + i * RenderShiftX, y, CardWidth, CardHeight));
  592. }
  593. }
  594. break;
  595. case SP_Left:
  596. {
  597. int x = G_PokerGame->BoardRect2D.x + RenderLeftRightSpace;
  598. int y = Board2DCen.y - (m_cardNum * RenderShiftY + CardHeight)/2;
  599. for(int i = 0; i < m_cardNum; i++)
  600. {
  601. if (canSee)
  602. m_game->m_cardTexture[m_cards[i].cardID]->Bind();
  603. else
  604. m_game->m_cardBackTexture->Bind();
  605. G_RendDriver->DrawTextureRect(RectF(x, y + i * RenderShiftY, CardWidth, CardHeight));
  606. }
  607. }
  608. break;
  609. }
  610. 显示所出的牌
  611. {
  612. int outX, outY;
  613. int i, j;
  614. if(m_screenPos == SP_Down)
  615. {
  616. outX = Board2DCen.x - m_outNum * RenderShiftX/2 - RenderShiftX;
  617. outY = G_PokerGame->BoardRect2D.GetBottom()-RenderUpDownSpace - CardHeight * 2 - RenderUpDownDistance;
  618. for(i = MaxPlayerCard - m_outNum, j=0; i < MaxPlayerCard; i++, j++)
  619. {
  620. m_game->m_cardTexture[m_cards[i].cardID]->Bind();
  621. G_RendDriver->DrawTextureRect(RectF( outX+j * RenderShiftX, outY, CardWidth,CardHeight));
  622. }
  623. }
  624. if(m_screenPos == SP_Right)
  625. {
  626. outX = G_PokerGame->BoardRect2D.GetRight() - RenderLeftRightSpace - CardWidth*2.8f;
  627. outY = Board2DCen.y - ((m_outNum - 1) * RenderShiftY + CardHeight)/2;
  628. for(i = MaxPlayerCard - m_outNum, j = 0; i < MaxPlayerCard; i++, j++)
  629. {
  630. m_game->m_cardTexture[m_cards[i].cardID]->Bind();
  631. G_RendDriver->DrawTextureRect(RectF(outX, outY+j * RenderShiftY, CardWidth,CardHeight ));
  632. }
  633. }
  634. if(m_screenPos == SP_Up)
  635. {
  636. outX = Board2DCen.x - ((m_outNum - 1) * RenderShiftX + CardWidth)/2;
  637. outY = G_PokerGame->BoardRect2D.y + RenderUpDownSpace + CardHeight + RenderUpDownDistance;
  638. for(i = MaxPlayerCard - m_outNum, j=0; i < MaxPlayerCard; i++, j++)
  639. {
  640. m_game->m_cardTexture[m_cards[i].cardID]->Bind();
  641. G_RendDriver->DrawTextureRect(RectF( outX+j * RenderShiftX, outY , CardWidth,CardHeight ));
  642. }
  643. }
  644. if(m_screenPos == SP_Left)
  645. {
  646. outX = G_PokerGame->BoardRect2D.x + RenderLeftRightSpace + CardWidth*1.8f;
  647. outY = Board2DCen.y - ((m_outNum - 1) * RenderShiftY + CardHeight)/2;
  648. for(i = MaxPlayerCard - m_outNum, j = 0; i < MaxPlayerCard; i++, j++)
  649. {
  650. m_game->m_cardTexture[m_cards[i].cardID]->Bind();
  651. G_RendDriver->DrawTextureRect(RectF(outX, outY+j * RenderShiftY, CardWidth,CardHeight));
  652. }
  653. }
  654. }
  655. }
  656. //标记要出牌
  657. bool PokerPlayer::ClickCards(int cardValue[],int num)
  658. {
  659. int find = 0;
  660. for(int i = 0; i < num; i++)
  661. {
  662. for(int j = 0; j < m_cardNum; j++)
  663. {
  664. if(m_cards[j].cardValue == cardValue[i]
  665. && m_cards[j].bClicked == false //有可能两张相同value
  666. )
  667. {
  668. find++;
  669. m_cards[j].bClicked = true;
  670. break;
  671. }
  672. }
  673. }
  674. assert(find == num);
  675. return (find == num);
  676. }
  677. //标记要出牌
  678. bool PokerPlayer::ClickCardsID(int cardID[],int num)
  679. {
  680. int find = 0;
  681. for(int i = 0; i < num; i++)
  682. {
  683. for(int j = 0; j < m_cardNum; j++)
  684. {
  685. if(m_cards[j].cardID == cardID[i]
  686. && m_cards[j].bClicked == false //有可能两张相同value
  687. )
  688. {
  689. find++;
  690. m_cards[j].bClicked = true;
  691. break;
  692. }
  693. }
  694. }
  695. assert(find == num);
  696. return (find == num);
  697. }
  698. int PokerPlayer::ClickCard(const vec2& mousePos)
  699. {
  700. int x1, y1, x2, y2;
  701. x1 = CardX;
  702. y1 = CardY - RenderClickedAddDistance;
  703. x2 = (m_cardNum - 1) * RenderShiftX + m_game->CardWidth + CardX;
  704. y2 = CardY + m_game->CardHeight;
  705. if((mousePos.x < x2) && (mousePos.x > x1)
  706. && (mousePos.y > y1) && (mousePos.y < y2))
  707. {
  708. if(m_cardNum != 0)
  709. {
  710. int n;
  711. n = (mousePos.x - CardX) / RenderShiftX;
  712. if(n >= m_cardNum)
  713. n = m_cardNum - 1;
  714. if(m_cards[n].bClicked == false)
  715. {
  716. m_cards[n].bClicked = true;
  717. m_clickedNum++;
  718. }
  719. else if(m_cards[n].bClicked == true)
  720. {
  721. m_cards[n].bClicked = false;
  722. m_clickedNum--;
  723. }
  724. m_sound->PlaySound__("data/sound/chess_duk.wav");
  725. }
  726. }
  727. return 0;
  728. }
  729. ToOutCards::ToOutCards()
  730. {
  731. for(int i = 0; i < MaxPlayerCard; i++)
  732. {
  733. m_cards[i].cardID = (CardID)0;
  734. m_cards[i].cardValue = -1;
  735. }
  736. m_cardNum = 0;
  737. }
  738. int ToOutCards::MinCard()
  739. {
  740. int min = m_cards[0].cardValue;
  741. for(int i = 1; i < m_cardNum; i++)
  742. {
  743. if(m_cards[i].cardValue < min)
  744. {
  745. min = m_cards[i].cardValue;
  746. }
  747. }
  748. return min;
  749. }
  750. int ToOutCards::CountCard(int value)
  751. {
  752. int n = 0;
  753. for(int i = 0 ; i < m_cardNum ; i++)
  754. if(m_cards[i].cardValue == value)
  755. n++;
  756. return n;
  757. }
  758. const char* PokerCmdToString(int enumeration)
  759. {
  760. switch(enumeration)
  761. {
  762. case CMD_ShuffleCard:return "CMD_ShuffleCard";
  763. case CMD_BeLord :return "CMD_BeLord ";
  764. case CMD_NotBeLord :return "CMD_NotBeLord ";
  765. case CMD_OutCard :return "CMD_OutCard ";
  766. case CMD_Pass :return "CMD_Pass ";
  767. case CMD_GameOver :return "CMD_GameOver ";
  768. case CMD_Restart :return "CMD_Restart ";
  769. default :return "CMD_unknow";
  770. }
  771. return "CMD_unknow";
  772. }

斗地主游戏派生类:

  1. //========================================================
  2. // @Date: 2016.05
  3. // @File: SourceDemoClient/Poker/PokerDouDiZhu.h
  4. // @Brief: PokerDouDiZhu
  5. // @Author: LouLei
  6. // @Email: twopointfive@163.com
  7. // @Copyright (Crapell) - All Rights Reserved
  8. //========================================================
  9. #if !defined(DouDiZhu_h__)
  10. #define DouDiZhu_h__
  11. #include "PokerGame.h"
  12. //准备要出的牌
  13. class ToOutCardsDouDizhu:public ToOutCards
  14. {
  15. public:
  16. };
  17. enum OutType
  18. {
  19. None = -1,
  20. GZ = 0, //单张
  21. DZ , //对子
  22. SZ , //顺子
  23. SGBD , //三张不带
  24. SD1 , //三带一
  25. SD2 , //三带二
  26. SD2G , //四带二
  27. SD2D , //四带二对
  28. LD3 , //三连对
  29. LD4 ,
  30. LD5 ,
  31. LD6 ,
  32. LD7 ,
  33. FJBD , //飞机不带
  34. FJD2G , //飞机带二个
  35. FJD2D , //飞机带两对
  36. SFJBD , //三飞机不带
  37. SFJDSG, //三飞机带三个
  38. SFJDSD, //三飞机带三对
  39. ZD , //炸弹
  40. SW , //双王
  41. };
  42. struct CurOutCards
  43. {
  44. int value;
  45. OutType type;
  46. //char type[10];
  47. int num;
  48. int min;
  49. };
  50. class DouDizhuPlayerRobot;
  51. class DouDizhuPlayerRole;
  52. class PokerDouDiZhu:public PokerGame
  53. {
  54. public:
  55. enum CardValue
  56. {
  57. Value3 = 3,
  58. Value4,
  59. Value5,
  60. Value6,
  61. Value7,
  62. Value8,
  63. Value9,
  64. Value10,
  65. ValueJ,
  66. ValueQ,
  67. ValueK,
  68. ValueA = 14,
  69. Value2 = 15,
  70. ValueJokerSmall = 16,
  71. ValueJokerBig = 17,
  72. };
  73. PokerDouDiZhu();
  74. virtual ~PokerDouDiZhu();
  75. virtual bool Start();
  76. virtual bool Stop();
  77. virtual bool Render();
  78. virtual bool Update();
  79. virtual bool CheckRoundEnd(); //结束判断
  80. virtual void StateDealCard(); //发牌
  81. void StateDecideLord(); //选地主
  82. //注意:不要循环发送,比如主机发过来,调用了几层函数又发回去
  83. void SendDecideLord(int turn); //
  84. void DecideLord(int turn); //选出地主
  85. virtual void SignCard(Card *card); //标记牌分值
  86. virtual void FirstOut(); //首次出牌
  87. //没出的最大单牌
  88. int MaxCard();
  89. void OnRButtonDown();
  90. bool Button_NotBeLord();
  91. bool Button_BeLord();
  92. bool Button_Pass();
  93. //处理游戏网络命令包
  94. virtual int ProcessPacketCmd(PacketBase* packet);
  95. //virtual const char* CmdToString(const char* stream,int len);
  96. int m_winnerTurn; //标记哪个是赢家
  97. int m_lordTurn; //地主位置
  98. Card m_lordCard[3]; //三张地主牌
  99. CurOutCards m_curOutCards;
  100. ToOutCardsDouDizhu m_toOutCards; //准备要出的牌
  101. DouDizhuPlayerRole* m_myRolePlayer;
  102. TexturePtr m_lordTexture;
  103. TexturePtr m_notbeLordTexture;
  104. TexturePtr m_notbeLordButtonTexture;
  105. TexturePtr m_sanfenButtonTexture;
  106. TexturePtr m_winTexture;
  107. TexturePtr m_loseTexture;
  108. //炸弹倍数
  109. int m_zhadanNum;
  110. };
  111. extern PokerDouDiZhu* G_PokerDouDiZhu;
  112. #endif
  113. //========================================================
  114. // @Date: 2016.05
  115. // @File: SourceDemoClient/Poker/PokerDouDiZhu.cpp
  116. // @Brief: PokerDouDiZhu
  117. // @Author: LouLei
  118. // @Email: twopointfive@163.com
  119. // @Copyright (Crapell) - All Rights Reserved
  120. //========================================================
  121. #include "General/Pch.h"
  122. #include "General/Timer.h"
  123. #include "General/Window.h"
  124. #include "Input/InputMgr.h"
  125. #include "Poker/PokerDoudizhu.h"
  126. #include "Poker/PokerGame.h"
  127. #include "Poker/DouDiZhuPlayer.h"
  128. #include "Poker/MiniGamePoker.h"
  129. #include "Poker/MiPoker_PlayGui.h"
  130. #include "Net/PacketList.h"
  131. #include "Gui/MiniGuis.h"
  132. #include "Gui/GuiMgr.h"
  133. #include "Gui/GuiControlMisc.h"
  134. #include "Rpg/MiniGame.h"
  135. #include "Rpg/SyncGameInfo.h"
  136. #include "Packet/PacketMiniGame.h"
  137. #include "Render/RendDriver.h"
  138. #include "Render/Texture.h"
  139. #include "Sound/ChannelSound.h"
  140. #include "General/Pce.h"
  141. PokerDouDiZhu* G_PokerDouDiZhu = NULL;
  142. PokerDouDiZhu::PokerDouDiZhu()
  143. {
  144. m_lastOutTurn = -1;
  145. m_lordTurn = -1;
  146. m_winnerTurn = -1;
  147. G_PokerDouDiZhu = this;
  148. }
  149. PokerDouDiZhu::~PokerDouDiZhu()
  150. {
  151. }
  152. bool PokerDouDiZhu::Start()
  153. {
  154. m_myRolePlayer = NULL;//?
  155. PokerGame::Start();
  156. G_TextureMgr->AddTexture(m_notbeLordTexture,"data/minigame/poker/bujiao.png");
  157. G_TextureMgr->AddTexture(m_notbeLordButtonTexture,"data/minigame/poker/bujiaobutton.png");
  158. G_TextureMgr->AddTexture(m_lordTexture,"data/minigame/poker/islord.png");
  159. G_TextureMgr->AddTexture(m_sanfenButtonTexture,"data/minigame/poker/sanfen.png");
  160. G_TextureMgr->AddTexture(m_winTexture,"data/minigame/poker/win.png");
  161. G_TextureMgr->AddTexture(m_loseTexture,"data/minigame/poker/lose.png");
  162. m_turnTime = 0;
  163. m_lordTurn = -1;
  164. m_myPlayer = NULL;
  165. //
  166. m_playerNum = 3;
  167. for(int i = 0; i < m_playerNum; i++)
  168. {
  169. MyRoomPlayerInfo* playerInfo = G_SyncMyRoomInfo->GetPlayerFromIndex(i);
  170. if (playerInfo)
  171. {
  172. //roomSlot 不一定连续,但已经排序
  173. if (playerInfo->roomSlot == G_SyncMyRoomInfo->m_myRoomSlot)
  174. {
  175. m_players[i] = m_myRolePlayer = new DouDizhuPlayerRole;
  176. m_myPlayer = m_myRolePlayer;
  177. }
  178. else
  179. {
  180. if (G_PokerGame->IsHost()==false ||
  181. playerInfo->isAI==false)
  182. {
  183. //非主机上ai表现同实体玩家
  184. m_players[i] = new DouDizhuPlayer;
  185. }
  186. else
  187. {
  188. //主机负责ai玩家的模拟
  189. m_players[i] = new DouDizhuPlayerRobot;
  190. }
  191. }
  192. m_players[i]->SetPlayerInfo(playerInfo);
  193. }
  194. else
  195. {
  196. return false;
  197. }
  198. }
  199. //
  200. if (m_myRolePlayer)
  201. {
  202. m_myRolePlayer->m_toOutCard = &m_toOutCards;
  203. }
  204. else
  205. {
  206. return false;
  207. }
  208. for(int i = 0; i < m_playerNum; i++)
  209. {
  210. dynamic_cast<DouDizhuPlayer*>(m_players[i])->g_curOutCards = &m_curOutCards;
  211. m_players[i]->m_turn = i;
  212. m_players[i]->m_game = this;
  213. m_players[i]->Start();
  214. }
  215. //
  216. MiPoker_PlayGui* playGui = G_GuiMgr->GetGui<MiPoker_PlayGui>();
  217. if (playGui && playGui->IsAwake())
  218. {
  219. //自动出牌
  220. if(m_myPlayer)
  221. m_myPlayer->m_workingWithAI = playGui->m_textButtonOption[2]->GetState()==GCS_CLICK;
  222. //明牌
  223. m_openPoker = playGui->m_textButtonOption[3]->GetState()==GCS_CLICK;
  224. }
  225. //
  226. int myTurn = m_myRolePlayer?m_myRolePlayer->m_turn:0;
  227. m_players[myTurn]->m_screenPos = SP_Down;
  228. m_players[++myTurn%m_playerNum]->m_screenPos = SP_Right;
  229. m_players[++myTurn%m_playerNum]->m_screenPos = SP_Left;
  230. //进入miniplaygui,(选人、选关卡都已在房间里进行完毕)。
  231. //if(GetStyle()) G_GuiMgr->PushGui(GetStyle()->playGUI.c_str(),GL_DIALOG);
  232. return true;
  233. }
  234. bool PokerDouDiZhu::Stop()
  235. {
  236. Free();
  237. return true;
  238. }
  239. bool PokerDouDiZhu::Update()
  240. {
  241. PokerGame::Update();
  242. switch(m_gameStatus)
  243. {
  244. case Dealing:
  245. StateDealCard();
  246. break;
  247. case Preparing:
  248. {
  249. //call back
  250. if (G_Mouse->IsButtonDowning(MOUSE_LEFT))
  251. {
  252. if(Button_BeLord())
  253. return true;
  254. if(Button_NotBeLord())
  255. return true;
  256. }
  257. }
  258. break;
  259. case Playing:
  260. {
  261. CheckRoundEnd();
  262. if (G_Mouse->IsButtonDowning(MOUSE_LEFT))
  263. {
  264. //todo set ui visible + call back
  265. if(Button_Pass())
  266. return true;
  267. }
  268. //call back
  269. if (G_Mouse->IsButtonDowning(MOUSE_RIGHT))
  270. {
  271. OnRButtonDown();
  272. }
  273. }
  274. break;
  275. case Resulting:
  276. {
  277. if (m_turnTime > 5)
  278. {
  279. if (m_bHost)
  280. {
  281. C2SPacketMiniGameCmd packet;
  282. packet.WriteHeader();
  283. packet.WriteValue(CMD_Restart);
  284. G_MiniGame->SendPacketToOther(&packet);
  285. }
  286. Free();
  287. Start(); //send shuffle
  288. }
  289. }
  290. break;
  291. }
  292. return true;
  293. }
  294. bool PokerDouDiZhu::Render()
  295. {
  296. PokerGame::Render();
  297. //if(m_gameStatus == Playing || m_gameStatus == Preparing)
  298. {
  299. //显示地主牌
  300. {
  301. int x, y;
  302. x = Board2DCen.x - CardWidth * 5/2;
  303. y = G_PokerGame->BoardRect2D.y + RenderUpDownDistance;
  304. if(m_gameStatus == Playing)
  305. {
  306. for(int i = 0; i < 3; i++)
  307. {
  308. m_cardTexture[m_lordCard[i].cardID]->Bind();
  309. G_RendDriver->DrawTextureRect(RectF( x+i * 2 * CardWidth, y, CardWidth,CardHeight));
  310. }
  311. }
  312. else
  313. {
  314. //未叫显示背面
  315. for(int i = 0; i < 3; i++)
  316. {
  317. m_cardBackTexture->Bind();
  318. G_RendDriver->DrawTextureRect(RectF(x + i * 2 * CardWidth, y, CardWidth, CardHeight));
  319. }
  320. }
  321. }
  322. }
  323. if (m_gameStatus == Resulting)
  324. {
  325. if (m_myRolePlayer==NULL
  326. || m_winnerTurn == m_myRolePlayer->m_turn
  327. || (m_winnerTurn!=m_lordTurn && m_myRolePlayer->IsLord()==false) )
  328. {
  329. m_winTexture->Bind();
  330. G_RendDriver->DrawTextureRect(vec2(Board2DCen.x-m_winTexture->GetWidth()/2, Board2DCen.y-m_winTexture->GetHeight()/2));
  331. }
  332. else
  333. {
  334. m_loseTexture->Bind();
  335. G_RendDriver->DrawTextureRect(vec2(Board2DCen.x-m_loseTexture->GetWidth()/2, Board2DCen.y-m_loseTexture->GetHeight()/2));
  336. }
  337. }
  338. return true;
  339. }
  340. bool PokerDouDiZhu::CheckRoundEnd()
  341. {
  342. //if(m_players[m_turn]->m_cardNum == 0)
  343. //{
  344. // m_winnerTurn = m_turn;
  345. // GameOver();
  346. // return true;
  347. //}
  348. bool gameOver = false;
  349. for(int i = 0; i < m_playerNum; i++)
  350. {
  351. if(m_players[i]->m_cardNum == 0)
  352. {
  353. m_winnerTurn = i;
  354. gameOver = true;
  355. }
  356. }
  357. if(gameOver&&m_bHost)
  358. {
  359. int fen = 3;
  360. if(m_winnerTurn == m_lordTurn)
  361. fen = -3;
  362. //fen *= zhadan;
  363. for(int i = 0; i < m_playerNum; i++)
  364. {
  365. if(i!=m_lordTurn)
  366. m_players[i]->m_totalScore += fen ;
  367. else
  368. m_players[i]->m_totalScore -= fen*2;
  369. }
  370. char sound[256];
  371. if (m_winnerTurn == m_lordTurn)
  372. {
  373. sprintf(sound,"data/sound/poker/play_lord_win");
  374. }
  375. else
  376. {
  377. sprintf(sound,"data/sound/poker/play_farmer_win");
  378. }
  379. if (m_winnerTurn%2) //
  380. strcat(sound,"_femail.wav");
  381. else
  382. strcat(sound,".wav");
  383. m_players[m_winnerTurn]->m_sound->PlaySound__(sound);
  384. C2SPacketMiniGameCmd packet;
  385. packet.WriteHeader();
  386. packet.WriteValue(CMD_GameOver);
  387. packet.WriteValue(m_winnerTurn);
  388. G_MiniGame->SendPacketToOther(&packet);
  389. m_gameStatus = Resulting;
  390. m_turnTime = 0;
  391. }
  392. return gameOver;
  393. }
  394. //标记牌值
  395. void PokerDouDiZhu::SignCard(Card *card)
  396. {
  397. int id = card->cardID;
  398. if(id == JokerSmall)
  399. {
  400. card->cardValue = 16;
  401. }
  402. else if(id == JokerBig)
  403. {
  404. card->cardValue = 17;
  405. }
  406. else if(id >= 0 && id < JokerSmall)
  407. {
  408. card->cardValue = (id + 12) %13 + 3;
  409. }
  410. }
  411. void PokerDouDiZhu::StateDealCard()
  412. {
  413. //另外三张决定地主后再发
  414. if (m_dealCardNum>=51)
  415. {
  416. for(int i = 0; i < m_playerNum; i++)
  417. m_players[i]->SortCard();
  418. m_gameStatus = Preparing;
  419. return;
  420. }
  421. m_dealAccumTime += G_Timer->GetStepTime();
  422. //0.1秒发一张
  423. if (m_dealAccumTime > m_dealCardNum*0.1f)
  424. {
  425. CardID cardID = (CardID)m_cardShuffle[m_dealCardNum];
  426. if (cardID>=0)
  427. {
  428. m_cardFlag[cardID] = InHand;
  429. int playerIndex = m_dealCardNum % m_playerNum;
  430. m_players[playerIndex]->RecvCard(cardID);
  431. m_dealCardNum++;
  432. }
  433. else
  434. {
  435. //host洗牌还没发下来
  436. }
  437. }
  438. }
  439. void PokerDouDiZhu::SendDecideLord(int turn)
  440. {
  441. C2SPacketMiniGameCmd packet;
  442. packet.WriteHeader();
  443. packet.WriteValue(CMD_BeLord);
  444. packet.WriteValue(m_turn);
  445. //todo给lord发三张地主牌,目前是洗牌时已经发送
  446. G_MiniGame->SendPacketToOther(&packet);
  447. }
  448. void PokerDouDiZhu::DecideLord(int turn)
  449. {
  450. m_lordTurn = turn;
  451. m_lastOutTurn = turn;
  452. m_turn = turn;
  453. m_turnTime = 0;
  454. m_gameStatus = Playing;
  455. for(int i = 0; i < 3; i++)
  456. {
  457. m_lordCard[i].cardID = (CardID)m_cardShuffle[i+CardNum-3];
  458. }
  459. //给地主发三张牌
  460. for(int i = 0; i < 3; i++)
  461. m_players[m_lordTurn]->RecvCard(m_lordCard[i].cardID);
  462. m_players[m_lordTurn]->SortCard();
  463. char sound[256];
  464. sprintf(sound,"data/sound/poker/call_jiaofeng_3");
  465. if (m_turn%2) //
  466. strcat(sound,"_femail.wav");
  467. else
  468. strcat(sound,".wav");
  469. if(m_myRolePlayer)
  470. m_myRolePlayer->m_sound->PlaySound__(sound);
  471. }
  472. //决定地主
  473. void PokerDouDiZhu::StateDecideLord()
  474. {
  475. }
  476. void PokerDouDiZhu::FirstOut()
  477. {
  478. }
  479. //现存最大单牌
  480. int PokerDouDiZhu::MaxCard()
  481. {
  482. if(m_cardFlag[JokerBig] != BeOut)
  483. return 17;
  484. if(m_cardFlag[JokerSmall] != BeOut)
  485. return 16;
  486. int max = 0;
  487. for(int i = 0; i < JokerSmall; i++)
  488. {
  489. if(m_cardFlag[i] != BeOut && max < (i +12) % 13)
  490. max = (i + 12) % 13 + 3;
  491. }
  492. return max;
  493. }
  494. void PokerDouDiZhu::OnRButtonDown()
  495. {
  496. if(m_myRolePlayer==NULL
  497. ||m_turn != m_myRolePlayer->m_turn)
  498. return;
  499. if(m_gameStatus != Playing)
  500. return;
  501. m_myRolePlayer->m_notOut = 0;//?
  502. if(m_gameStatus == Playing && m_myRolePlayer->TryOutCard())
  503. {
  504. OutCard(m_myRolePlayer);
  505. //if (CheckRoundEnd()==false)
  506. {
  507. C2SPacketMiniGameCmd packet;
  508. packet.WriteHeader();
  509. packet.WriteValue(CMD_OutCard);
  510. packet.WriteValue(m_myRolePlayer->m_turn);
  511. packet.WriteValue(m_curOutCards);
  512. //
  513. packet.WriteValue(m_myRolePlayer->m_outNum);
  514. for(int i = MaxPlayerCard - m_myRolePlayer->m_outNum; i < MaxPlayerCard; i++)
  515. {
  516. packet.WriteValue(m_myRolePlayer->m_cards[i].cardID);
  517. }
  518. G_MiniGame->SendPacketToOther(&packet);
  519. m_lastOutTurn = m_myRolePlayer->m_turn;
  520. NextTurn();
  521. }
  522. }
  523. }
  524. //人当地主
  525. bool PokerDouDiZhu::Button_BeLord()
  526. {
  527. if(m_myRolePlayer==NULL
  528. ||m_turn != m_myRolePlayer->m_turn)
  529. return false;
  530. if(m_gameStatus != Preparing)
  531. return false;
  532. int ClickX = G_PokerGame->GetMousePos().x;
  533. int ClickY = G_PokerGame->GetMousePos().y;
  534. int buttonX = Board2DCen.x - 80;
  535. int buttonY = G_PokerGame->BoardRect2D.GetBottom()-RenderUpDownSpace-CardHeight-32;
  536. if(ClickX>buttonX && ClickX<buttonX+m_sanfenButtonTexture->GetWidth()
  537. && ClickY>buttonY && ClickY < buttonY+m_sanfenButtonTexture->GetHeight())
  538. {
  539. G_PokerDouDiZhu->SendDecideLord(m_turn);
  540. DecideLord(m_myRolePlayer->m_turn);
  541. return true;
  542. }
  543. return false;
  544. }
  545. //人不当地主
  546. bool PokerDouDiZhu::Button_NotBeLord()
  547. {
  548. if(m_myRolePlayer==NULL
  549. ||m_turn != m_myRolePlayer->m_turn)
  550. return false;
  551. if(m_gameStatus != Preparing)
  552. return false;
  553. int ClickX = G_PokerGame->GetMousePos().x;
  554. int ClickY = G_PokerGame->GetMousePos().y;
  555. int buttonX = G_Window->m_iWidth/2 + 20;
  556. int buttonY = G_PokerGame->BoardRect2D.GetBottom()-RenderUpDownSpace-CardHeight-32;
  557. if(ClickX>buttonX && ClickX<buttonX+m_notbeLordButtonTexture->GetWidth()
  558. && ClickY>buttonY && ClickY < buttonY+m_notbeLordButtonTexture->GetHeight())
  559. {
  560. C2SPacketMiniGameCmd packet;
  561. packet.WriteHeader();
  562. packet.WriteValue(CMD_NotBeLord);
  563. packet.WriteValue(m_myRolePlayer->m_turn);
  564. G_MiniGame->SendPacketToOther(&packet);
  565. m_turn = (m_myRolePlayer->m_turn+1) % m_playerNum;
  566. m_turnTime = 0;
  567. //NextTurn()
  568. char sound[256];
  569. sprintf(sound,"data/sound/poker/call_bujiao");
  570. if (m_turn%2) //
  571. strcat(sound,"_femail.wav");
  572. else
  573. strcat(sound,".wav");
  574. m_myRolePlayer->m_sound->PlaySound__(sound);
  575. return true;
  576. }
  577. return false;
  578. }
  579. bool PokerDouDiZhu::Button_Pass()
  580. {
  581. if(m_myRolePlayer==NULL
  582. ||m_lastOutTurn == m_myRolePlayer->m_turn)
  583. return false;
  584. if(m_turn != m_myRolePlayer->m_turn)
  585. return false;
  586. if(m_gameStatus != Playing)
  587. return false;
  588. int ClickX = G_PokerGame->GetMousePos().x;
  589. int ClickY = G_PokerGame->GetMousePos().y;
  590. int buttonX = Board2DCen.x - 30;
  591. int buttonY = G_PokerGame->BoardRect2D.GetBottom()-RenderUpDownSpace-CardHeight-32;
  592. if(ClickX>buttonX && ClickX<buttonX+m_passButtonTexture->GetWidth()
  593. && ClickY>buttonY && ClickY < buttonY+m_passButtonTexture->GetHeight())
  594. {
  595. C2SPacketMiniGameCmd packet;
  596. packet.WriteHeader();
  597. packet.WriteValue(CMD_Pass);
  598. packet.WriteValue(m_myRolePlayer->m_turn);
  599. G_MiniGame->SendPacketToOther(&packet);
  600. m_myRolePlayer->m_notOut = 1;
  601. NextTurn();
  602. char sound[256];
  603. sprintf(sound,"data/sound/poker/play_guo_%d",Rand()%2);
  604. if (m_turn%2) //
  605. strcat(sound,"_femail.wav");
  606. else
  607. strcat(sound,".wav");
  608. m_myRolePlayer->m_sound->PlaySound__(sound);
  609. return true;
  610. }
  611. return false;
  612. }
  613. int PokerDouDiZhu::ProcessPacketCmd(PacketBase* packet)
  614. {
  615. PokerGame::ProcessPacketCmd(packet);
  616. packet->SeekPos(PacketBase::HeadSize);
  617. int cmd;
  618. packet->ReadValue(cmd);
  619. switch(cmd)
  620. {
  621. case CMD_BeLord:
  622. {
  623. int turn = 0;
  624. packet->ReadValue(turn);
  625. DecideLord(turn);
  626. }
  627. break;
  628. case CMD_NotBeLord:
  629. {
  630. int turn = 0;
  631. packet->ReadValue(turn);
  632. m_turn = turn;
  633. NextTurn();
  634. char sound[256];
  635. sprintf(sound,"data/sound/poker/call_bujiao");
  636. if (m_turn%2) //
  637. strcat(sound,"_femail.wav");
  638. else
  639. strcat(sound,".wav");
  640. m_myRolePlayer->m_sound->PlaySound__(sound);
  641. }
  642. break;
  643. case CMD_Pass:
  644. {
  645. int turn = 0;
  646. packet->ReadValue(turn);
  647. m_turn = turn;
  648. m_players[m_turn]->m_notOut = true;
  649. NextTurn();
  650. char sound[256];
  651. sprintf(sound,"data/sound/poker/play_guo_%d",Rand()%2);
  652. if (m_turn%2) //
  653. strcat(sound,"_femail.wav");
  654. else
  655. strcat(sound,".wav");
  656. m_players[m_turn]->m_sound->PlaySound__(sound);
  657. }
  658. break;
  659. case CMD_OutCard:
  660. {
  661. int turn = 0;
  662. packet->ReadValue(turn);
  663. packet->ReadValue(m_curOutCards);
  664. //
  665. int outNum;
  666. int cardID[MaxPlayerCard];
  667. packet->ReadValue(outNum);
  668. for(int i = 0; i < outNum; i++)
  669. {
  670. packet->ReadValue(cardID[i]);
  671. }
  672. dynamic_cast<DouDizhuPlayer*>(m_players[turn])->ClickCardsID(cardID,outNum);
  673. m_turn = turn;
  674. m_lastOutTurn = turn;
  675. m_players[turn]->m_notOut = false;
  676. OutCard(m_players[turn]);
  677. NextTurn();
  678. }
  679. break;
  680. case CMD_GameOver:
  681. {
  682. int turn = 0;
  683. packet->ReadValue(turn);
  684. m_winnerTurn = turn;
  685. m_turnTime = 0;
  686. m_gameStatus = Resulting;
  687. char sound[256];
  688. if (m_winnerTurn == m_lordTurn)
  689. {
  690. sprintf(sound,"data/sound/poker/play_lord_win");
  691. }
  692. else
  693. {
  694. sprintf(sound,"data/sound/poker/play_farmer_win");
  695. }
  696. if (m_winnerTurn%2) //
  697. strcat(sound,"_femail.wav");
  698. else
  699. strcat(sound,".wav");
  700. m_players[m_winnerTurn]->m_sound->PlaySound__(sound);
  701. }
  702. break;
  703. case CMD_Restart:
  704. Free();
  705. Start();
  706. break;
  707. }
  708. return 0;
  709. }

斗地主玩家派生类:

  1. //========================================================
  2. // @Date: 2016.05
  3. // @File: SourceDemoClient/Poker/PokerDouDiZhu.h
  4. // @Brief: PokerDouDiZhu
  5. // @Author: LouLei
  6. // @Email: twopointfive@163.com
  7. // @Copyright (Crapell) - All Rights Reserved
  8. //========================================================
  9. #if !defined(DouDizhuPlayer_h__)
  10. #define DouDizhuPlayer_h__
  11. #include "PokerGame.h"
  12. class DouDizhuPlayer:public PokerPlayer
  13. {
  14. public:
  15. DouDizhuPlayer();
  16. virtual bool Start();
  17. //virtual void Update();
  18. virtual void Render();
  19. virtual void SortCard(); //整牌
  20. virtual void OutCard();
  21. bool IsLord(); //是否地主
  22. bool IsMyTurn(); //是否轮到
  23. CurOutCards* g_curOutCards;
  24. };
  25. class DouDizhuPlayerRobot:public DouDizhuPlayer
  26. {
  27. public:
  28. virtual bool Start();
  29. virtual void Update();
  30. virtual void Render();
  31. bool ThinkOutCard(); //出牌
  32. void OutFirst(); //先出
  33. bool OutFollow(); //跟牌
  34. void FirstLianZi(); //出串
  35. void FirstSanZhang(); //出三张,含三带一
  36. void FirstDuiZi(); //出对子
  37. void FirstDanZhang(); //出单牌
  38. void FirstZhaDan(); //出炸弹
  39. void FirstDanJoker(); //出单大王
  40. void FirstJoker(); //出双王
  41. bool searchDanJoker(); //查找是否有单王,且为大王
  42. bool searchJoker(); //查找是否有双王
  43. bool searchZhaDan(); //查找有无炸弹
  44. bool searchSanZhang(); //查找有无三张
  45. bool searchDuiZi(); //查找有无对子
  46. bool searchDanZhang(); //查找有无单张
  47. bool searchLianZi(); //查找有无连子
  48. bool FollowLianZi(); //跟连子
  49. bool FollowSanZhang(); //跟三张
  50. bool FollowSiDai2(); //出四带二
  51. bool FollowSanDaiYi(); //出三带一
  52. bool FollowDuiZi(); //跟对子
  53. bool FollowDanZhang(); //跟单牌
  54. bool FollowZhaDan(); //跟炸弹
  55. int m_position; //标记牌位置
  56. int m_lianziLen; //顺子的长度
  57. int m_lianziLast; //顺尾
  58. };
  59. class DouDizhuPlayerRole:public DouDizhuPlayerRobot
  60. {
  61. public:
  62. DouDizhuPlayerRole();
  63. virtual bool Start();
  64. virtual void Update();
  65. virtual void Render();
  66. virtual bool TryOutCard(); //出牌
  67. void SaveOutCard(); //保存待出的牌
  68. bool sd(int temp[]); //是否三对,要求不同
  69. bool sfjdsd(); //三飞机带三对
  70. bool ld7(); //七连对
  71. bool ld6(); //六连对
  72. bool ld5(); //五连对
  73. bool fjd2d(); //飞机带2
  74. bool sfjbd(); //三飞机不带
  75. bool sfjdsg(); //三飞机带三个
  76. bool ld(int temp[]); //连对
  77. bool sd2d(); //四带二对
  78. bool ld4(); //四连对
  79. bool fjd2g(); //飞机带二个
  80. bool fjbd(); //飞机不带
  81. bool sd2g(); //三带二个
  82. bool ld3(); //三连对
  83. bool sz(int); //顺子
  84. bool sd2(); //四带二
  85. bool zd(); //炸弹
  86. bool sd1(); //三带一
  87. bool sgbd(); //三个不带
  88. bool sw(); //双王
  89. bool dz(); //对子
  90. ToOutCardsDouDizhu* m_toOutCard; //准备要出的牌
  91. //int m_clickedNum; //点击待出的牌数
  92. };
  93. #endif
  94. //========================================================
  95. // @Date: 2016.05
  96. // @File: SourceDemoClient/Poker/PokerDouDiZhu.cpp
  97. // @Brief: PokerDouDiZhu
  98. // @Author: LouLei
  99. // @Email: twopointfive@163.com
  100. // @Copyright (Crapell) - All Rights Reserved
  101. //========================================================
  102. #include "General/Pch.h"
  103. #include "General/Timer.h"
  104. #include "General/Window.h"
  105. #include "Input/InputMgr.h"
  106. #include "Render/RendDriver.h"
  107. #include "Poker/PokerDoudizhu.h"
  108. #include "Poker/PokerGame.h"
  109. #include "Poker/DouDiZhuPlayer.h"
  110. #include "Poker/MiniGamePoker.h"
  111. #include "Packet/PacketMiniGame.h"
  112. #include "Sound/ChannelSound.h"
  113. #include "Rpg/MiniGame.h"
  114. #include "Gui/GuiMgr.h"
  115. #include "Gui/GuiControlMisc.h"
  116. #include "General/Pce.h"
  117. //DouDizhuPlayer析构的时候报告过heap corruption detected:after normal block(#xxx) at 0x xxxxxxxx
  118. //原因:DouDizhuPlayer* p = new DouDizhuPlayer; ((DouDizhuPlayerRobot*)p)->m_toOutCard = ; 错误的静态强制转换会导致堆栈溢出。
  119. DouDizhuPlayer::DouDizhuPlayer()
  120. {
  121. }
  122. bool DouDizhuPlayer::Start()
  123. {
  124. PokerPlayer::Start();
  125. m_notOut = 0;
  126. m_workingWithAI = false;
  127. return true;
  128. }
  129. void DouDizhuPlayer::Render()
  130. {
  131. PokerPlayer::Render();
  132. int CardHeight=m_game->CardHeight;
  133. int CardWidth=m_game->CardWidth;
  134. Texture* texture;
  135. //switch()
  136. if(m_game->m_gameStatus == Playing
  137. &&IsLord())
  138. {
  139. //显示地主标志
  140. texture = G_PokerDouDiZhu->m_lordTexture;
  141. texture->Bind();
  142. if(m_screenPos == SP_Down)
  143. {
  144. G_RendDriver->DrawTextureRect(vec2(Board2DCen.x - texture->GetWidth()/2, G_PokerGame->BoardRect2D.GetBottom()-RenderUpDownSpace));
  145. }
  146. else if(m_screenPos == SP_Right)
  147. {
  148. G_RendDriver->DrawTextureRect(vec2(G_PokerGame->BoardRect2D.GetRight()-RenderLeftRightSpace, Board2DCen.y - texture->GetHeight()));
  149. }
  150. else if(m_screenPos == SP_Left)
  151. {
  152. G_RendDriver->DrawTextureRect(vec2(G_PokerGame->BoardRect2D.x+RenderLeftRightSpace-texture->GetWidth(), Board2DCen.y - texture->GetHeight()));
  153. }
  154. }
  155. //显示不出状态
  156. if(m_notOut == 1)
  157. {
  158. int index = int(G_Timer->GetAccumTime()/10)%4;
  159. texture = m_game->m_passTexture[index];
  160. texture->Bind();
  161. if(m_screenPos == SP_Down)
  162. {
  163. int posY = G_PokerGame->BoardRect2D.GetBottom()-RenderUpDownSpace - CardHeight * 2;
  164. G_RendDriver->DrawTextureRect(vec2(Board2DCen.x , posY));
  165. }
  166. else if(m_screenPos == SP_Left)
  167. {
  168. G_RendDriver->DrawTextureRect(vec2(G_PokerGame->BoardRect2D.x+RenderLeftRightSpace+CardWidth*1.8f, Board2DCen.y - texture->GetHeight()));
  169. }
  170. else if(m_screenPos == SP_Right)
  171. {
  172. G_RendDriver->DrawTextureRect(vec2(G_PokerGame->BoardRect2D.GetRight()-RenderLeftRightSpace-CardWidth*2.8f, Board2DCen.y - texture->GetHeight()));
  173. }
  174. }
  175. //显示思考中
  176. if((m_game->m_gameStatus==Playing||m_game->m_gameStatus==Preparing)
  177. &&IsMyTurn())
  178. {
  179. //m_ctrlThink->SetVisible(true);
  180. int index = int(G_Timer->GetAccumTime()*10)%4;
  181. texture = m_game->m_thinkTexture[index];
  182. texture->Bind();
  183. if(m_screenPos == SP_Down)
  184. {
  185. G_RendDriver->DrawTextureRect(vec2(Board2DCen.x + 100 , G_PokerGame->BoardRect2D.GetBottom()-RenderUpDownSpace-CardHeight-texture->GetHeight()));
  186. }
  187. else if(m_screenPos == SP_Left)
  188. {
  189. G_RendDriver->DrawTextureRect(vec2(G_PokerGame->BoardRect2D.x+RenderLeftRightSpace+CardWidth, Board2DCen.y));
  190. }
  191. else if(m_screenPos == SP_Right)
  192. {
  193. G_RendDriver->DrawTextureRect(vec2(G_PokerGame->BoardRect2D.GetRight()-RenderLeftRightSpace-CardWidth-texture->GetWidth(), Board2DCen.y));
  194. }
  195. }
  196. //显示叫地主按钮
  197. if(G_PokerDouDiZhu->m_gameStatus == Preparing)
  198. {
  199. //显示叫地主按钮
  200. int posX;
  201. if(IsMyTurn())
  202. {
  203. if(m_screenPos == SP_Down)
  204. {
  205. G_PokerDouDiZhu->m_sanfenButtonTexture->Bind();
  206. G_RendDriver->DrawTextureRect(vec2(Board2DCen.x - 80, G_PokerGame->BoardRect2D.GetBottom()-RenderUpDownSpace-CardHeight-32));
  207. G_PokerDouDiZhu->m_notbeLordButtonTexture->Bind();
  208. G_RendDriver->DrawTextureRect(vec2(Board2DCen.x + 20, G_PokerGame->BoardRect2D.GetBottom()-RenderUpDownSpace-CardHeight-32));
  209. }
  210. else if(m_screenPos == SP_Left)
  211. {
  212. posX = G_PokerGame->BoardRect2D.x+RenderLeftRightSpace + CardWidth*1.8f;
  213. G_PokerDouDiZhu->m_sanfenButtonTexture->Bind();
  214. G_RendDriver->DrawTextureRect(vec2(posX, Board2DCen.y - 80));
  215. G_PokerDouDiZhu->m_notbeLordButtonTexture->Bind();
  216. G_RendDriver->DrawTextureRect(vec2(posX, Board2DCen.y + 20));
  217. }
  218. else if(m_screenPos == SP_Right)
  219. {
  220. posX = G_PokerGame->BoardRect2D.GetRight() - RenderLeftRightSpace - CardWidth*2.8f;
  221. G_PokerDouDiZhu->m_sanfenButtonTexture->Bind();
  222. G_RendDriver->DrawTextureRect(vec2(posX, Board2DCen.y - 80));
  223. G_PokerDouDiZhu->m_notbeLordButtonTexture->Bind();
  224. G_RendDriver->DrawTextureRect(vec2(posX, Board2DCen.y + 20));
  225. }
  226. }
  227. else
  228. {
  229. //显示叫地主状态
  230. if(m_screenPos == SP_Down)
  231. {
  232. G_PokerDouDiZhu->m_notbeLordTexture->Bind();
  233. int posY = G_PokerGame->BoardRect2D.GetBottom()-RenderUpDownSpace - CardHeight * 2;
  234. G_RendDriver->DrawTextureRect(vec2(Board2DCen.x, posY));
  235. }
  236. else if(m_screenPos == SP_Left)
  237. {
  238. posX = G_PokerGame->BoardRect2D.x+RenderLeftRightSpace + CardWidth*1.8f;
  239. G_PokerDouDiZhu->m_notbeLordTexture->Bind();
  240. G_RendDriver->DrawTextureRect(vec2(posX, Board2DCen.y + 20));
  241. }
  242. else if(m_screenPos == SP_Right)
  243. {
  244. posX = G_PokerGame->BoardRect2D.GetRight() - RenderLeftRightSpace - CardWidth*2.8f;
  245. G_PokerDouDiZhu->m_notbeLordTexture->Bind();
  246. G_RendDriver->DrawTextureRect(vec2(posX, Board2DCen.y + 20));
  247. }
  248. }
  249. }
  250. }
  251. void DouDizhuPlayer::SortCard()
  252. {
  253. int i, j;
  254. int idi, idj;
  255. Card card;
  256. for(i = 0 ; i < m_cardNum ; i++)
  257. {
  258. for(j = i ; j < m_cardNum ; j++)
  259. {
  260. idi = m_cards[i].cardValue;
  261. idj = m_cards[j].cardValue;
  262. if(idj > idi
  263. ||((idi == idj) && (m_cards[j].Color() > m_cards[i].Color()))
  264. )
  265. {
  266. card = m_cards[j];
  267. m_cards[j] = m_cards[i];
  268. m_cards[i] = card;
  269. }
  270. }
  271. }
  272. }
  273. bool DouDizhuPlayer::IsLord()
  274. {
  275. return G_PokerDouDiZhu->m_lordTurn == m_turn;
  276. }
  277. bool DouDizhuPlayer::IsMyTurn()
  278. {
  279. return G_PokerDouDiZhu->m_turn == m_turn;
  280. }
  281. void DouDizhuPlayer::OutCard()
  282. {
  283. PokerPlayer::OutCard();
  284. if(m_bBaoPai==false
  285. &&m_cardNum <=2)
  286. {
  287. char sound[256];
  288. if(m_cardNum == 1)
  289. {
  290. sprintf(sound,"data/sound/poker/play_bao1");
  291. }
  292. if(m_cardNum == 2)
  293. {
  294. sprintf(sound,"data/sound/poker/play_bao2");
  295. }
  296. if (m_turn%2) //
  297. strcat(sound,"_femail.wav");
  298. else
  299. strcat(sound,".wav");
  300. m_sound->PlaySound__(sound);
  301. m_bBaoPai = true;
  302. return;
  303. }
  304. char sound[256];
  305. switch (g_curOutCards->type)
  306. {
  307. case GZ:
  308. sprintf(sound,"data/sound/poker/one_poker_%d",g_curOutCards->value-PokerDouDiZhu::Value3);
  309. break;
  310. case DZ:
  311. sprintf(sound,"data/sound/poker/two_poker_%d",g_curOutCards->value-PokerDouDiZhu::Value3);
  312. break;
  313. case SGBD:
  314. sprintf(sound,"data/sound/poker/play_3zhang");
  315. break;
  316. case SD1:
  317. sprintf(sound,"data/sound/poker/play_3dai1");
  318. break;
  319. case SD2:
  320. sprintf(sound,"data/sound/poker/play_3dai2");
  321. break;
  322. case SD2G:
  323. case SD2D:
  324. sprintf(sound,"data/sound/poker/play_4dai2");
  325. break;
  326. case SZ:
  327. sprintf(sound,"data/sound/poker/play_shun");
  328. break;
  329. case LD3:
  330. sprintf(sound,"data/sound/poker/play_sandui");
  331. break;
  332. case LD4:
  333. case LD5:
  334. case LD6:
  335. case LD7:
  336. sprintf(sound,"data/sound/poker/play_liandui");
  337. break;
  338. case FJBD:
  339. case FJD2G:
  340. case FJD2D:
  341. case SFJBD:
  342. case SFJDSG:
  343. case SFJDSD:
  344. sprintf(sound,"data/sound/poker/play_feiji");
  345. break;
  346. case ZD:
  347. sprintf(sound,"data/sound/poker/play_zhadan_%d",Rand()%3);
  348. break;
  349. case SW:
  350. sprintf(sound,"data/sound/poker/play_wangzha");
  351. break;
  352. default:
  353. sprintf(sound,"data/sound/poker/play_dani");
  354. break;
  355. }
  356. if (m_turn%2) //
  357. {
  358. strcat(sound,"_femail.wav");
  359. }
  360. else
  361. {
  362. strcat(sound,".wav");
  363. }
  364. m_sound->PlaySound__(sound);
  365. //播放出牌动作 todo 装备扑克道具
  366. if(m_movieCtrl)
  367. {
  368. String name = m_movieCtrl->GetRenderCharacterUI()->GetCurAnimName();
  369. if(name == "stand")
  370. m_movieCtrl->GetRenderCharacterUI()->PlayAnim("attack");
  371. else
  372. m_movieCtrl->GetRenderCharacterUI()->PlayAnim("stand");
  373. }
  374. //todo call back 播一次结束后恢复站位
  375. }
  376. bool DouDizhuPlayerRobot::Start()
  377. {
  378. DouDizhuPlayer::Start();
  379. m_workingWithAI = true;
  380. return true;
  381. }
  382. void DouDizhuPlayerRobot::Update()
  383. {
  384. PokerPlayer::Update();
  385. //if (m_bAI == true)
  386. if (m_game->m_turn == m_turn
  387. && m_game->m_turnTime>1.0f //思考时间
  388. )
  389. {
  390. switch(m_game->m_gameStatus)
  391. {
  392. case Preparing:
  393. {
  394. int cardNum = 0;
  395. for(int i = 0; i < m_cardNum; i++)
  396. {
  397. if(m_cards[i].cardValue > PokerDouDiZhu::ValueA)
  398. {
  399. cardNum++;
  400. }
  401. }
  402. //有两张大牌,叫地主
  403. if(cardNum >= 2)
  404. {
  405. G_PokerDouDiZhu->SendDecideLord(m_turn);
  406. G_PokerDouDiZhu->DecideLord(m_turn);
  407. return;
  408. }
  409. else
  410. {
  411. //真实玩家都不叫
  412. if(Rand()%4==0)
  413. {
  414. G_PokerDouDiZhu->SendDecideLord(m_turn);
  415. G_PokerDouDiZhu->DecideLord(m_turn);
  416. }
  417. return;
  418. }
  419. m_game->NextTurn();
  420. C2SPacketMiniGameCmd packet;
  421. packet.WriteHeader();
  422. packet.WriteValue(CMD_NotBeLord);
  423. packet.WriteValue(m_turn);
  424. G_MiniGame->SendPacketToOther(&packet);
  425. char sound[256];
  426. sprintf(sound,"data/sound/poker/call_bujiao");
  427. if (m_turn%2) //
  428. strcat(sound,"_femail.wav");
  429. else
  430. strcat(sound,".wav");
  431. m_sound->PlaySound__(sound);
  432. }
  433. break;
  434. case Playing:
  435. {
  436. ThinkOutCard();
  437. if(m_notOut==false)
  438. {
  439. //out
  440. m_game->OutCard(this);
  441. //if (m_game->CheckRoundEnd()==false)
  442. {
  443. C2SPacketMiniGameCmd packet;
  444. packet.WriteHeader();
  445. packet.WriteValue(CMD_OutCard);
  446. packet.WriteValue(m_turn);
  447. packet.WriteValue(*g_curOutCards);
  448. //
  449. packet.WriteValue(m_outNum);
  450. for(int i = MaxPlayerCard - m_outNum; i < MaxPlayerCard; i++)
  451. {
  452. packet.WriteValue(m_cards[i].cardID);
  453. }
  454. G_MiniGame->SendPacketToOther(&packet);
  455. m_game->m_lastOutTurn = m_turn;
  456. m_game->NextTurn();
  457. }
  458. }
  459. else
  460. {
  461. //pass
  462. C2SPacketMiniGameCmd packet;
  463. packet.WriteHeader();
  464. packet.WriteValue(CMD_Pass);
  465. packet.WriteValue(m_turn);
  466. G_MiniGame->SendPacketToOther(&packet);
  467. m_game->NextTurn();
  468. char sound[256];
  469. sprintf(sound,"data/sound/poker/play_guo_%d",Rand()%2);
  470. if (m_turn%2) //
  471. strcat(sound,"_femail.wav");
  472. else
  473. strcat(sound,".wav");
  474. m_sound->PlaySound__(sound);
  475. }
  476. }
  477. break;
  478. }
  479. }
  480. }
  481. void DouDizhuPlayerRobot::Render()
  482. {
  483. DouDizhuPlayer::Render();
  484. }
  485. bool DouDizhuPlayerRobot::ThinkOutCard()
  486. {
  487. int LastOutTurn = G_PokerDouDiZhu->m_lastOutTurn;
  488. m_notOut = 1;
  489. AnalyseCard();
  490. if(LastOutTurn == m_turn)
  491. {
  492. OutFirst();
  493. m_notOut = 0;
  494. }
  495. else
  496. {
  497. int before = (m_turn + 2) % 3;
  498. int after = (m_turn + 1) % 3;
  499. bool tryFollow = false;//要不要出牌
  500. if(IsLord())
  501. {
  502. //自己是地主
  503. tryFollow = true;
  504. }
  505. else if(LastOutTurn == G_PokerDouDiZhu->m_lordTurn)
  506. {
  507. //地主出的牌
  508. tryFollow = true;
  509. }
  510. else
  511. {
  512. //非地主出的牌
  513. if(g_curOutCards->num==m_cardNum)//出牌可以赢 出完
  514. {
  515. tryFollow = true;
  516. }
  517. else if(m_cardNum <= 2) //手里只有12张牌,快赢了
  518. {
  519. tryFollow = true;
  520. }
  521. else if(g_curOutCards->type == GZ && g_curOutCards->value <10) //出牌太小
  522. {
  523. tryFollow = true;
  524. }
  525. else if(g_curOutCards->type == DZ && g_curOutCards->value < 8) //出牌太小
  526. {
  527. tryFollow = true;
  528. }
  529. }
  530. if (tryFollow)
  531. {
  532. //是否划算:拆牌 王打三
  533. if(OutFollow())//能不能出牌
  534. m_notOut = 0;
  535. }
  536. }
  537. return true;
  538. }
  539. //先出算法
  540. void DouDizhuPlayerRobot::OutFirst()
  541. {
  542. //很少出4张,留着炸弹用
  543. //连子能找出飞机来?
  544. //先出得分最小的牌 可以被带的除外
  545. //出连子 连子太大也可以先不出 连到2 也可以只出一半
  546. if(searchLianZi())
  547. {
  548. FirstLianZi();
  549. return;
  550. }
  551. //出 单张 对子 三张中的较小者 单张数少的话考虑带
  552. OutType bestType = None;
  553. int bestValue = 999;
  554. //单张
  555. if(searchDanZhang())
  556. {
  557. if (m_position<bestValue)
  558. {
  559. bestType = GZ;
  560. bestValue = m_position;
  561. }
  562. }
  563. //对子
  564. if(searchDuiZi())
  565. {
  566. if (m_position<bestValue)
  567. {
  568. bestType = DZ;
  569. bestValue = m_position;
  570. }
  571. }
  572. //三张
  573. if(searchSanZhang())
  574. {
  575. if (m_position<bestValue)
  576. {
  577. bestType = SGBD;
  578. bestValue = m_position;
  579. }
  580. }
  581. //恢复
  582. m_position = bestValue;
  583. //出单张
  584. if(bestType == GZ)
  585. {
  586. FirstDanZhang();
  587. return;
  588. }
  589. //出对子
  590. if(bestType == DZ)
  591. {
  592. FirstDuiZi();
  593. return;
  594. }
  595. //出三张
  596. if(bestType == SGBD)
  597. {
  598. FirstSanZhang(); //会带
  599. return;
  600. }
  601. //出炸弹
  602. if(searchZhaDan())
  603. {
  604. FirstZhaDan();
  605. return;
  606. }
  607. //出双王
  608. if(searchJoker())
  609. {
  610. FirstJoker();
  611. return;
  612. }
  613. //出单王
  614. if(searchDanJoker())
  615. {
  616. FirstDanJoker();
  617. return;
  618. }
  619. else
  620. {}
  621. }
  622. //跟牌算法
  623. bool DouDizhuPlayerRobot::OutFollow()
  624. {
  625. if(g_curOutCards->type == GZ) //单张
  626. {
  627. if(FollowDanZhang())
  628. return true;
  629. else
  630. {
  631. if(searchDanJoker()) //有王出之
  632. {
  633. FirstDanJoker();
  634. return true;
  635. }
  636. if(searchZhaDan()) //有炸弹出之
  637. {
  638. FirstZhaDan();
  639. return true;
  640. }
  641. }
  642. }
  643. else if(g_curOutCards->type == DZ) //对子
  644. {
  645. if(FollowDuiZi())
  646. return true;
  647. else
  648. {
  649. if(searchZhaDan()) //有炸弹出之
  650. {
  651. FirstZhaDan();
  652. return true;
  653. }
  654. else
  655. {
  656. if(searchJoker())//有双王出之
  657. {
  658. FirstJoker();
  659. return true;
  660. }
  661. }
  662. }
  663. }
  664. else if(g_curOutCards->type == SGBD) //三张
  665. {
  666. if(FollowSanZhang())
  667. return true;
  668. else
  669. {
  670. if(searchZhaDan()) //有炸弹出之
  671. {
  672. FirstZhaDan();
  673. return true;
  674. }
  675. else if(searchJoker()) //有双王出之
  676. {
  677. FirstJoker();
  678. return true;
  679. }
  680. }
  681. }
  682. else if(g_curOutCards->type == SD1) //三带一
  683. {
  684. if(FollowSanDaiYi())
  685. return true;
  686. else
  687. {
  688. if(searchZhaDan()) //有炸弹出之
  689. {
  690. FirstZhaDan();
  691. return true;
  692. }
  693. else if(searchJoker()) //有双王出之
  694. {
  695. FirstJoker();
  696. return true;
  697. }
  698. }
  699. }
  700. else if(g_curOutCards->type == SZ) //连子
  701. {
  702. if(FollowLianZi())
  703. return true;
  704. else
  705. {
  706. if(searchZhaDan()) //有炸弹出之
  707. {
  708. FirstZhaDan();
  709. return true;
  710. }
  711. else if(searchJoker()) //有双王出之
  712. {
  713. FirstJoker();
  714. return true;
  715. };
  716. }
  717. }
  718. else if(g_curOutCards->type == SD2G) //四带二
  719. {
  720. if(FollowSiDai2())
  721. return true;
  722. else
  723. {
  724. if(searchZhaDan()) //有炸弹出之
  725. {
  726. FirstZhaDan();
  727. return true;
  728. }
  729. else if(searchJoker()) //有双王出之
  730. {
  731. FirstJoker();
  732. return true;
  733. }
  734. }
  735. }
  736. else if(g_curOutCards->type == ZD) //炸弹
  737. {
  738. if(FollowZhaDan())
  739. return true;
  740. else
  741. {
  742. if(searchJoker())//有双王出之
  743. {
  744. FirstJoker();
  745. return true;
  746. }
  747. }
  748. }
  749. return false;
  750. }
  751. //出连子
  752. void DouDizhuPlayerRobot::FirstLianZi()
  753. {
  754. int start = m_lianziLast - m_lianziLen; //连子开始组号
  755. int a1[12] = {0};
  756. int i = 0;
  757. for( i = 0; start < m_lianziLast + 1; start++, i++)
  758. {
  759. a1[i] = start;
  760. }
  761. for(int j = 0; j < i + 1; j++)//改牌的状态为出了的
  762. {
  763. for(int k = 0;k < 20;k++)
  764. {
  765. if(m_cards[k].cardValue == a1[j])
  766. {
  767. m_cards[k].bClicked = true;
  768. break;
  769. }
  770. }
  771. }
  772. g_curOutCards->value = a1[i - 1];
  773. g_curOutCards->num = i;
  774. g_curOutCards->min = a1[0];
  775. g_curOutCards->type = SZ;
  776. }
  777. //出单张
  778. void DouDizhuPlayerRobot::FirstDanZhang()
  779. {
  780. for(int k = 0; k < 20; k++)//改牌的状态为出了的
  781. {
  782. if(m_cards[k].cardValue == m_position)
  783. {
  784. m_cards[k].bClicked = 1;
  785. break;
  786. }
  787. }
  788. g_curOutCards->value = m_position;
  789. g_curOutCards->num = 1 ;
  790. g_curOutCards->type = GZ;
  791. }
  792. //出对子
  793. void DouDizhuPlayerRobot::FirstDuiZi()
  794. {
  795. int n = 0;
  796. for(int k = 0; k < 20; k++)//改牌的状态为出了的
  797. {
  798. if(m_cards[k].cardValue == m_position)
  799. {
  800. m_cards[k].bClicked = true;
  801. n++;
  802. if(n >= 2)
  803. break;
  804. }
  805. }
  806. g_curOutCards->value = m_position;
  807. g_curOutCards->num = 2;
  808. g_curOutCards->type = DZ;
  809. }
  810. //出三张
  811. void DouDizhuPlayerRobot::FirstSanZhang()
  812. {
  813. int i = m_position;
  814. assert(ValueCount[i] == 3);
  815. int j = 0;
  816. int bt = 0;
  817. while(!bt)
  818. {
  819. if(ValueCount[j] == 1 && j != i)
  820. {
  821. int a1[4] = {0};
  822. a1[0] = i;
  823. a1[1] = i;
  824. a1[2] = i;
  825. a1[3] = j;
  826. bt = 1;
  827. g_curOutCards->value = a1[0];
  828. g_curOutCards->num = 4;
  829. g_curOutCards->type = SD1;
  830. ClickCards(a1,g_curOutCards->num);
  831. return;
  832. }
  833. else
  834. {
  835. j++;
  836. if(j>12)
  837. {
  838. int a1[3] = {0};
  839. a1[0] = i;
  840. a1[1] = i;
  841. a1[2] = i;
  842. g_curOutCards->value = a1[0];
  843. g_curOutCards->num = 3;
  844. g_curOutCards->type = SGBD;
  845. ClickCards(a1,g_curOutCards->num);
  846. return;
  847. }
  848. }
  849. }
  850. }
  851. //出炸弹
  852. void DouDizhuPlayerRobot::FirstZhaDan()
  853. {
  854. int n = 0;
  855. for(int k = 0; k < 20; k++)//改牌的状态为出了
  856. {
  857. if(m_cards[k].cardValue == m_position)
  858. {
  859. m_cards[k].bClicked = true;
  860. n++;
  861. if(n >= 4)
  862. break;
  863. }
  864. }
  865. g_curOutCards->value = m_position;
  866. g_curOutCards->num = 4;
  867. g_curOutCards->type = ZD;
  868. }
  869. //出双王
  870. void DouDizhuPlayerRobot::FirstJoker()
  871. {
  872. for(int k = 0; k < 20; k++) //改牌的状态为出了的
  873. {
  874. if((m_cards[k].cardID == JokerSmall
  875. || m_cards[k].cardID == JokerBig)
  876. && m_cards[k].bClicked == false)
  877. {
  878. m_cards[k].bClicked = true;
  879. }
  880. }
  881. g_curOutCards->num = 2 ;
  882. g_curOutCards->value = 17;
  883. g_curOutCards->type = SW;
  884. }
  885. //出单大王
  886. void DouDizhuPlayerRobot::FirstDanJoker()
  887. {
  888. for(int k = 0; k < 20; k++)//改牌的状态为出了的
  889. {
  890. if(m_cards[k].cardValue == m_position)
  891. {
  892. m_cards[k].bClicked = true;
  893. break;
  894. }
  895. }
  896. g_curOutCards->value = m_position;
  897. g_curOutCards->num = 1;
  898. g_curOutCards->type = GZ;
  899. }
  900. //找单张,在顺子后找3---2
  901. bool DouDizhuPlayerRobot::searchDanZhang()
  902. {
  903. m_position = -1;
  904. if(m_cardNum < 3 && !searchJoker())
  905. {
  906. //还剩两张
  907. int j = 0, a[2] = {0};
  908. for(int i = 0; i <= PokerDouDiZhu::ValueJokerBig; i++)
  909. {
  910. if(ValueCount[i] == 1)
  911. a[j++] = i;
  912. }
  913. //第二张最大
  914. if(a[1] == G_PokerDouDiZhu->MaxCard())
  915. m_position = a[1];
  916. else
  917. m_position = a[0];
  918. }
  919. else
  920. {
  921. //从小到大找
  922. for(int i = 0; i < PokerDouDiZhu::ValueJokerSmall; i++)
  923. {
  924. if(ValueCount[i] == 1)
  925. {
  926. m_position = i;
  927. break;
  928. }
  929. }
  930. }
  931. if(m_position != -1)
  932. return true;
  933. else
  934. return false;
  935. }
  936. //找对子
  937. bool DouDizhuPlayerRobot::searchDuiZi()
  938. {
  939. m_position = -1;
  940. for(int i = 0; i < PokerDouDiZhu::ValueJokerSmall; i++)
  941. {
  942. if(ValueCount[i] == 2)
  943. {
  944. m_position = i;
  945. break;
  946. }
  947. }
  948. if(m_position != -1)
  949. return true;
  950. else
  951. return false;
  952. }
  953. //找三张
  954. bool DouDizhuPlayerRobot::searchSanZhang()
  955. {
  956. m_position = -1;
  957. for(int i = 0; i < PokerDouDiZhu::Value2; i++)
  958. {
  959. if(ValueCount[i] == 3)
  960. {
  961. m_position = i;
  962. break;
  963. }
  964. }
  965. if(m_position != -1)
  966. return true;
  967. return false;
  968. }
  969. //找炸弹
  970. bool DouDizhuPlayerRobot::searchZhaDan()
  971. {
  972. m_position = -1;
  973. for(int i = 0; i < PokerDouDiZhu::ValueJokerSmall; i++)
  974. {
  975. if(ValueCount[i] == 4)
  976. {
  977. m_position = i;
  978. break;
  979. }
  980. }
  981. if(m_position != -1)
  982. return true;
  983. return false;
  984. }
  985. //找双王
  986. bool DouDizhuPlayerRobot::searchJoker()
  987. {
  988. if(ValueCount[PokerDouDiZhu::ValueJokerBig] > 0 && ValueCount[PokerDouDiZhu::ValueJokerSmall] > 0)
  989. {
  990. return true;
  991. }
  992. return false;
  993. }
  994. //找连子
  995. bool DouDizhuPlayerRobot::searchLianZi()
  996. {
  997. int restValues[12] = {0};
  998. int maxLian = 0;
  999. m_lianziLast = -1;
  1000. m_lianziLen = 1;
  1001. for(int i = 0; i < PokerDouDiZhu::ValueQ; i++) //最大J可以连子
  1002. {
  1003. if(ValueCount[i] > 0)
  1004. restValues[maxLian++] = i; //连续存放还有的牌value-3value不再连续
  1005. }
  1006. //不会找出三连对,play时只会抽出一张
  1007. for(int i = 0; i < maxLian - 1; i++)
  1008. {
  1009. if(restValues[i+1] == restValues[i]+1
  1010. && restValues[i]+1 < PokerDouDiZhu::Value2)
  1011. {
  1012. m_lianziLen++;
  1013. if(m_lianziLen >= 5)
  1014. m_lianziLast = restValues[i] + 1;
  1015. //能连一直继续
  1016. continue;
  1017. }
  1018. //不能继续连了
  1019. if(m_lianziLen < 5)
  1020. {
  1021. //打断连子,重新计数,继续
  1022. m_lianziLen = 1;
  1023. m_lianziLast = -1;
  1024. }
  1025. else
  1026. {
  1027. //已经找好
  1028. return true;
  1029. }
  1030. }
  1031. if(m_lianziLen < 5)
  1032. return false;
  1033. return true;
  1034. }
  1035. //找单大王
  1036. bool DouDizhuPlayerRobot::searchDanJoker()
  1037. {
  1038. if(ValueCount[PokerDouDiZhu::ValueJokerBig] > 0 && ValueCount[PokerDouDiZhu::ValueJokerSmall] == 0)
  1039. {
  1040. m_position = PokerDouDiZhu::ValueJokerBig;
  1041. return true;
  1042. }
  1043. return false;
  1044. }
  1045. //跟单张牌的情况
  1046. bool DouDizhuPlayerRobot::FollowDanZhang()
  1047. {
  1048. //对手连出 或对手牌很少 拆牌必要性加大
  1049. for(int i = g_curOutCards->value+1; i <= PokerDouDiZhu::ValueJokerBig ; i++)
  1050. {
  1051. if(ValueCount[i] == 1
  1052. || (ValueCount[i] > 1 && i == PokerDouDiZhu::Value2) //多个2可拆
  1053. //|| //地主牌仅剩1
  1054. //|| 上家是地主 或自己是地主 上家一直破单张作弊
  1055. )
  1056. {
  1057. int a1[1] = {0};
  1058. a1[0] = i;
  1059. ClickCards(a1,g_curOutCards->num); //出牌后对玩家手中的牌进行相应清理
  1060. g_curOutCards->value = a1[0];
  1061. g_curOutCards->num = 1 ;
  1062. g_curOutCards->type = GZ;
  1063. return true;
  1064. }
  1065. }
  1066. return false;
  1067. }
  1068. //跟对子
  1069. bool DouDizhuPlayerRobot::FollowDuiZi()
  1070. {
  1071. //不同时期 剩余牌数不同 评分标准也不同
  1072. //对手连出 或对手牌很少 拆牌必要性加大
  1073. for(int i = g_curOutCards->value+1; i <= PokerDouDiZhu::Value2; i++)
  1074. {
  1075. if(ValueCount[i]==2
  1076. || (ValueCount[i] > 2 && i == PokerDouDiZhu::Value2) //多个2可拆
  1077. //|| (ValueCount[i] > 2 && i>= PokerDouDiZhu::ValueA) //多个>A可拆 对2没有时再拆A
  1078. //|| //地主牌仅剩2
  1079. )
  1080. {
  1081. int a1[2] = {0};
  1082. a1[0] = i;
  1083. a1[1] = i;
  1084. ClickCards(a1,g_curOutCards->num); //出牌后对玩家手中的牌进行相应清理
  1085. g_curOutCards->value = a1[0] ;
  1086. g_curOutCards->num = 2;
  1087. g_curOutCards->type = DZ;
  1088. return 1;
  1089. }
  1090. }
  1091. return 0;
  1092. }
  1093. //跟三张
  1094. bool DouDizhuPlayerRobot::FollowSanZhang()
  1095. {
  1096. for(int i = g_curOutCards->value+1; i <= PokerDouDiZhu::Value2; i++)
  1097. {
  1098. if(ValueCount[i] == 3)
  1099. {
  1100. int a1[3] = {0};
  1101. a1[0] = i;
  1102. a1[1] = i;
  1103. a1[2] = i;
  1104. ClickCards(a1,g_curOutCards->num);
  1105. g_curOutCards->value = a1[0];
  1106. g_curOutCards->num = 3;
  1107. g_curOutCards->type = SGBD;
  1108. return true;
  1109. }
  1110. }
  1111. return false;
  1112. }
  1113. //跟连子
  1114. bool DouDizhuPlayerRobot::FollowLianZi()
  1115. {
  1116. int lens = 1;
  1117. int end = 0;
  1118. for(int i = g_curOutCards->value+1; i < PokerDouDiZhu::ValueQ && lens < g_curOutCards->num; i++)
  1119. {
  1120. for(int j = 0; j < g_curOutCards->num; j++, i++)
  1121. if(ValueCount[i] > 0)
  1122. {
  1123. lens++;
  1124. if(j == g_curOutCards->num - 1)
  1125. end = i;
  1126. }
  1127. else
  1128. {
  1129. lens = 1;
  1130. break;
  1131. }
  1132. }
  1133. //找到匹配的连子
  1134. if(lens == g_curOutCards->num)
  1135. {
  1136. int start = -1;
  1137. start = end - g_curOutCards->num + 1; //连子开始组号
  1138. int a1[12] = {0};
  1139. int i = 0;
  1140. for( i = 0; i < g_curOutCards->num; i++)
  1141. a1[i] = start++;
  1142. ClickCards(a1,g_curOutCards->num);
  1143. g_curOutCards->value = a1[i];
  1144. g_curOutCards->min = a1[0];
  1145. g_curOutCards->num = i - 1;
  1146. g_curOutCards->type = SZ;
  1147. return true;
  1148. }
  1149. //未找到匹配的连子
  1150. else
  1151. return false;
  1152. }
  1153. //四带二只能带对子
  1154. bool DouDizhuPlayerRobot::FollowSiDai2()
  1155. {
  1156. //42 不用作带牌?todo更智能的判断
  1157. for(int i = g_curOutCards->value+1; i < PokerDouDiZhu::Value2; i++)
  1158. {
  1159. if(ValueCount[i] == 4)
  1160. {
  1161. int j = 0;
  1162. int bt = 0;
  1163. while(!bt)
  1164. {
  1165. if(ValueCount[j] == 2)
  1166. {
  1167. int a1[8] = {0};
  1168. int ans = i;
  1169. for(int k = 0; k < 4; k++)
  1170. a1[k] = ans++;
  1171. a1[4] = j;
  1172. a1[5] = j + 1;
  1173. ClickCards(a1,g_curOutCards->num);
  1174. bt = 1;
  1175. g_curOutCards->value = a1[0];
  1176. g_curOutCards->num = 8;
  1177. g_curOutCards->type = SD2G;
  1178. return true;
  1179. }
  1180. else
  1181. {
  1182. j++;
  1183. if(j > 12)
  1184. {
  1185. bt = 1;
  1186. return false;
  1187. }
  1188. }
  1189. }
  1190. }
  1191. }
  1192. return false;
  1193. }
  1194. //用炸弹炸掉
  1195. bool DouDizhuPlayerRobot::FollowZhaDan()
  1196. {
  1197. //42 用作炸弹?
  1198. for(int i = g_curOutCards->value+1; i <= PokerDouDiZhu::Value2; i++)
  1199. {
  1200. if(ValueCount[i] == 4)
  1201. {
  1202. int a1[4] = {0};
  1203. int ans = i;
  1204. for(int k = 0; k < 4; k++)
  1205. a1[k] = ans++;
  1206. ClickCards(a1,g_curOutCards->num);
  1207. g_curOutCards->value = a1[0];
  1208. g_curOutCards->num = 4;
  1209. g_curOutCards->type = ZD;
  1210. return true;
  1211. }
  1212. }
  1213. return false;
  1214. }
  1215. //出三带一
  1216. bool DouDizhuPlayerRobot::FollowSanDaiYi()
  1217. {
  1218. for(int i = g_curOutCards->value+1; i < PokerDouDiZhu::Value2; i++)
  1219. {
  1220. if(ValueCount[i] == 3)
  1221. {
  1222. int j = 0;
  1223. int bt = 0;
  1224. while(!bt)
  1225. {
  1226. if(ValueCount[j] == 1 && j != i)
  1227. {
  1228. int a1[4] = {0};
  1229. a1[0] = i;
  1230. a1[1] = i;
  1231. a1[2] = i;
  1232. a1[3] = j;
  1233. bt = 1;
  1234. g_curOutCards->value = a1[0];
  1235. g_curOutCards->num = 4;
  1236. g_curOutCards->type = SD1;
  1237. ClickCards(a1,g_curOutCards->num);
  1238. return true;
  1239. }
  1240. else
  1241. {
  1242. j++;
  1243. if(j > 12)
  1244. return false;
  1245. }
  1246. }
  1247. }
  1248. }
  1249. return false;
  1250. }
  1251. DouDizhuPlayerRole::DouDizhuPlayerRole()
  1252. //:m_clickedNum(0)
  1253. {
  1254. }
  1255. bool DouDizhuPlayerRole::Start()
  1256. {
  1257. DouDizhuPlayerRobot::Start();
  1258. m_workingWithAI = false;
  1259. return true;
  1260. }
  1261. void DouDizhuPlayerRole::Update()
  1262. {
  1263. if (m_workingWithAI == true)
  1264. {
  1265. DouDizhuPlayerRobot::Update();
  1266. }
  1267. else
  1268. {
  1269. if (m_game->m_turn == m_turn)
  1270. {
  1271. switch(m_game->m_gameStatus)
  1272. {
  1273. case Preparing:
  1274. {
  1275. //if (G_Mouse->IsButtonDowning(MOUSE_LEFT))
  1276. //{
  1277. // if(Button_BeLord()) return;
  1278. // if(Button_NotBeLord()) return;
  1279. //}
  1280. }
  1281. break;
  1282. case Playing:
  1283. {
  1284. //if (G_Mouse->IsButtonDowning(MOUSE_LEFT))
  1285. //{
  1286. // //todo set ui visible + call back
  1287. // if(Button_Pass())
  1288. // return true;
  1289. // m_myRolePlayer->ClickCard(this->GetMousePos());
  1290. //}
  1291. //if (G_Mouse->IsButtonDowning(MOUSE_RIGHT))
  1292. //{
  1293. // OnRButtonDown();
  1294. //}
  1295. if (G_PokerGame->IsButtonDowning(MOUSE_LEFT))
  1296. {
  1297. ClickCard(G_PokerGame->GetMousePos());
  1298. }
  1299. }
  1300. break;
  1301. }
  1302. }
  1303. }
  1304. }
  1305. void DouDizhuPlayerRole::Render()
  1306. {
  1307. //PokerPlayer::Render();
  1308. DouDizhuPlayerRobot::Render();
  1309. int CardHeight=m_game->CardHeight;
  1310. int CardWidth=m_game->CardWidth;
  1311. //显示不出按钮
  1312. {
  1313. if(m_game->m_turn == m_turn
  1314. && m_game->m_lastOutTurn != m_turn
  1315. && m_game->m_gameStatus == Playing)
  1316. {
  1317. m_game->m_passButtonTexture->Bind();
  1318. G_RendDriver->DrawTextureRect(vec2(Board2DCen.x - 30, G_PokerGame->BoardRect2D.GetBottom()-RenderUpDownSpace-CardHeight-32));
  1319. }
  1320. }
  1321. //if(m_game->m_gameStatus == Playing
  1322. // &&IsLord())
  1323. //{
  1324. // //显示地主
  1325. // G_PokerDouDiZhu->m_isLordTexture->Bind();
  1326. // if(m_screenPos == SP_Down)
  1327. // {
  1328. // G_RendDriver->DrawTextureRect(vec2(Board2DCen.x - 33, G_PokerGame->BoardRect2D.GetBottom()-RenderUpDownSpace));
  1329. // }
  1330. //}
  1331. 显示叫地主按钮
  1332. //{
  1333. // if(IsMyTurn()
  1334. // && G_PokerDouDiZhu->m_gameStatus == Preparing)
  1335. // {
  1336. // G_PokerDouDiZhu->m_sanfenButtonTexture->Bind();
  1337. // G_RendDriver->DrawTextureRect(vec2(Board2DCen.x - 80, G_PokerGame->BoardRect2D.GetBottom()-RenderUpDownSpace));
  1338. // G_PokerDouDiZhu->m_buJiaoButtonTexture->Bind();
  1339. // G_RendDriver->DrawTextureRect(vec2(Board2DCen.x + 20, G_PokerGame->BoardRect2D.GetBottom()-RenderUpDownSpace));
  1340. // }
  1341. //}
  1342. }
  1343. //保存待出的牌
  1344. void DouDizhuPlayerRole::SaveOutCard()
  1345. {
  1346. for(int i = 0; i < MaxPlayerCard; i++)
  1347. m_toOutCard->m_cards[i].cardID = (CardID)-1;
  1348. int num = 0;
  1349. for(int i = 0; i < m_cardNum; i++)
  1350. {
  1351. if(m_cards[i].bClicked == true)
  1352. {
  1353. m_toOutCard->m_cards[num++] = m_cards[i];
  1354. }
  1355. }
  1356. m_toOutCard->m_cardNum = num;
  1357. }
  1358. bool DouDizhuPlayerRole::TryOutCard()
  1359. {
  1360. if(m_clickedNum <= 0)
  1361. return false;
  1362. SaveOutCard();
  1363. int tmp = g_curOutCards->value;
  1364. if(G_PokerDouDiZhu->m_lastOutTurn != m_turn)
  1365. {
  1366. switch(m_clickedNum)
  1367. {
  1368. case 0:
  1369. return false;
  1370. case 1:
  1371. {
  1372. if(g_curOutCards->type == GZ && m_toOutCard->m_cards[0].cardValue > g_curOutCards->value)
  1373. {
  1374. g_curOutCards->value = m_toOutCard->m_cards[0].cardValue;
  1375. g_curOutCards->num = 1;
  1376. g_curOutCards->type = GZ;
  1377. return true;
  1378. }
  1379. }
  1380. case 2:
  1381. {
  1382. if(g_curOutCards->type == DZ && dz()) //是不是对子
  1383. {
  1384. if(tmp < m_toOutCard->m_cards[0].cardValue)
  1385. return true;
  1386. }
  1387. if(sw())
  1388. return true;
  1389. }
  1390. case 3:
  1391. {
  1392. if(g_curOutCards->type == SGBD && sgbd())
  1393. if(tmp < m_toOutCard->m_cards[0].cardValue)
  1394. return 1;
  1395. }
  1396. case 4:
  1397. {
  1398. if(g_curOutCards->type == SD1 && sd1())
  1399. {
  1400. if(tmp < m_toOutCard->m_cards[1].cardValue)
  1401. return true;
  1402. }
  1403. if(g_curOutCards->type != ZD && zd())
  1404. return true;
  1405. if(g_curOutCards->type == ZD && zd())
  1406. {
  1407. if(tmp < m_toOutCard->m_cards[1].cardValue)
  1408. return true;
  1409. }
  1410. }
  1411. case 5:
  1412. {
  1413. if(g_curOutCards->type == SZ && sz(5))
  1414. if(tmp < m_toOutCard->m_cards[0].cardValue)
  1415. return true;
  1416. if(g_curOutCards->type == SD2 && sd2())
  1417. if(tmp < m_toOutCard->m_cards[2].cardValue)
  1418. return true;
  1419. }
  1420. case 6:
  1421. {
  1422. if(g_curOutCards->type == SZ && sz(6))
  1423. if(tmp < m_toOutCard->m_cards[0].cardValue)
  1424. return true;
  1425. if(g_curOutCards->type == LD3 && ld3())
  1426. if(tmp < m_toOutCard->m_cards[5].cardValue)
  1427. return true;
  1428. if(g_curOutCards->type == SD2G && sd2g())
  1429. if(tmp < m_toOutCard->m_cards[3].cardValue)
  1430. return true;
  1431. if(g_curOutCards->type == FJBD && fjbd())
  1432. if(tmp < m_toOutCard->m_cards[4].cardValue)
  1433. return true;
  1434. }
  1435. case 7:
  1436. {
  1437. if(g_curOutCards->type == SZ && sz(7))
  1438. if(tmp < m_toOutCard->m_cards[0].cardValue)
  1439. return true;
  1440. }
  1441. case 8:
  1442. {
  1443. if(g_curOutCards->type == SZ && sz(8))
  1444. if(tmp < m_toOutCard->m_cards[0].cardValue)
  1445. return true;
  1446. if(g_curOutCards->type == FJD2G && fjd2g())
  1447. if(tmp < m_toOutCard->m_cards[2].cardValue)
  1448. return true;
  1449. if(g_curOutCards->type == LD4 && ld4())
  1450. if(tmp < m_toOutCard->m_cards[7].cardValue)
  1451. return true;
  1452. if(g_curOutCards->type == SD2G && sd2d())
  1453. return true;
  1454. }
  1455. case 9:
  1456. {
  1457. if(g_curOutCards->type == SZ && sz(9))
  1458. if(tmp < m_toOutCard->m_cards[0].cardValue)
  1459. return true;
  1460. if(g_curOutCards->type == SFJBD && sfjbd())
  1461. if(tmp < m_toOutCard->m_cards[8].cardValue)
  1462. return true;
  1463. }
  1464. case 10:return sz(10) || fjd2d() || ld5();
  1465. case 11:return sz(11);
  1466. case 12:return sz(12) || ld6() || sfjdsg();
  1467. case 13:return sz(13);
  1468. case 14:return ld7();
  1469. case 15:return sfjdsd();
  1470. default: return false;
  1471. }
  1472. }
  1473. else
  1474. {
  1475. switch(m_clickedNum)
  1476. {
  1477. case 0: return false ;
  1478. case 1:
  1479. {
  1480. g_curOutCards->value = m_toOutCard->m_cards[0].cardValue;
  1481. g_curOutCards->num = 1;
  1482. g_curOutCards->type = GZ;
  1483. }
  1484. return true;
  1485. case 2: return dz() || sw();
  1486. case 3: return sgbd();
  1487. case 4: return sd1() || zd();
  1488. case 5: return sz(5) || sd2();
  1489. case 6: return sz(6) || ld3() || sd2g() || fjbd();
  1490. case 7: return sz(7);
  1491. case 8: return sz(8) || fjd2g() || ld4() || sd2d();
  1492. case 9: return sz(9) || sfjbd();
  1493. case 10: return sz(10) || fjd2d() || ld5();
  1494. case 11: return sz(11);
  1495. case 12: return sz(12) || ld6() || sfjdsg();
  1496. case 13: return sz(13);
  1497. case 14: return ld7();
  1498. case 15: return sfjdsd();
  1499. default: return false;
  1500. }
  1501. }
  1502. return false;
  1503. }
  1504. //对子
  1505. bool DouDizhuPlayerRole::dz()
  1506. {
  1507. if(m_toOutCard->m_cards[0].cardValue == m_toOutCard->m_cards[1].cardValue)
  1508. {
  1509. g_curOutCards->value = m_toOutCard->m_cards[0].cardValue;
  1510. g_curOutCards->num = 2;
  1511. g_curOutCards->type = DZ;
  1512. return true;
  1513. }
  1514. return false ;
  1515. }
  1516. //双王
  1517. bool DouDizhuPlayerRole::sw()
  1518. {
  1519. if(m_toOutCard->m_cards[0].cardValue + m_toOutCard->m_cards[1].cardValue == 33) //记得改成和这个一样的
  1520. {
  1521. g_curOutCards->num =2;
  1522. g_curOutCards->type = SW;
  1523. return true;
  1524. }
  1525. return false ;
  1526. }
  1527. //三个不带
  1528. bool DouDizhuPlayerRole::sgbd()
  1529. {
  1530. if(m_toOutCard->m_cards[0].cardValue == m_toOutCard->m_cards[1].cardValue && m_toOutCard->m_cards[1].cardValue == m_toOutCard->m_cards[2].cardValue)
  1531. {
  1532. g_curOutCards->value = m_toOutCard->m_cards[0].cardValue;
  1533. g_curOutCards->num =3;
  1534. g_curOutCards->type = SGBD;
  1535. return true;
  1536. }
  1537. return false;
  1538. }
  1539. //三带一
  1540. bool DouDizhuPlayerRole::sd1()
  1541. {
  1542. int analyse[2] , m = 0 , n = 0 , i , j , k , num = 5 ;
  1543. for(i = 0 ; i < num ; i++)
  1544. for(j = i+1 ; j < num ; j++)
  1545. for(k = j+1 ; k < num ; k++)
  1546. {
  1547. if(m_toOutCard->m_cards[i].cardValue == m_toOutCard->m_cards[j].cardValue && m_toOutCard->m_cards[j].cardValue == m_toOutCard->m_cards[k].cardValue)
  1548. {
  1549. for(m = 0 ; m < num ; m++)
  1550. {
  1551. if(m != i && m != j && m != k)
  1552. analyse[n++] = m_toOutCard->m_cards[m].cardValue;
  1553. }
  1554. if(analyse[0] != m_toOutCard->m_cards[i].cardValue)
  1555. {
  1556. g_curOutCards->value = m_toOutCard->m_cards[i].cardValue;
  1557. g_curOutCards->num = 3;
  1558. g_curOutCards->type = SD1;
  1559. return true;
  1560. }
  1561. else
  1562. return false ;
  1563. }
  1564. }
  1565. return false;
  1566. }
  1567. //炸弹
  1568. bool DouDizhuPlayerRole::zd()
  1569. {
  1570. if(m_toOutCard->m_cards[0].cardValue == m_toOutCard->m_cards[1].cardValue
  1571. && m_toOutCard->m_cards[1].cardValue == m_toOutCard->m_cards[2].cardValue
  1572. && m_toOutCard->m_cards[2].cardValue == m_toOutCard->m_cards[3].cardValue)
  1573. {
  1574. g_curOutCards->value = m_toOutCard->m_cards[0].cardValue;
  1575. g_curOutCards->num = 4;
  1576. g_curOutCards->type = ZD;
  1577. return true;
  1578. }
  1579. else
  1580. return false;
  1581. }
  1582. //三带二
  1583. bool DouDizhuPlayerRole::sd2()
  1584. {
  1585. int analyse[2] , m = 0 , n = 0 , i , j , k , num = 5 ;
  1586. for(i = 0 ; i < num ; i++)
  1587. for(j = i+1 ; j < num ; j++)
  1588. for(k = j+1 ; k < num ; k++)
  1589. {
  1590. if(m_toOutCard->m_cards[i].cardValue == m_toOutCard->m_cards[j].cardValue && m_toOutCard->m_cards[j].cardValue == m_toOutCard->m_cards[k].cardValue)
  1591. {
  1592. for(m = 0 ; m < num ; m++)
  1593. {
  1594. if(m != i && m != j && m != k)
  1595. analyse[n++] = m_toOutCard->m_cards[m].cardValue;
  1596. }
  1597. if(analyse[0] == analyse[1])
  1598. {
  1599. g_curOutCards->value = m_toOutCard->m_cards[i].cardValue;
  1600. g_curOutCards->num =4;
  1601. g_curOutCards->type = SD2;
  1602. return true;
  1603. }
  1604. else
  1605. return false;
  1606. }
  1607. }
  1608. return false;
  1609. }
  1610. //顺子 n 代表牌数
  1611. bool DouDizhuPlayerRole::sz(int n)
  1612. {
  1613. int i ;
  1614. for(i = 0 ; i < n-1 ; i++)
  1615. {
  1616. if(m_toOutCard->m_cards[i].cardValue == PokerDouDiZhu::Value2
  1617. || m_toOutCard->m_cards[i + 1].cardValue == PokerDouDiZhu::Value2)
  1618. return false; 不能有2
  1619. if(m_toOutCard->m_cards[i].cardValue != m_toOutCard->m_cards[i + 1].cardValue + 1)
  1620. return false;
  1621. }
  1622. g_curOutCards->value = m_toOutCard->m_cards[0].cardValue;
  1623. g_curOutCards->min = m_toOutCard->m_cards[n -1].cardValue;
  1624. g_curOutCards->num = n;
  1625. g_curOutCards->type = SZ;
  1626. return true;
  1627. }
  1628. //连对3 (三连对)
  1629. bool DouDizhuPlayerRole::ld3()
  1630. {
  1631. int min = m_toOutCard->MinCard(); //不能为KA2 (13 14 15)
  1632. if(min == 13)
  1633. return false;
  1634. if(m_toOutCard->CountCard(min) == 2 && m_toOutCard->CountCard(min + 1) == 2 && m_toOutCard->CountCard(min + 2) == 2)
  1635. {
  1636. g_curOutCards->value = min;
  1637. g_curOutCards->num = 6;
  1638. g_curOutCards->type = LD3;
  1639. return true;
  1640. }
  1641. return false;
  1642. }
  1643. //四带二个
  1644. bool DouDizhuPlayerRole::sd2g()
  1645. {
  1646. int analyse[2], m = 0, n = 0, i, j, k, p;
  1647. for(i = 0; i < 6; i++)
  1648. for(j = i+1; j < 6; j++)
  1649. for(k = j+1; k < 6; k++)
  1650. for(p = k+1; p < 6; p++)
  1651. {
  1652. if(m_toOutCard->m_cards[i].cardValue == m_toOutCard->m_cards[j].cardValue
  1653. && m_toOutCard->m_cards[j].cardValue == m_toOutCard->m_cards[k].cardValue
  1654. && m_toOutCard->m_cards[k].cardValue == m_toOutCard->m_cards[p].cardValue)
  1655. {
  1656. for(n = 0, m = 0; m < 6; m++)
  1657. {
  1658. if(m != i && m != j && m != k && m != p)
  1659. analyse[n++] = m_toOutCard->m_cards[m].cardValue;
  1660. }
  1661. if(analyse[0] != analyse[1])
  1662. {
  1663. g_curOutCards->value = m_toOutCard->m_cards[i].cardValue;
  1664. g_curOutCards->num =6;
  1665. g_curOutCards->type = SD2G;
  1666. return true;
  1667. }
  1668. return false;
  1669. }
  1670. }
  1671. return false;
  1672. }
  1673. //飞机不带
  1674. bool DouDizhuPlayerRole::fjbd()
  1675. {
  1676. int analyse[3], m = 0, n = 0, i, j, k, num = 6;
  1677. for(i = 0; i < num ; i++)
  1678. for(j = i + 1; j < num; j++)
  1679. for(k = j + 1; k < num; k++)
  1680. {
  1681. if(m_toOutCard->m_cards[i].cardValue == m_toOutCard->m_cards[j].cardValue && m_toOutCard->m_cards[j].cardValue == m_toOutCard->m_cards[k].cardValue)
  1682. {
  1683. for(n = 0, m = 0; m < num; m++)
  1684. {
  1685. if(m != i && m != j && m != k)
  1686. analyse[n++] = m_toOutCard->m_cards[m].cardValue;
  1687. }
  1688. if(analyse[0] == analyse[1] && analyse[1] == analyse[2])//判断另外三个是否相等
  1689. {
  1690. if(abs(m_toOutCard->m_cards[i].cardValue - analyse[0]) != 1)
  1691. return false; //当两个三个不是连着的时
  1692. if(((m_toOutCard->m_cards[i].cardValue > analyse[0]) ? m_toOutCard->m_cards[i].cardValue : analyse[0]) == PokerDouDiZhu::Value2)
  1693. return false; //最大不能为2
  1694. g_curOutCards->value = m_toOutCard->m_cards[i].cardValue < analyse[0] ? m_toOutCard->m_cards[i].cardValue : analyse[0];
  1695. g_curOutCards->num =6;
  1696. g_curOutCards->type = FJBD;
  1697. return true;
  1698. }
  1699. return false;
  1700. }
  1701. }
  1702. return false;
  1703. }
  1704. //飞机带二个
  1705. bool DouDizhuPlayerRole::fjd2g()
  1706. {
  1707. int analyse[2], m = 0, n = 0, i, j, k, t[2][3] = {0}, num = 8;
  1708. for(i = 0; i < num; i++)
  1709. {
  1710. for(j = i+1; j < num; j++)
  1711. {
  1712. for(k = j+1; k < num; k++)
  1713. {
  1714. if(m_toOutCard->m_cards[i].cardValue == m_toOutCard->m_cards[j].cardValue && m_toOutCard->m_cards[j].cardValue == m_toOutCard->m_cards[k].cardValue)
  1715. {
  1716. t[n][0] = i;
  1717. t[n][1] = j;
  1718. t[n++][2] = k;
  1719. }
  1720. if(n == 2)
  1721. {
  1722. if(abs(m_toOutCard->m_cards[t[0][0]].cardValue - m_toOutCard->m_cards[t[1][0]].cardValue) != 1)
  1723. return false; //当两个三个不是连着的时
  1724. for(n = 0, m = 0; m < num; m++)
  1725. {
  1726. if(m != t[0][0] && m != t[0][1] && m != t[0][2]
  1727. && m != t[1][0] && m != t[1][1] && m != t[1][2])
  1728. analyse[n++] = m_toOutCard->m_cards[m].cardValue;
  1729. }
  1730. if(analyse[0] != analyse[1])
  1731. {
  1732. if((m_toOutCard->m_cards[t[0][0]].cardValue < m_toOutCard->m_cards[t[1][0]].cardValue ? m_toOutCard->m_cards[t[0][0]].cardValue : m_toOutCard->m_cards[t[1][0]].cardValue) == 14)
  1733. return false; //最大不能为2
  1734. g_curOutCards->value = m_toOutCard->m_cards[t[0][0]].cardValue < m_toOutCard->m_cards[t[1][0]].cardValue ? m_toOutCard->m_cards[t[0][0]].cardValue : m_toOutCard->m_cards[t[1][0]].cardValue;
  1735. g_curOutCards->num = 8;
  1736. g_curOutCards->type = FJD2G;
  1737. return true;
  1738. }
  1739. return false;
  1740. }
  1741. }
  1742. }
  1743. }
  1744. return false;
  1745. }
  1746. //4连对
  1747. bool DouDizhuPlayerRole::ld4()
  1748. {
  1749. int min = m_toOutCard->MinCard();
  1750. if(min == 12)
  1751. return false; //最大不能为2
  1752. if(m_toOutCard->CountCard(min) == 2 && m_toOutCard->CountCard(min+1) == 2
  1753. && m_toOutCard->CountCard(min + 2) == 2 && m_toOutCard->CountCard(min + 3) == 2)
  1754. {
  1755. g_curOutCards->value = min;
  1756. g_curOutCards->num = 8;
  1757. g_curOutCards->type = LD4;
  1758. return true;
  1759. }
  1760. return false;
  1761. }
  1762. //四带两对
  1763. bool DouDizhuPlayerRole::sd2d()
  1764. {
  1765. int analyse[4], m = 0, n = 0, i, j, k, p;
  1766. for(i = 0; i < 8; i++)
  1767. for(j = i+1; j < 8; j++)
  1768. for(k = j+1; k < 8; k++)
  1769. for(p = k+1; p < 8; p++)
  1770. {
  1771. if(m_toOutCard->m_cards[i].cardValue == m_toOutCard->m_cards[j].cardValue
  1772. && m_toOutCard->m_cards[j].cardValue == m_toOutCard->m_cards[k].cardValue
  1773. && m_toOutCard->m_cards[k].cardValue == m_toOutCard->m_cards[p].cardValue)
  1774. {
  1775. for(n = 0, m = 0; m < 8; m++)
  1776. {
  1777. if(m != i && m != j && m != k && m != p)
  1778. analyse[n++] = m_toOutCard->m_cards[m].cardValue;
  1779. }
  1780. if(ld(analyse))
  1781. {
  1782. g_curOutCards->value = m_toOutCard->m_cards[i].cardValue;
  1783. g_curOutCards->num = 8;
  1784. g_curOutCards->type = SD2D;
  1785. return true;
  1786. }
  1787. return false;
  1788. }
  1789. }
  1790. return false;
  1791. }
  1792. //是不是二对 , 要求不一样
  1793. bool DouDizhuPlayerRole::ld(int temp[])
  1794. {
  1795. int i, j, m, n = 0, analyse[2], num = 4;
  1796. for (i = 0; i < num; i++)
  1797. for (j = i+1 ; j < num ; j++)
  1798. {
  1799. if(temp[i] == temp[j])
  1800. for(m = 0 ; m < num ; m++)
  1801. {
  1802. if(m != i && m != j)
  1803. analyse[n++] = temp[m];
  1804. }
  1805. if(analyse[0] == analyse[1] && analyse[0] != temp[i])
  1806. {
  1807. return true;
  1808. }
  1809. }
  1810. return false;
  1811. }
  1812. //三飞机带三个
  1813. bool DouDizhuPlayerRole::sfjdsg()
  1814. {
  1815. int analyse[3], m = 0, n = 0, i, j, k, t[3][3] = {0}, num = 12;
  1816. for(i = 0; i < num ; i++)
  1817. for(j = i+1; j < num; j++)
  1818. for(k = j+1; k < num; k++)
  1819. {
  1820. if(m_toOutCard->m_cards[i].cardValue == m_toOutCard->m_cards[j].cardValue
  1821. && m_toOutCard->m_cards[j].cardValue == m_toOutCard->m_cards[k].cardValue)
  1822. {
  1823. t[n][0] = i;
  1824. t[n][1] = j;
  1825. t[n++][2] = k;
  1826. }
  1827. if(n == 3)
  1828. {
  1829. for(n = 0, m = 0; m < num; m++)
  1830. {
  1831. if(m != t[0][0] && m != t[0][1] && m != t[0][2]
  1832. && m != t[1][0] && m != t[1][1] && m != t[1][2]
  1833. && m != t[2][0] && m != t[2][1] && m != t[2][2])
  1834. analyse[n++] = m_toOutCard->m_cards[m].cardValue ;
  1835. }
  1836. if(analyse[0] != analyse[1] && analyse[0] != analyse[2] && analyse[2] != analyse[1])
  1837. {
  1838. analyse[0] = m_toOutCard->m_cards[t[0][0]].cardValue;
  1839. analyse[1] = m_toOutCard->m_cards[t[1][0]].cardValue;
  1840. analyse[2] = m_toOutCard->m_cards[t[2][0]].cardValue;
  1841. if((analyse[0] + analyse[1] + analyse[2]) != (MinCard(analyse, 3) + 1) * 3)
  1842. return false; //三个是不是连着的
  1843. if(MinCard(analyse, 3) == 13)
  1844. return false; //最大不能为2
  1845. g_curOutCards->value = MinCard(analyse, 3);
  1846. g_curOutCards->num =12;
  1847. g_curOutCards->type = SFJDSG;
  1848. return true;
  1849. }
  1850. return false ;
  1851. }
  1852. }
  1853. return false;
  1854. }
  1855. //三飞机不带
  1856. bool DouDizhuPlayerRole::sfjbd()
  1857. {
  1858. int min = m_toOutCard->MinCard();
  1859. if(min == 13)
  1860. return false; //最大不能为2
  1861. if( m_toOutCard->CountCard(min) == 3
  1862. && m_toOutCard->CountCard(min + 1) == 3
  1863. && m_toOutCard->CountCard(min + 2) == 3)
  1864. {
  1865. g_curOutCards->value = min;
  1866. g_curOutCards->num = 9;
  1867. g_curOutCards->type = SFJBD;
  1868. return true;
  1869. }
  1870. return false;
  1871. }
  1872. //飞机带两对
  1873. bool DouDizhuPlayerRole::fjd2d()
  1874. {
  1875. int analyse[4], m = 0, n = 0, i, j, k, t[3][3] = {0}, num = 10;
  1876. for(i = 0; i < num; i++)
  1877. for(j = i+1; j < num; j++)
  1878. for(k = j+1; k < num; k++)
  1879. {
  1880. if(m_toOutCard->m_cards[i].cardValue == m_toOutCard->m_cards[j].cardValue
  1881. && m_toOutCard->m_cards[j].cardValue == m_toOutCard->m_cards[k].cardValue)
  1882. {
  1883. t[n][0] = i;
  1884. t[n][1] = j;
  1885. t[n++][2] = k;
  1886. }
  1887. if(n == 2)
  1888. {
  1889. if(abs(m_toOutCard->m_cards[t[0][0]].cardValue - m_toOutCard->m_cards[t[1][0]].cardValue) != 1)
  1890. return false; //当两个三个不是连着的时
  1891. for(n = 0, m = 0; m < num; m++)
  1892. {
  1893. if(m != t[0][0] && m != t[0][1] && m != t[0][2] && m != t[1][0] && m != t[1][1] && m != t[1][2])
  1894. analyse[n++] = m_toOutCard->m_cards[m].cardValue;
  1895. }
  1896. if(ld(analyse))
  1897. {
  1898. if(((m_toOutCard->m_cards[t[0][0]].cardValue < m_toOutCard->m_cards[t[1][0]].cardValue)
  1899. ? m_toOutCard->m_cards[t[0][0]].cardValue : m_toOutCard->m_cards[t[1][0]].cardValue) == 14)
  1900. return false; //最大不能为2
  1901. g_curOutCards->value = m_toOutCard->m_cards[t[0][0]].cardValue < m_toOutCard->m_cards[t[1][0]].cardValue
  1902. ? m_toOutCard->m_cards[t[0][0]].cardValue : m_toOutCard->m_cards[t[1][0]].cardValue;
  1903. g_curOutCards->num =10;
  1904. g_curOutCards->type = FJD2D;
  1905. return true;
  1906. }
  1907. return false;
  1908. }
  1909. }
  1910. return false;
  1911. }
  1912. //五连对
  1913. bool DouDizhuPlayerRole::ld5()
  1914. {
  1915. int min = m_toOutCard->MinCard();
  1916. if(min == 11)
  1917. return false; //最大不能为2
  1918. if( m_toOutCard->CountCard(min) == 2 && m_toOutCard->CountCard(min + 1) == 2
  1919. && m_toOutCard->CountCard(min + 2) == 2 && m_toOutCard->CountCard(min + 3) == 2
  1920. && m_toOutCard->CountCard(min + 4) == 2)
  1921. {
  1922. g_curOutCards->value = min;
  1923. g_curOutCards->num =10;
  1924. g_curOutCards->type = LD5;
  1925. return true;
  1926. }
  1927. return false;
  1928. }
  1929. //六连对
  1930. bool DouDizhuPlayerRole::ld6()
  1931. {
  1932. int min = m_toOutCard->MinCard();
  1933. if(min == 10)
  1934. return false; //最大不能为2
  1935. if( m_toOutCard->CountCard(min) == 2 && m_toOutCard->CountCard(min + 1) == 2
  1936. && m_toOutCard->CountCard(min + 2) == 2 && m_toOutCard->CountCard(min + 3) == 2
  1937. && m_toOutCard->CountCard(min + 4) == 2 && m_toOutCard->CountCard(min + 5) == 2)
  1938. {
  1939. g_curOutCards->value = min;
  1940. g_curOutCards->num =12;
  1941. g_curOutCards->type = LD6;
  1942. return true;
  1943. }
  1944. return false;
  1945. }
  1946. //七连对
  1947. bool DouDizhuPlayerRole::ld7()
  1948. {
  1949. int min = m_toOutCard->MinCard();
  1950. if(min == 9)
  1951. return false; //最大不能为2
  1952. if( m_toOutCard->CountCard(min) == 2 && m_toOutCard->CountCard(min + 1) == 2
  1953. && m_toOutCard->CountCard(min + 2) == 2 && m_toOutCard->CountCard(min + 3) == 2
  1954. && m_toOutCard->CountCard(min + 4) == 2 && m_toOutCard->CountCard(min + 5) == 2
  1955. && m_toOutCard->CountCard(min + 6) == 2)
  1956. {
  1957. g_curOutCards->value = min;
  1958. g_curOutCards->num =14;
  1959. g_curOutCards->type = LD7;
  1960. return true;
  1961. }
  1962. return false;
  1963. }
  1964. //三飞机带三对
  1965. bool DouDizhuPlayerRole::sfjdsd()
  1966. {
  1967. int analyse[6], m = 0, n = 0, i, j, k, t[3][3] = {0}, num = 15;
  1968. for(i = 0; i < num; i++)
  1969. for(j = i+1; j < num; j++)
  1970. for(k = j+1; k < num; k++)
  1971. {
  1972. if(m_toOutCard->m_cards[i].cardValue == m_toOutCard->m_cards[j].cardValue
  1973. && m_toOutCard->m_cards[j].cardValue == m_toOutCard->m_cards[k].cardValue)
  1974. {
  1975. t[n][0] = i;
  1976. t[n][1] = j;
  1977. t[n++][2] = k;
  1978. }
  1979. if(n == 3)
  1980. {
  1981. for(n = 0, m = 0; m < num; m++)
  1982. {
  1983. if(m != t[0][0] && m != t[0][1] && m != t[0][2]
  1984. && m != t[1][0] && m != t[1][1] && m != t[1][2]
  1985. && m != t[2][0] && m != t[2][1] && m != t[2][2])
  1986. analyse[n++] = m_toOutCard->m_cards[m].cardValue;
  1987. }
  1988. if(sd(analyse))
  1989. {
  1990. analyse[0] = m_toOutCard->m_cards[t[0][0]].cardValue;
  1991. analyse[1] = m_toOutCard->m_cards[t[1][0]].cardValue;
  1992. analyse[2] = m_toOutCard->m_cards[t[2][0]].cardValue;
  1993. if((analyse[0] + analyse[1] + analyse[2]) != (MinCard(analyse, 3) + 1) * 3)
  1994. return false; //三个是不是连着的
  1995. if(MinCard(analyse, 3) == 13)
  1996. return false; //最大不能为2
  1997. g_curOutCards->value = MinCard(analyse, 3);
  1998. g_curOutCards->num =15;
  1999. g_curOutCards->type = SFJDSD;
  2000. return true;
  2001. }
  2002. return false;
  2003. }
  2004. }
  2005. return false;
  2006. }
  2007. //是不是三对, 要求不一样
  2008. bool DouDizhuPlayerRole::sd(int temp[])
  2009. {
  2010. int i, j, m = 0, n = 0, num = 6, t[3];
  2011. for (i = 0; i < num; i++)
  2012. for (j = i+1 ; j < num ; j++)
  2013. {
  2014. if(temp[i] == temp[j])
  2015. t[m++] = j;
  2016. if((m > 1) && (temp[t[m - 2]] == temp[t[m - 1]])) //除出三个一样的
  2017. return false;
  2018. }
  2019. if(m == 3)
  2020. return true;
  2021. return false;
  2022. }

蜘蛛纸牌代码:

  1. //========================================================
  2. // @Date: 2016.05
  3. // @File: SourceDemoClient/Poker/PokerHongXin.cpp
  4. // @Brief: SpiderGame
  5. // @Author: LouLei
  6. // @Email: twopointfive@163.com
  7. // @Copyright (Crapell) - All Rights Reserved
  8. //========================================================
  9. #ifndef _SpideGame_
  10. #define _SpideGame_
  11. #include "Math/MathLib.h"
  12. #include "General/Vector.h"
  13. #include "Render/Texture.h"
  14. #include "PokerCard.h"
  15. #include "Rpg/MiniGame.h"
  16. typedef Vector<int> IntVector;
  17. struct ScreenStruct
  18. {
  19. char LbFrom; //牌从该列移出
  20. char LbTo; //移出的牌移到该列
  21. char MoveCardNum; //拖动牌数
  22. int nBackNum; //主列牌的覆盖牌数
  23. };
  24. enum SpiderGameStatus
  25. {
  26. Waiting,
  27. Dealing, //发牌
  28. Completing,//收牌
  29. Tiping,
  30. Playing,
  31. Resulting,
  32. };
  33. #define DOWNPOS (BoardRect2D.y + BoardRect2D.height - 30) //分数区域底部位置
  34. #define CARDDIS_BACK 17 //8 //未翻牌重叠间距高度
  35. #define CARDDIS_FRONT 20 //翻开牌重叠间距高度
  36. #define CardWidth 71
  37. #define CardHeight 96
  38. class SoundChannel;
  39. //顶部的一列牌
  40. class Every
  41. {
  42. public:
  43. int CardAt(int index);
  44. void PushCard(int card);
  45. void DeleteCard(int index);
  46. //某一个牌是否上一张牌小
  47. bool IsLessThenTop(int index);
  48. //计算最大可拖动牌数
  49. int CalMaxMoveNum();
  50. RectF CardRect(int index);
  51. int m_index;
  52. IntVector m_cards; //所有牌
  53. int m_backNum; //未翻牌数
  54. int m_maxMoveNum; //最大可拖动牌数
  55. };
  56. class MiniGameSpiderPoker:public MiniGame
  57. {
  58. public:
  59. MiniGameSpiderPoker();
  60. virtual~MiniGameSpiderPoker();
  61. virtual bool Start();
  62. virtual bool Stop();
  63. virtual bool Render();
  64. virtual bool Update();
  65. virtual bool Free();
  66. //三种类型结构
  67. virtual MiniPlayer* CreatePlayer();
  68. virtual MiniPlayer* CreateRobot ();
  69. virtual MiniPlayer* CreateRole ();
  70. //发牌过程函数
  71. bool OnDeal();
  72. //根据给定牌的列和链表,计算出可以拖动的矩形大小
  73. void GetRecvRect(Every*every,RectF &rect);
  74. //判断拖动牌的个数
  75. int GetMoveCardNum(Every*every,const vec2& point);
  76. //计算拖动牌左上角坐标和鼠标按下点坐标的横纵距离
  77. void GetTwoPointJL(Every*every,const vec2& point);
  78. //判断一列牌中是否可以收牌
  79. void IsCardAccess(Every*ever);
  80. //提示功能
  81. bool OnTip();
  82. void OnUndo();
  83. void OnGameRead();
  84. void OnGameSave();
  85. //判断是否胜利
  86. bool IsGameEnd();
  87. //增加一个撤消状态
  88. void AddScreen(char CardList,char CardListOther,char MoveCardNum,int BackNum);
  89. void DebugCheck();
  90. public:
  91. SpiderGameStatus m_gameStatus;
  92. float m_stateAccumeTime;
  93. #define MaxEveryNum 10
  94. int EveryNum;
  95. //十列牌
  96. Every m_cardEverys[MaxEveryNum];
  97. IntVector m_cardsDealLeft; //剩余牌链表
  98. IntVector m_cardsComplete; //已经完成的牌
  99. int m_dealLeft; //剩余发牌轮数
  100. Every* m_curDealEvery;
  101. vec2 m_curDealPoint; //发牌或收牌的起点和终点
  102. vec2 m_curDealPointEnd;
  103. int m_curDealCardVal;
  104. Every* m_curCompleteEvery;
  105. vec2 m_curCompletePoint; //发牌或收牌的起点和终点
  106. vec2 m_curCompletePointEnd;
  107. int m_curCompleteCardNum;
  108. int m_curCompleteCardVal;
  109. int m_moveComplete; //已完成的列数
  110. int m_Score; //总分数
  111. int m_moveNum; //拖动次数
  112. bool m_tipButton;
  113. bool m_dealButton;
  114. //撤消功能
  115. ScreenStruct * m_undos;
  116. int m_curUndo; //当前屏幕号
  117. int m_MaxScreen; //记录的最大屏幕数
  118. float EveryDis; //列间距
  119. bool m_openPoker;
  120. private:
  121. vec2I m_moveOffset; //鼠标点和拖动牌左上角的偏移
  122. int m_curMoveNum; //跟随鼠标拖动牌个数
  123. Every* m_curMoveEvery; //拖动的列
  124. IntVector m_movingCards; //拖动的牌
  125. //存储牌拖动信息
  126. IntVector m_tipMoves; //依次存储当前列、对比列、当前列与对比列可以拖动牌的个数
  127. int m_curTip; //当前可拖动牌信息个数,值为1到一拖动牌信息个数最大值
  128. TexturePtr m_texCards[CardNum];
  129. TexturePtr m_texCardBack;
  130. TexturePtr m_texCardSlot;
  131. TexturePtr m_texBack;
  132. SoundChannel* m_sound;
  133. };
  134. extern MiniGameSpiderPoker* G_SpiderGame;
  135. #endif
  136. //========================================================
  137. // @Date: 2016.05
  138. // @File: SourceDemoClient/Poker/PokerHongXin.cpp
  139. // @Brief: SpiderGame
  140. // @Author: LouLei
  141. // @Email: twopointfive@163.com
  142. // @Copyright (Crapell) - All Rights Reserved
  143. //========================================================
  144. #include "General/Pch.h"
  145. #include "General/Timer.h"
  146. #include "General/Window.h"
  147. #include "MiniGameSpiderPoker.h"
  148. #include "Input/InputMgr.h"
  149. #include "Render/RendDriver.h"
  150. #include "Render/Font.h"
  151. #include "Sound/ChannelSound.h"
  152. #include "General/Vector.cpp"
  153. #include "General/Pce.h"
  154. #include "Render/MC_MovieClip.h"
  155. #include "Render/Camera.h"
  156. #include "Gui/GuiMgr.h"
  157. #include "Gui/RpgGuis.h"
  158. #include "Render/Shader.h"
  159. template class Vector<int>;
  160. MiniGameSpiderPoker* G_SpiderGame = NULL;
  161. MiniGameSpiderPoker::MiniGameSpiderPoker()
  162. {
  163. G_SpiderGame = this;
  164. m_MaxScreen = 50;
  165. m_undos = new ScreenStruct[m_MaxScreen];
  166. m_sound = new SoundChannel;
  167. }
  168. MiniGameSpiderPoker::~MiniGameSpiderPoker()
  169. {
  170. SafeDeleteArray(m_undos);
  171. SafeDelete(m_sound);
  172. G_SpiderGame = NULL;
  173. }
  174. bool MiniGameSpiderPoker::Start()
  175. {
  176. if(!MiniGame::Start())
  177. return false;
  178. m_openPoker = false;
  179. const char* cardTexName[] =
  180. {
  181. "data/minigame/poker/mei2.png",
  182. "data/minigame/poker/mei3.png",
  183. ...
  184. };
  185. for(int i = 0; i < CardNum; i++)
  186. {
  187. G_TextureMgr->AddTexture(m_texCards[i], cardTexName[i]);
  188. }
  189. G_TextureMgr->AddTexture(m_texCardBack, "data/minigame/poker/cardback01.png");
  190. G_TextureMgr->AddTexture(m_texCardSlot, "data/minigame/poker/cardslot.png");
  191. G_TextureMgr->AddTexture(m_texBack, "data/minigame/poker/back.png");
  192. //
  193. if(m_movieScene == NULL)
  194. {
  195. LoadConfig loader(LoadConfig::GenDonotReShrinkBound, true, true);
  196. m_movieScene = new RendSys::MovieClip;
  197. m_movieScene->LoadFromFile("data/minigame/poker/board.movie", &loader);
  198. Frame frame;
  199. frame.SetPos(m_startPos);
  200. m_movieScene->SetProgramFrame(&frame);
  201. m_movieScene->Advance();
  202. }
  203. if(m_movieScene->IsLoadComplete() == false)
  204. {
  205. m_gameState = MS_End;
  206. return false;
  207. }
  208. SetBoardRect(RectF(100, 100, G_Window->m_iWidth-200, G_Window->m_iHeight-200),
  209. RectF(m_startPos.x - 50, m_startPos.z - 33, 100, 66),
  210. m_startPos.y + 10.1f);
  211. EveryNum = 10;
  212. m_moveNum = 0;
  213. m_Score = 0;
  214. m_moveComplete = 0;
  215. m_curUndo = 0;
  216. m_undos[0].LbFrom = 0;
  217. m_undos[0].LbTo = 0;
  218. m_undos[0].MoveCardNum = 0;
  219. m_curMoveEvery = 0;
  220. m_curTip = 0;
  221. EveryDis = (BoardRect2D.width - CardWidth * EveryNum) / 11; //利用总距离减去牌的总宽度
  222. //先清除所有链表中数据
  223. for(int i = 0; i < EveryNum; i++)
  224. {
  225. m_cardEverys[i].m_cards.clear();
  226. m_cardEverys[i].m_maxMoveNum = 0;
  227. m_cardEverys[i].m_index = i;
  228. }
  229. m_cardsDealLeft.clear();
  230. m_movingCards.clear();
  231. 104张牌数组
  232. int level = Rand()%2+1;
  233. //int level = 1;
  234. if(level == 1)
  235. {
  236. //单色
  237. for(int i = 0; i < 8; i++)
  238. {
  239. for(int j = 1; j <= 13; j++)
  240. {
  241. m_cardsDealLeft.push_back(j);
  242. }
  243. }
  244. }
  245. else if(level == 2)
  246. {
  247. //双色
  248. for(int i = 0; i < 4; i++)
  249. {
  250. for(int j = 1; j <= 26; j++)
  251. {
  252. m_cardsDealLeft.push_back(j);
  253. }
  254. }
  255. }
  256. //else if (level ==3)
  257. //{
  258. // //4
  259. // for(int i=0;i<2;i++)
  260. // {
  261. // for(int j=1;j<=52;j++)
  262. // {
  263. // m_cardsDealLeft.push_back(j);
  264. // }
  265. // }
  266. //}
  267. 刷牌: 随机i-1中的任意一个数与i交换
  268. //for (int i = 2; i < 104; i++)
  269. //{
  270. // int ran = Rand()%i;
  271. // char temp = m_cardsDealLeft[ran];
  272. // m_cardsDealLeft[ran] = m_cardsDealLeft[i];
  273. // m_cardsDealLeft[i] = temp;
  274. //}
  275. //设置10个列的牌
  276. while(true)
  277. {
  278. if(m_cardsDealLeft.size() == 60)
  279. break;
  280. for(int i = 0; i < EveryNum; i++)
  281. {
  282. if(m_cardsDealLeft.size() == 60)
  283. break;
  284. m_cardEverys[i].m_cards.push_back(m_cardsDealLeft.back());
  285. m_cardsDealLeft.pop_back();
  286. }
  287. }
  288. DebugCheck();
  289. //给每列未翻的牌个数赋值
  290. for(int i = 0; i < EveryNum; i++)
  291. {
  292. if (m_cardEverys[i].m_cards.size()>0)
  293. {
  294. m_cardEverys[i].m_backNum = m_cardEverys[i].m_cards.size()-1;
  295. }
  296. else
  297. {
  298. m_cardEverys[i].m_backNum = 0;
  299. }
  300. }
  301. //给剩余发牌次数和已完成列牌次数赋值
  302. m_dealLeft = 6;
  303. m_moveComplete = 0;
  304. //分数和拖动数重新计算
  305. m_Score = 500;
  306. m_moveNum = 0;
  307. OnDeal();
  308. //进入miniplaygui,(选人、选关卡都已在房间里进行完毕)。
  309. if(GetStyle()) G_GuiMgr->PushGui(GetStyle()->playGUI.c_str(),GL_DIALOG);
  310. //
  311. for(int i = 0; i < m_allPlayerNum; i++)
  312. {
  313. if(m_miniPlayer[i])
  314. m_miniPlayer[i]->Start();
  315. }
  316. //设置摄像机
  317. CameraCtrlerTarget* ctrler = new CameraCtrlerTarget;
  318. ctrler->SetDistToTar(60);
  319. ctrler->SetTarPos(m_startPos);
  320. G_Camera->PushCtrler(ctrler);
  321. G_Camera->SetEuler(0, -60, 0);
  322. //片头摄像机
  323. PushIntroCamera();
  324. return true;
  325. }
  326. MiniPlayer* MiniGameSpiderPoker::CreatePlayer()
  327. {
  328. return NULL;//new ChessPlayer;
  329. }
  330. MiniPlayer* MiniGameSpiderPoker::CreateRobot()
  331. {
  332. return NULL;// new ChessPlayerRobot;
  333. }
  334. MiniPlayer* MiniGameSpiderPoker::CreateRole()
  335. {
  336. //m_myRolePlayer = NULL;//new ChessPlayerRole;
  337. //return m_myRolePlayer;
  338. return NULL;
  339. }
  340. bool MiniGameSpiderPoker::Stop()
  341. {
  342. {
  343. if(m_myPlayer && m_myPlayer->m_liveNum > 0)
  344. {
  345. G_GuiMgr->GetGui<Rpg_ResultDialog>()->ShowResult(true);
  346. }
  347. else
  348. {
  349. G_GuiMgr->GetGui<Rpg_ResultDialog>()->ShowResult(false);
  350. }
  351. G_GuiMgr->PushGui("Rpg_ResultDialog", GL_DIALOGBOTTOM);
  352. }
  353. return MiniGame::Stop();
  354. }
  355. bool MiniGameSpiderPoker::Update()
  356. {
  357. SetBoardRect(RectF(100, 100, G_Window->m_iWidth-200, G_Window->m_iHeight-200),
  358. RectF(m_startPos.x - 50, m_startPos.z - 33, 100, 66),
  359. m_startPos.y + 10.1f);
  360. EveryDis = (BoardRect2D.width - CardWidth * 10) / 11; //利用总距离减去牌的总宽度
  361. if(m_3dMode)
  362. {
  363. m_movieScene->Advance();
  364. }
  365. if(G_Keyboard->IsKeyUping(DIK_Z) && G_Keyboard->IsKeyPressed(DIK_LCONTROL))
  366. {
  367. OnUndo();
  368. }
  369. if(m_gameStatus == Playing)
  370. {
  371. vec2 pos = this->GetMousePos();
  372. //if (G_Mouse->IsButtonPressed(MOUSE_LEFT))
  373. {
  374. RectF rect;
  375. //提示
  376. rect.x = BoardRect2D.x + BoardRect2D.width / 2 - 100;
  377. rect.y = DOWNPOS - 100;
  378. rect.width = 200;
  379. rect.height = 100;
  380. if(rect.IsPointIn(pos))
  381. {
  382. m_tipButton = true;
  383. }
  384. else
  385. {
  386. m_tipButton = false;
  387. }
  388. //发牌
  389. rect.x = BoardRect2D.x + BoardRect2D.width - EveryDis - (m_dealLeft - 1) * CARDDIS_BACK - CardWidth;
  390. rect.y = DOWNPOS - CardHeight;
  391. rect.width = CardWidth;
  392. rect.height = CardHeight;
  393. if(rect.IsPointIn(pos))
  394. {
  395. m_dealButton = true;
  396. }
  397. else
  398. {
  399. m_dealButton = false;
  400. }
  401. }
  402. if(G_Mouse->IsButtonDowning(MOUSE_LEFT))
  403. {
  404. //拖动牌
  405. RectF rect;
  406. for(int m = 0; m < EveryNum; m++)
  407. {
  408. //得到需要跟随牌的个数
  409. m_curMoveNum = GetMoveCardNum(&m_cardEverys[m], pos);
  410. //按下点在矩形区域内,并且当前列有元素
  411. if(m_curMoveNum > 0)
  412. {
  413. m_curMoveEvery = &m_cardEverys[m];
  414. //计算鼠标点和拖动牌左上角坐标的距离
  415. GetTwoPointJL(m_curMoveEvery, pos);
  416. int nCount = m_curMoveEvery->m_cards.size();
  417. //删除指定列中被拖动的牌
  418. for(int i = 1; i <= m_curMoveNum; i++)
  419. {
  420. m_movingCards.push_back(m_curMoveEvery->m_cards.at(nCount - i));
  421. m_curMoveEvery->DeleteCard(nCount - i);
  422. }
  423. break;
  424. }
  425. }
  426. //提示
  427. if(m_tipButton)
  428. {
  429. OnTip();
  430. m_gameStatus = Tiping;
  431. m_stateAccumeTime = 0;
  432. }
  433. //发牌
  434. if(m_dealButton)
  435. {
  436. OnDeal();
  437. }
  438. }
  439. if(G_Mouse->IsButtonUping(MOUSE_LEFT))
  440. {
  441. if(m_movingCards.size() > 0)
  442. {
  443. RectF rectSave; //可以接收列的范围
  444. RectF rectCard; //列牌可拖动的矩形区域
  445. bool bMoveSuccess = false; //是否在当前列中加了临时数组的牌
  446. for(int i = 0; i < EveryNum; i++)
  447. {
  448. Every* it = &m_cardEverys[i];
  449. //计算可接收拖动牌的范围
  450. GetRecvRect(it, rectCard);
  451. rectSave.x = rectCard.x - EveryDis / 2;
  452. rectSave.width = rectCard.width + EveryDis;
  453. rectSave.y = rectCard.y;
  454. rectSave.height = rectCard.height + CardHeight;
  455. int nCount = it->m_cards.size();
  456. int nCount1 = m_movingCards.size();
  457. if (rectSave.IsPointIn(pos))
  458. {
  459. if((nCount == 0 || m_curMoveEvery == it))
  460. {
  461. bMoveSuccess = true;
  462. }
  463. else
  464. {
  465. int toCard = -1;
  466. if(nCount > 0)
  467. toCard = it->m_cards.at(nCount - 1);
  468. int moveCard = m_movingCards.at(nCount1 - 1);
  469. if( toCard == (moveCard + 1)
  470. || toCard == (moveCard + 1 + 13)
  471. || toCard == (moveCard + 1 - 13)
  472. )
  473. {
  474. bMoveSuccess = true;
  475. }
  476. }
  477. }
  478. if(bMoveSuccess)
  479. {
  480. //在新列牌中加入拖动过来的牌
  481. for(int j = m_movingCards.size(); j > 0; j--)
  482. {
  483. it->PushCard(m_movingCards.at(j - 1));
  484. }
  485. AddScreen(m_curMoveEvery->m_index, i, m_movingCards.size(), m_curMoveEvery->m_backNum);
  486. //移完翻牌
  487. if(m_curMoveEvery->m_cards.size() == m_curMoveEvery->m_backNum
  488. && m_curMoveEvery->m_backNum > 0)
  489. {
  490. m_curMoveEvery->m_backNum -= 1;
  491. }
  492. m_curMoveEvery->CalMaxMoveNum();
  493. //分数和拖动牌次数更新
  494. if(it != m_curMoveEvery)
  495. {
  496. m_moveNum++;
  497. m_Score --;
  498. }
  499. //收牌
  500. IsCardAccess(it);
  501. break;
  502. }
  503. }
  504. //拖动失败
  505. if(bMoveSuccess == false)
  506. {
  507. for(int j = m_movingCards.size(); j > 0; j--)
  508. m_curMoveEvery->PushCard(m_movingCards.at(j - 1));
  509. }
  510. //清空拖动牌
  511. m_movingCards.clear();
  512. }
  513. }
  514. }
  515. return true;
  516. }
  517. bool MiniGameSpiderPoker::Free()
  518. {
  519. MiniGame::Free();
  520. return true;
  521. }
  522. void MiniGameSpiderPoker::DebugCheck()
  523. {
  524. return;
  525. for(int c = 1; c <= 26; c++)
  526. {
  527. int num = 0;
  528. for(int i = 0; i < 10; i++)
  529. {
  530. for(int j = 0; j < m_cardEverys[i].m_cards.size(); j++)
  531. {
  532. if(m_cardEverys[i].m_cards[j] == c)
  533. {
  534. num++;
  535. }
  536. }
  537. }
  538. for(int j = 0; j < m_cardsDealLeft.size(); j++)
  539. {
  540. if(m_cardsDealLeft[j] == c)
  541. {
  542. num++;
  543. }
  544. }
  545. if(num != (8 - m_moveComplete) && num != 0)
  546. {
  547. int a = 0;
  548. }
  549. }
  550. }
  551. int Value2CardID(int value)
  552. {
  553. if(value == 1)
  554. {
  555. return HONGTA;
  556. }
  557. else if(2 <= value && value <= 13)
  558. {
  559. return HONGT2 + value - 2;
  560. }
  561. else if(value == 14)
  562. {
  563. return HEITA;
  564. }
  565. else if(15 <= value && value <= 26)
  566. {
  567. return HEIT2 + value - 15;
  568. }
  569. return JokerBig;
  570. };
  571. bool MiniGameSpiderPoker::Render()
  572. {
  573. if(m_3dMode)
  574. {
  575. G_RendDriver->EndUI();
  576. if(m_movieScene == NULL
  577. || m_movieScene->IsLoadComplete() == false)
  578. return false;
  579. m_movieScene->RendClip();
  580. G_RendDriver->PushMatrix();
  581. G_RendDriver->MultMatrix(mat2Dto3D);
  582. if(G_ShaderMgr && G_ShaderMgr->m_curEffect)
  583. {
  584. G_ShaderMgr->m_picked = false;
  585. //todo 每个物体单独设置 没必要
  586. //G_ShaderMgr->m_doReceiveShadow = m_doReceiveShadow;
  587. G_ShaderMgr->MapChangeParm();
  588. }
  589. }
  590. else
  591. {
  592. G_RendDriver->BeginUI();
  593. if(G_ShaderMgr && G_ShaderMgr->m_curEffect)
  594. {
  595. G_ShaderMgr->m_picked = false;
  596. //todo 每个物体单独设置 没必要
  597. //G_ShaderMgr->m_doReceiveShadow = m_doReceiveShadow;
  598. G_ShaderMgr->MapChangeParm();
  599. }
  600. //背景
  601. G_RendDriver->ShaderColor4f(1, 1, 1, 1);
  602. G_RendDriver->SetRenderStateEnable(RS_DEPTH_TEST, false);
  603. m_texBack->Bind();
  604. G_RendDriver->DrawTextureRect(BoardRect2D);
  605. }
  606. //10列牌的槽位
  607. G_RendDriver->ShaderColor4f(1, 1, 1, 1);
  608. m_texCardSlot->Bind();
  609. for(int i = 0; i < EveryNum; i++)
  610. {
  611. if(m_cardEverys[i].m_cards.size()==0)
  612. {
  613. G_RendDriver->DrawTextureRect(m_cardEverys[i].CardRect(0));
  614. }
  615. }
  616. //显示分数和点击数
  617. //brush.CreateSolidBrush(RGB(0,255,150));
  618. //画矩形
  619. if(m_gameStatus == Playing && m_tipButton)
  620. {
  621. G_RendDriver->ShaderColor4f(0, 1, 0, 1);
  622. }
  623. else
  624. {
  625. G_RendDriver->ShaderColor4f(1, 1, 1, 1);
  626. }
  627. G_RendDriver->DrawTextureRect(RectF(BoardRect2D.x+BoardRect2D.width / 2 - 100,
  628. DOWNPOS - 100,
  629. 200, 100));
  630. G_RendDriver->ShaderColor4f(1, 1, 1, 1);
  631. String str;
  632. str.format("score: %d", m_Score);
  633. G_FontMgr->TextAtPos(vec2(BoardRect2D.x+BoardRect2D.width / 2 - 30, DOWNPOS - 80), str.c_str()); //显示分数
  634. str.format("move: %d", m_moveNum);
  635. G_FontMgr->TextAtPos(vec2(BoardRect2D.x+BoardRect2D.width / 2 - 30, DOWNPOS - 60), str.c_str()); //显示操作数
  636. //显示所有牌
  637. {
  638. //绘制10列牌
  639. for(int m = 0; m < EveryNum; m++)
  640. {
  641. //未翻的牌
  642. if (m_openPoker)//作弊显示翻开
  643. {
  644. G_RendDriver->ShaderColor4f(0.3f, 1, 0.5f, 1);
  645. }
  646. else
  647. {
  648. G_RendDriver->ShaderColor4f(1, 1, 1, 1);
  649. }
  650. int backNum = m_cardEverys[m].m_backNum;
  651. m_texCardBack->Bind();
  652. for(int i = 0; i < backNum; i++)
  653. {
  654. if (m_openPoker)//作弊显示翻开
  655. {
  656. m_texCards[Value2CardID(m_cardEverys[m].m_cards[i])]->Bind();
  657. }
  658. G_RendDriver->DrawTextureRect(m_cardEverys[m].CardRect(i));
  659. }
  660. //翻开的牌
  661. G_RendDriver->ShaderColor4f(1, 1, 1, 1);
  662. int frontNum = m_cardEverys[m].m_cards.size() - backNum;
  663. for(int i = 0; i < frontNum; i++)
  664. {
  665. m_texCards[Value2CardID(m_cardEverys[m].m_cards[backNum + i])]->Bind();
  666. G_RendDriver->DrawTextureRect(m_cardEverys[m].CardRect(i+backNum));
  667. }
  668. }
  669. //下面可发牌
  670. m_texCardBack->Bind();
  671. for(int i = 0; i < m_dealLeft; i++)
  672. {
  673. if(i == m_dealLeft - 1 && m_gameStatus == Playing && m_dealButton)
  674. {
  675. G_RendDriver->ShaderColor4f(0, 1, 0, 1);
  676. }
  677. else
  678. {
  679. G_RendDriver->ShaderColor4f(1, 1, 1, 1);
  680. }
  681. int x = BoardRect2D.x + BoardRect2D.width - EveryDis - i * CARDDIS_BACK - CardWidth;
  682. int y = DOWNPOS - CardHeight;
  683. G_RendDriver->DrawTextureRect(RectF(x, y, CardWidth, CardHeight));
  684. }
  685. G_RendDriver->ShaderColor4f(1, 1, 1, 1);
  686. //左下已完成列
  687. for(int i = 0; i < m_moveComplete; i++)
  688. {
  689. if(m_cardsComplete.at(i) == 1)
  690. m_texCards[HONGTK]->Bind();
  691. else
  692. m_texCards[HEITK]->Bind();
  693. int x = BoardRect2D.x + EveryDis + i * CARDDIS_BACK;
  694. int y = DOWNPOS - CardHeight;
  695. G_RendDriver->DrawTextureRect(RectF(x, y, CardWidth, CardHeight));
  696. }
  697. int moveNum = m_movingCards.size();
  698. vec2 point = this->GetMousePos();
  699. //拖动的牌
  700. for(int i = 0; i < moveNum; i++)
  701. {
  702. m_texCards[Value2CardID(m_movingCards[moveNum - i - 1])]->Bind();
  703. G_RendDriver->DrawTextureRect(RectF(point.x - m_moveOffset.x, point.y + i * CARDDIS_FRONT - m_moveOffset.y, CardWidth, CardHeight));
  704. }
  705. }
  706. m_stateAccumeTime += G_Timer->GetStepTimeLimited();
  707. if(m_gameStatus == Tiping)
  708. {
  709. if(m_stateAccumeTime > 1)
  710. {
  711. m_gameStatus = Playing;
  712. m_stateAccumeTime = 0;
  713. }
  714. G_RendDriver->ShaderColor4f(0, 1, 0, 1);
  715. if(m_tipMoves.size() != 0)
  716. {
  717. //取得需特殊显示牌信息
  718. Every* List1 = &m_cardEverys[m_tipMoves.at(3 * m_curTip)]; //得到当前列数
  719. Every* List2 = &m_cardEverys[m_tipMoves.at(3 * m_curTip + 1)]; //得到对比列数
  720. int moveNum = m_tipMoves.at(3 * m_curTip + 2);
  721. int count1 = List1->m_cards.size(); //计算当前列元素个数
  722. //特殊显示主列牌
  723. for(int i = 0; i <= moveNum - 1; i++)
  724. {
  725. int val = List1->CardAt(count1 - moveNum + i);
  726. m_texCards[Value2CardID(val)]->Bind();
  727. G_RendDriver->DrawTextureRect(List1->CardRect(count1 - moveNum + i));
  728. }
  729. //特殊显示对比列牌
  730. int count2 = List2->m_cards.size(); //计算对比列元素个数
  731. if (count2>0)
  732. {
  733. int val = List2->CardAt(count2 - 1);
  734. m_texCards[Value2CardID(val)]->Bind();
  735. }
  736. else
  737. {
  738. m_texCardSlot->Bind();
  739. }
  740. G_RendDriver->DrawTextureRect(List2->CardRect(count2 - 1));
  741. }
  742. G_RendDriver->ShaderColor4f(1, 1, 1, 1);
  743. }
  744. if(m_gameStatus == Dealing)
  745. {
  746. if(m_curDealEvery->m_index >= EveryNum-1)
  747. {
  748. m_gameStatus = Playing;
  749. m_stateAccumeTime = 0;
  750. DebugCheck();
  751. //发牌次数减少一
  752. m_dealLeft--;
  753. //判断完整列
  754. for(int i = 0; i < EveryNum; i++)
  755. {
  756. IsCardAccess(&m_cardEverys[i]);
  757. }
  758. //清除撤销
  759. m_curUndo = 0;
  760. }
  761. else
  762. {
  763. vec2 oldPoint = m_curDealPoint;
  764. vec2 dif = m_curDealPointEnd - m_curDealPoint;
  765. dif.Normalize();
  766. m_curDealPoint += dif * (G_Timer->GetStepTimeLimited() * 2800);
  767. if((m_curDealPointEnd - m_curDealPoint).Dot(dif) <= 0)
  768. {
  769. m_curDealPoint.x = BoardRect2D.width - EveryDis - (m_dealLeft - 1) * CARDDIS_BACK - CardWidth;
  770. m_curDealPoint.y = DOWNPOS - CardHeight;
  771. m_curDealPointEnd = m_curDealEvery->CardRect(m_curDealEvery->m_cards.size()).GetPos();
  772. //加入发的牌
  773. m_curDealEvery->PushCard(m_cardsDealLeft.back());
  774. m_cardsDealLeft.pop_back();
  775. m_sound->PlaySound__("data/sound/poker/deal.wav");
  776. m_curDealEvery++;
  777. if(m_cardsDealLeft.size() > 0)
  778. {
  779. m_curDealCardVal = m_cardsDealLeft.back();
  780. }
  781. else
  782. {
  783. m_gameStatus = Playing;
  784. m_stateAccumeTime = 0;
  785. m_dealLeft = 0;
  786. //判断完整列
  787. for(int i = 0; i < EveryNum; i++)
  788. {
  789. IsCardAccess(&m_cardEverys[i]);
  790. }
  791. //清除撤销
  792. m_curUndo = 0;
  793. }
  794. }
  795. m_texCards[Value2CardID(m_curDealCardVal)]->Bind();
  796. G_RendDriver->DrawTextureRect(RectF(m_curDealPoint.x, m_curDealPoint.y, CardWidth, CardHeight));
  797. }
  798. }
  799. if(m_gameStatus == Completing)
  800. {
  801. vec2 oldPoint = m_curCompletePoint;
  802. vec2 dif = m_curCompletePointEnd - m_curCompletePoint;
  803. dif.Normalize();
  804. m_curCompletePoint += dif * (G_Timer->GetStepTimeLimited() * 2800);
  805. if((m_curCompletePointEnd - m_curCompletePoint).Dot(dif) <= 0)
  806. {
  807. m_curCompleteCardNum++;
  808. //收完
  809. if(m_curCompleteCardNum >= 13)
  810. {
  811. m_moveComplete += 1;
  812. //更新已完成牌链表
  813. if(m_curCompleteCardVal <= 13)
  814. m_cardsComplete.push_back(1);
  815. else
  816. m_cardsComplete.push_back(-1);
  817. m_curCompleteEvery->m_maxMoveNum -= 13;
  818. m_curUndo = 0;
  819. m_gameStatus = Playing;
  820. m_stateAccumeTime = 0;
  821. //收完翻牌
  822. if(m_curCompleteEvery->m_cards.size() == m_curCompleteEvery->m_backNum
  823. && m_curCompleteEvery->m_backNum > 0)
  824. {
  825. m_curCompleteEvery->m_backNum--;
  826. m_curCompleteEvery->m_maxMoveNum = 1;
  827. }
  828. }
  829. else
  830. {
  831. m_sound->PlaySound__("data/sound/poker/deal.wav");
  832. m_curCompleteCardVal = m_curCompleteEvery->m_cards.back();
  833. //删除最后一张牌
  834. m_curCompleteEvery->m_cards.pop_back();
  835. //计算发牌的起点和终点位置
  836. int nCount = m_curCompleteEvery->m_cards.size();
  837. int nBack = m_curCompleteEvery->m_backNum;
  838. m_curCompletePoint = m_curCompleteEvery->CardRect(m_curCompleteEvery->m_cards.size()).GetPos();
  839. }
  840. }
  841. m_texCards[Value2CardID(m_curCompleteCardVal)]->Bind();
  842. G_RendDriver->DrawTextureRect(RectF(m_curCompletePoint.x, m_curCompletePoint.y, CardWidth, CardHeight));
  843. //绘制已经收好的
  844. if(m_curCompleteCardNum > 0)
  845. {
  846. m_texCards[Value2CardID(m_curCompleteCardVal - 1)]->Bind();
  847. G_RendDriver->DrawTextureRect(RectF(m_curCompletePointEnd.x, m_curCompletePointEnd.y, CardWidth, CardHeight));
  848. }
  849. }
  850. if(m_3dMode)
  851. {
  852. G_RendDriver->PopMatrix();
  853. }
  854. return true;
  855. }
  856. //发牌
  857. bool MiniGameSpiderPoker::OnDeal()
  858. {
  859. if(m_cardsDealLeft.size() <= 0)
  860. {
  861. return false;
  862. }
  863. m_gameStatus = Dealing;
  864. m_stateAccumeTime = 0;
  865. m_curDealEvery = m_cardEverys;
  866. //发牌的起点和终点
  867. m_curDealPoint.x = BoardRect2D.width - EveryDis - (m_dealLeft - 1) * CARDDIS_BACK - CardWidth;
  868. m_curDealPoint.y = DOWNPOS - CardHeight;
  869. m_curDealPointEnd = m_curDealEvery->CardRect(m_curDealEvery->m_cards.size()).GetPos();
  870. return true;
  871. }
  872. //得到每一列牌的可以相应鼠标消息的区域大小
  873. void MiniGameSpiderPoker::GetRecvRect(Every*every, RectF &rect)
  874. {
  875. int nCount = every->m_cards.size();
  876. int maxMove = every->m_maxMoveNum;
  877. int nBack = every->m_backNum;
  878. rect = every->CardRect(every->m_backNum);
  879. rect.height = CardHeight + (maxMove - 1) * CARDDIS_FRONT;
  880. }
  881. //判断拖动的牌的个数
  882. int MiniGameSpiderPoker::GetMoveCardNum(Every*every, const vec2& point)
  883. {
  884. int nCount = every->m_cards.size();
  885. int maxMove = every->m_maxMoveNum;
  886. int nBack = every->m_backNum;
  887. if(nCount == 0)
  888. return 0;
  889. //定义可以移动的矩形最大范围
  890. RectF rect;
  891. for(int i = 0; i < maxMove; i++)
  892. {
  893. rect = every->CardRect(nCount - i - 1);
  894. if(i == 0) //如果鼠标左键点下位置在最上面一张牌上
  895. {
  896. rect.height = CardHeight;
  897. }
  898. else
  899. {
  900. rect.height = CARDDIS_FRONT;
  901. }
  902. if(rect.IsPointIn(point))
  903. return i + 1;
  904. }
  905. return 0;
  906. }
  907. //计算鼠标点和拖动牌左上角坐标的距离
  908. void MiniGameSpiderPoker::GetTwoPointJL(Every*every, const vec2& point)
  909. {
  910. int nCount = every->m_cards.size();
  911. int maxMove = every->m_maxMoveNum;
  912. RectF rect;
  913. for(int i = 0; i < maxMove; i++)
  914. {
  915. rect = every->CardRect(nCount - maxMove + i);
  916. if(maxMove == i)
  917. {
  918. rect.height = CardHeight;
  919. }
  920. else
  921. {
  922. rect.height = CARDDIS_FRONT;
  923. }
  924. if(rect.IsPointIn(point))
  925. {
  926. m_moveOffset.x = point.x - rect.x;
  927. m_moveOffset.y = point.y - rect.y;
  928. return;
  929. }
  930. }
  931. }
  932. bool MiniGameSpiderPoker::OnTip()
  933. {
  934. m_tipMoves.clear();
  935. //提示第一个
  936. //m_curTip = 0;
  937. for(int i = 0; i < EveryNum; i++)
  938. {
  939. int nCount = m_cardEverys[i].m_cards.size();
  940. int nMoveCard = m_cardEverys[i].m_maxMoveNum;
  941. if(nCount == 0)
  942. continue;
  943. int nCountOther = 0;
  944. for(int n = 1; n <= nMoveCard; n++) //对选定列每张可移动牌进行判断
  945. {
  946. for(int j = 0; j < EveryNum; j++) //对选定牌与其他列最后一张牌进行对比
  947. {
  948. nCountOther = m_cardEverys[j].m_cards.size();
  949. if(j == i || nCountOther == 0)
  950. continue;
  951. //如果可移动牌可以移动,依次加入当前列,对比列,当前列与对比列可以移动牌的个数
  952. int ij = m_cardEverys[i].CardAt(nCount - n);
  953. int kc = m_cardEverys[j].CardAt(nCountOther - 1);
  954. if((ij == kc - 1
  955. || ij == kc - 1 - 13
  956. || ij == kc - 1 + 13)
  957. && ij != 13
  958. && ij != 26)
  959. {
  960. //如果提示牌前还有牌
  961. if(nCount - n - 1 >= m_cardEverys[i].m_backNum)
  962. {
  963. int ij_ = m_cardEverys[i].CardAt(nCount - n - 1);
  964. if(ij_ != kc
  965. && ij_ != kc + 13
  966. && ij_ != kc - 13)
  967. {
  968. m_tipMoves.push_back(i);
  969. m_tipMoves.push_back(j);
  970. m_tipMoves.push_back(n);
  971. }
  972. }
  973. else
  974. {
  975. m_tipMoves.push_back(i);
  976. m_tipMoves.push_back(j);
  977. m_tipMoves.push_back(n);
  978. }
  979. }
  980. }
  981. }
  982. }
  983. //如果保存有可移动信息
  984. if(m_tipMoves.size() != 0)
  985. {
  986. m_sound->PlaySound__("data/sound/poker/deal.wav");
  987. //更新显示信息数
  988. m_curTip += 1;
  989. if(m_curTip >= m_tipMoves.size() / 3)
  990. m_curTip = 0;
  991. return true;
  992. }
  993. else
  994. {
  995. m_sound->PlaySound__("data/sound/poker/cannot.wav");
  996. return false;
  997. }
  998. }
  999. //撤消
  1000. void MiniGameSpiderPoker::OnUndo()
  1001. {
  1002. if(m_curUndo == 0)
  1003. return;
  1004. else
  1005. {
  1006. char Lb = m_undos[m_curUndo].LbFrom;
  1007. char LbTo = m_undos[m_curUndo].LbTo;
  1008. char MoveCardNum = m_undos[m_curUndo].MoveCardNum;
  1009. int nBackNum = m_undos[m_curUndo].nBackNum;
  1010. Every* every = &m_cardEverys[Lb];
  1011. Every* everyTo = &m_cardEverys[LbTo];
  1012. int nCount = everyTo->m_cards.size();
  1013. for(int i = 0; i < MoveCardNum; i++)
  1014. {
  1015. //接收列减去移动牌
  1016. int CurrentMoveCard = everyTo->m_cards.at(nCount - MoveCardNum);
  1017. everyTo->DeleteCard(nCount - MoveCardNum);
  1018. //移出牌的列增加移动牌
  1019. every->PushCard(CurrentMoveCard);
  1020. }
  1021. //重新设置发牌列的未翻牌数
  1022. every->m_backNum = nBackNum;
  1023. every->m_maxMoveNum = every->CalMaxMoveNum();
  1024. m_curUndo--;
  1025. }
  1026. }
  1027. //判断某一列牌是否可以收牌
  1028. void MiniGameSpiderPoker::IsCardAccess(Every*every)
  1029. {
  1030. int nCount = every->m_cards.size();
  1031. int maxMove = every->m_maxMoveNum;
  1032. int nBack = every->m_backNum;
  1033. if(nCount - nBack < 13)
  1034. return;
  1035. //定义一个数组,存储1---13数字
  1036. int cardNum[13];
  1037. for(int i = 0; i < 13; i++)
  1038. cardNum[i] = i + 1;
  1039. bool isCardFullRedT = true;
  1040. //利用循环进行判断
  1041. for(int i = nCount; i > nCount - 13; i--)
  1042. {
  1043. if(every->m_cards.at(i - 1) != cardNum[nCount - i])
  1044. {
  1045. isCardFullRedT = false;
  1046. m_curCompleteEvery = every;
  1047. break;
  1048. }
  1049. }
  1050. for(int i = 0; i < 13; i++)
  1051. cardNum[i] = i + 14;
  1052. bool isCardFullBlackT = true;
  1053. for(int i = nCount; i > nCount - 13; i--)
  1054. {
  1055. if(every->m_cards.at(i - 1) != cardNum[nCount - i])
  1056. {
  1057. isCardFullBlackT = false;
  1058. m_curCompleteEvery = every;
  1059. break;
  1060. }
  1061. }
  1062. //收牌(1--1314--26依次存在)
  1063. if(isCardFullRedT || isCardFullBlackT)
  1064. {
  1065. m_curCompleteCardNum = 0;
  1066. m_curCompleteCardVal = m_curCompleteEvery->m_cards.back();
  1067. //将当前列最后一张牌删除
  1068. m_curCompleteEvery->m_cards.pop_back();
  1069. //计算发牌的起点和终点位置
  1070. m_curCompletePoint = m_curCompleteEvery->CardRect(nCount).GetPos();
  1071. m_curCompletePointEnd.x = BoardRect2D.x + EveryDis + m_moveComplete * CARDDIS_BACK;
  1072. m_curCompletePointEnd.y = DOWNPOS - CardHeight;
  1073. m_gameStatus = Completing;
  1074. m_stateAccumeTime = 0;
  1075. m_curUndo = 0;
  1076. }
  1077. }
  1078. bool MiniGameSpiderPoker::IsGameEnd()
  1079. {
  1080. bool IsGameEnd = true;
  1081. for(int i = 0; i < EveryNum; i++)
  1082. {
  1083. if(m_cardEverys[i].m_cards.size() != 0)
  1084. {
  1085. IsGameEnd = false;
  1086. break;
  1087. }
  1088. }
  1089. return IsGameEnd;
  1090. }
  1091. void MiniGameSpiderPoker::AddScreen(char LbFrom, char LbTo, char MoveCardNum, int BackNum)
  1092. {
  1093. if(m_curUndo == m_MaxScreen)
  1094. {
  1095. for(int i = 1; i < m_MaxScreen; i++) //第一个屏幕状态不变,做为一个标志
  1096. m_undos[i] = m_undos[i + 1];
  1097. }
  1098. else
  1099. m_curUndo++;
  1100. m_undos[m_curUndo].LbFrom = LbFrom;
  1101. m_undos[m_curUndo].LbTo = LbTo;
  1102. m_undos[m_curUndo].MoveCardNum = MoveCardNum;
  1103. m_undos[m_curUndo].nBackNum = BackNum;
  1104. }
  1105. int Every::CalMaxMoveNum()
  1106. {
  1107. int cardNum = m_cards.size();
  1108. for(int i = 1; i < cardNum - m_backNum + 1; i++)
  1109. {
  1110. if(IsLessThenTop(cardNum - i) || cardNum == 0)
  1111. continue;
  1112. else
  1113. {
  1114. m_maxMoveNum = i;
  1115. return i;
  1116. }
  1117. }
  1118. m_maxMoveNum = 0;
  1119. return 0;
  1120. }
  1121. bool Every::IsLessThenTop(int index)
  1122. {
  1123. if(index <= m_backNum || (index+1) > m_cards.size())
  1124. return false;
  1125. //如果当前牌比上一张牌小,并且当前牌数不是13,或者这张牌是最后一张牌
  1126. if((m_cards.at(index) == m_cards.at(index - 1) - 1)
  1127. && (m_cards.at(index) != 13) || index == 0)
  1128. return true;
  1129. else
  1130. return false;
  1131. }
  1132. void Every::DeleteCard(int index)
  1133. {
  1134. if(index < 0 || index > m_cards.size() - 1)
  1135. return;
  1136. m_cards.erase(m_cards.begin() + index);
  1137. CalMaxMoveNum();
  1138. }
  1139. void Every::PushCard(int card)
  1140. {
  1141. m_cards.push_back(card);
  1142. CalMaxMoveNum();
  1143. }
  1144. int Every::CardAt(int Index)
  1145. {
  1146. return m_cards[Index];
  1147. }
  1148. RectF Every::CardRect(int index)
  1149. {
  1150. RectF rect;
  1151. rect. x = G_SpiderGame->BoardRect2D.x + G_SpiderGame->EveryDis*(m_index + 1) + CardWidth * m_index;
  1152. if (index < m_backNum)
  1153. {
  1154. //未翻的牌
  1155. rect.y = G_SpiderGame->BoardRect2D.y+30 + index * CARDDIS_BACK;
  1156. }
  1157. else
  1158. {
  1159. //翻开的牌
  1160. rect.y = G_SpiderGame->BoardRect2D.y+30 + m_backNum * CARDDIS_BACK + (index-m_backNum) * CARDDIS_FRONT;
  1161. }
  1162. rect.width = CardWidth;
  1163. rect.height = CardHeight;
  1164. return rect;
  1165. }

完 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/145561
推荐阅读
相关标签
  

闽ICP备14008679号