logic.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. /********************************************************************
  2. created: pinorr
  3. file base: logic.h
  4. author: pinorr Q 505971450
  5. purpose: 跑胡子基本算法
  6. *********************************************************************/
  7. #include "cmd_define.h"
  8. #include <map>
  9. #include <vector>
  10. #include <algorithm>
  11. #include <cmath>
  12. using namespace std;
  13. map<__int64, BYTE> g_mapKeyAll;
  14. #define MAX_ANSWER_NUM 1024
  15. struct stAnswer
  16. {
  17. BYTE num;
  18. __int64 llNode[7];
  19. BYTE byNodeXi[7];
  20. BYTE byIndex[7];
  21. stAnswer() { memset(this, 0, sizeof(*this)); }
  22. __int64 push(__int64 llVal, BYTE index)
  23. {
  24. map<__int64, BYTE>::iterator iter = g_mapKeyAll.find(llVal);
  25. if (iter != g_mapKeyAll.end() && num < 7)
  26. {
  27. byNodeXi[num] = iter->second;
  28. byIndex[num] = index;
  29. llNode[num++] = llVal;
  30. return llVal;
  31. }
  32. return 0;
  33. }
  34. __int64 pop()
  35. {
  36. if (num > 0)
  37. return llNode[--num];
  38. return 0;
  39. }
  40. BYTE getHuXi()
  41. {
  42. BYTE byXi = 0;
  43. for (int i = 0; i < num; ++i)
  44. byXi += byNodeXi[i];
  45. return byXi;
  46. }
  47. };
  48. class CLogicPHZ
  49. {
  50. public:
  51. CLogicPHZ()
  52. {
  53. m_nAnswerNum = 0;
  54. m_nValNum = 0;
  55. m_nNullNum = 0;
  56. //TrainKey();
  57. readConfig("config.txt");
  58. }
  59. bool readConfig(string strFile)
  60. {
  61. m_vctKeyVal.clear();
  62. m_vctKeyNull.clear();
  63. g_mapKeyAll.clear();
  64. char szPath[MAX_PATH] = { 0 };
  65. GetCurrentDirectoryA(MAX_PATH, szPath);
  66. char szFileName[MAX_PATH] = { 0 };
  67. sprintf_s(szFileName, "%s/%s", szPath, strFile.c_str());
  68. FILE *fp;
  69. errno_t err = fopen_s(&fp, szFileName, "r");
  70. if (fp != 0)
  71. {
  72. char szData[900] = { 0 };
  73. // 设置文件起始位置
  74. fseek(fp, 0, SEEK_SET);
  75. while (!feof(fp))
  76. {
  77. memset(szData, 0, sizeof(szData));
  78. vector<string> vctVal;
  79. // 读取一行
  80. fread(szData, sizeof(szData), 1, fp);
  81. for (int i = 0; i < 900; i += 9) {
  82. __int64 lVal = *(__int64 *)&szData[i];
  83. if (lVal == 0)
  84. break;
  85. g_mapKeyAll[lVal] = *(BYTE *)&szData[i + 8];
  86. }
  87. }
  88. fclose(fp);
  89. map<__int64, BYTE>::iterator iter = g_mapKeyAll.begin();
  90. for (; iter != g_mapKeyAll.end(); ++iter)
  91. {
  92. if (getNumByKey(iter->first) <= 2) continue;
  93. if (iter->second == 0) {
  94. m_mapKeyIndex[iter->first] = 158 + m_vctKeyNull.size();
  95. m_vctKeyNull.push_back(iter->first);
  96. }
  97. else {
  98. m_mapKeyIndex[iter->first] = m_vctKeyVal.size();
  99. m_vctKeyVal.push_back(iter->first);
  100. }
  101. }
  102. m_nValNum = m_vctKeyVal.size();
  103. m_nNullNum = m_vctKeyNull.size();
  104. return true;
  105. }
  106. return false;
  107. }
  108. int getHuKeyInit(BYTE *cbCards, BYTE num, BYTE byThreshXi, bool bFindAll = false)
  109. {
  110. m_byThreshXi = byThreshXi;
  111. __int64 llVal = 0;
  112. for (int i = 0; i < num; ++i)
  113. {
  114. BYTE index = getIndexByVal(cbCards[i]);
  115. if (index >= MAX_TYPE) return false;
  116. llVal += (__int64)1 << (3 * index);
  117. }
  118. if (getCardsNum(llVal, 20) > 4)
  119. return 0;
  120. vector<BYTE> vctIndex3;
  121. stAnswer answer;
  122. for (int i = 0; i < 20; ++i)
  123. {
  124. BYTE num = getCardsNum(llVal, i);
  125. if (num == 4)
  126. {
  127. __int64 llNode = (__int64)4 << (i * 3);
  128. map<__int64, BYTE>::iterator iter = m_mapKeyIndex.find(llNode);
  129. if (iter == m_mapKeyIndex.end())
  130. continue; // 不可能到此
  131. answer.push(llNode, iter->second);
  132. llVal -= llNode;
  133. }
  134. else if (num == 3)
  135. {
  136. vctIndex3.push_back(i);
  137. llVal -= __int64((__int64)3 << (i * 3));
  138. }
  139. }
  140. m_nAnswerNum = 0;
  141. BYTE nKing = getCardsNum(llVal, 20);
  142. BYTE nNum3 = vctIndex3.size();
  143. for (int flag = 0; flag < ((int)1 << nNum3); ++flag)
  144. {
  145. if (!bFindAll && m_nAnswerNum > 0)
  146. return m_nAnswerNum;
  147. BYTE nNum = 0;
  148. for (int i = 0; i < 8; ++i)
  149. nNum += (flag >> i) & 1;
  150. if (nNum > nKing) continue;
  151. __int64 llTemp = llVal;
  152. stAnswer stTemp = answer;
  153. for (size_t i = 0; i < vctIndex3.size(); ++i)
  154. {
  155. __int64 llNode = (__int64)3 << (vctIndex3[i] * 3);
  156. if (flag & (1 << i)) {
  157. llNode += (__int64)1 << 60;
  158. llTemp -= (__int64)1 << 60;
  159. }
  160. map<__int64, BYTE>::iterator iter = m_mapKeyIndex.find(llNode);
  161. if (iter == m_mapKeyIndex.end())
  162. continue; // 不可能到此
  163. stTemp.push(llNode, iter->second);
  164. }
  165. getHuKey(llTemp, byThreshXi, stTemp, 0, bFindAll);
  166. }
  167. return m_nAnswerNum;
  168. }
  169. void getHuKey(__int64 llVal, BYTE byThreshXi, stAnswer &answer, int nBegin, bool bFindAll)
  170. {
  171. if (m_nAnswerNum >= MAX_ANSWER_NUM)
  172. return;
  173. if (!bFindAll && m_nAnswerNum > 0)
  174. return;
  175. BYTE byLeft = getNumByKey(llVal);
  176. if (byLeft == 0){
  177. if (answer.getHuXi() >= byThreshXi)
  178. m_answer[m_nAnswerNum++] = answer;
  179. return;
  180. }
  181. else if (byLeft % 3 == 1){
  182. return;
  183. }
  184. else if (byLeft == 3 || byLeft == 2){
  185. map<__int64, BYTE>::iterator iter = g_mapKeyAll.find(llVal);
  186. if (iter != g_mapKeyAll.end())
  187. {
  188. iter = m_mapKeyIndex.find(llVal);
  189. BYTE index = iter != m_mapKeyIndex.end() ? iter->second : 0xFF;
  190. answer.push(llVal, index);
  191. if (answer.getHuXi() >= byThreshXi)
  192. m_answer[m_nAnswerNum++] = answer;
  193. answer.pop();
  194. }
  195. return;
  196. }
  197. else{
  198. int i = nBegin;
  199. //回溯有息牌组
  200. for (; i < m_nValNum; ++i)
  201. {
  202. if (isContainKey(llVal, m_vctKeyVal[i]))
  203. {
  204. llVal -= answer.push(m_vctKeyVal[i], i);
  205. BYTE byNum = getNumByKey(llVal);
  206. getHuKey(llVal, byThreshXi, answer, i, bFindAll);
  207. llVal += answer.pop();
  208. }
  209. }
  210. if (answer.getHuXi() <= byThreshXi)
  211. return;
  212. BYTE byNum = getNumByKey(llVal);
  213. if (byNum == 0)
  214. m_answer[m_nAnswerNum++] = answer;
  215. else if (byNum == 1)
  216. return;
  217. else
  218. {
  219. //回溯无息牌组
  220. i -= m_nValNum;
  221. for (; i < m_nNullNum; ++i)
  222. {
  223. if (isContainKey(llVal, m_vctKeyNull[i]))
  224. {
  225. llVal -= answer.push(m_vctKeyNull[i], i + m_nValNum);
  226. BYTE byNum = getNumByKey(llVal);
  227. getHuKey(llVal, byThreshXi, answer, i + m_nValNum, bFindAll);
  228. llVal += answer.pop();
  229. }
  230. }
  231. }
  232. }
  233. }
  234. // 此处需过滤重复的答案
  235. void getAnswer(vector<stAnswer> &vctOut)
  236. {
  237. if (m_nAnswerNum > 0 && m_nAnswerNum < MAX_ANSWER_NUM)
  238. {
  239. int answer_num = 0;
  240. stAnswer answer_temp[MAX_ANSWER_NUM];
  241. map<string, BYTE> mapFlag;
  242. char chrTemp[1024] = {};
  243. for (int i = 0; i < m_nAnswerNum; ++i) {
  244. stAnswer temp = m_answer[i];
  245. sort(temp.byIndex, temp.byIndex + 7);
  246. sprintf_s(chrTemp, "%02X%02X%02X%02X%02X%02X%02X", (int)temp.byIndex[0], (int)temp.byIndex[1], (int)temp.byIndex[2],
  247. (int)temp.byIndex[3], (int)temp.byIndex[4], (int)temp.byIndex[5], (int)temp.byIndex[6]);
  248. map<string, BYTE>::iterator iter = mapFlag.find(chrTemp);
  249. if (iter == mapFlag.end()) {
  250. mapFlag[chrTemp] = 1;
  251. answer_temp[answer_num++] = m_answer[i];
  252. }
  253. else
  254. continue;
  255. }
  256. vctOut.resize(answer_num);
  257. memcpy(&vctOut[0], answer_temp, answer_num*sizeof(stAnswer));
  258. }
  259. }
  260. private:
  261. inline void addMapVal(__int64 llKey, BYTE val)
  262. {
  263. BYTE num = getNumByKey(llKey);
  264. if (g_mapKeyAll[llKey] < val)
  265. g_mapKeyAll[llKey] = val;
  266. }
  267. private:
  268. int m_nAnswerNum;
  269. stAnswer m_answer[MAX_ANSWER_NUM];
  270. vector<__int64> m_vctKeyVal; // 158
  271. vector<__int64> m_vctKeyNull; // 72
  272. map<__int64, BYTE> m_mapKeyIndex; // 72+158
  273. int m_nValNum;
  274. int m_nNullNum;
  275. BYTE m_byThreshXi;
  276. };