当前位置:   article > 正文

基于蒙特卡洛树搜索思想的中国象棋AI-C++实现

基于蒙特卡洛树搜索思想的中国象棋AI-C++实现
  1. /*象棋ai*/
  2. #pragma GCC optimize(1)
  3. #pragma GCC optimize(2)
  4. #pragma GCC optimize(3)
  5. #pragma GCC optimize("Ofast")
  6. #pragma GCC optimize("inline")
  7. #pragma GCC optimize("-fgcse")
  8. #pragma GCC optimize("-fgcse-lm")
  9. #pragma GCC optimize("-fipa-sra")
  10. #pragma GCC optimize("-ftree-pre")
  11. #pragma GCC optimize("-ftree-vrp")
  12. #pragma GCC optimize("-fpeephole2")
  13. #pragma GCC optimize("-ffast-math")
  14. #pragma GCC optimize("-fsched-spec")
  15. #pragma GCC optimize("unroll-loops")
  16. #pragma GCC optimize("-falign-jumps")
  17. #pragma GCC optimize("-falign-loops")
  18. #pragma GCC optimize("-falign-labels")
  19. #pragma GCC optimize("-fdevirtualize")
  20. #pragma GCC optimize("-fcaller-saves")
  21. #pragma GCC optimize("-fcrossjumping")
  22. #pragma GCC optimize("-fthread-jumps")
  23. #pragma GCC optimize("-funroll-loops")
  24. #pragma GCC optimize("-freorder-blocks")
  25. #pragma GCC optimize("-fschedule-insns")
  26. #pragma GCC optimize("inline-functions")
  27. #pragma GCC optimize("-ftree-tail-merge")
  28. #pragma GCC optimize("-fschedule-insns2")
  29. #pragma GCC optimize("-fstrict-aliasing")
  30. #pragma GCC optimize("-falign-functions")
  31. #pragma GCC optimize("-fcse-follow-jumps")
  32. #pragma GCC optimize("-fsched-interblock")
  33. #pragma GCC optimize("-fpartial-inlining")
  34. #pragma GCC optimize("no-stack-protector")
  35. #pragma GCC optimize("-freorder-functions")
  36. #pragma GCC optimize("-findirect-inlining")
  37. #pragma GCC optimize("-fhoist-adjacent-loads")
  38. #pragma GCC optimize("-frerun-cse-after-loop")
  39. #pragma GCC optimize("inline-small-functions")
  40. #pragma GCC optimize("-finline-small-functions")
  41. #pragma GCC optimize("-ftree-switch-conversion")
  42. #pragma GCC optimize("-foptimize-sibling-calls")
  43. #pragma GCC optimize("-fexpensive-optimizations")
  44. #pragma GCC optimize("inline-functions-called-once")
  45. #pragma GCC optimize("-fdelete-null-pointer-checks")
  46. #include<bits/stdc++.h>
  47. #include<random>
  48. #include<ctime>
  49. #include<windows.h>
  50. #include<omp.h>
  51. #define pll pair<int,int>
  52. using namespace std;
  53. typedef double lf;
  54. const int N=3e6;
  55. static default_random_engine e;
  56. struct Chess {
  57. int des[10][9];
  58. };
  59. int maxnumcore;
  60. int maxstep=6;
  61. int maxcal=5000;
  62. int thinktime=100;
  63. int nodelimt=6;
  64. int siz=0;
  65. vector<int> datree[N];
  66. Chess chess[N];
  67. int fa[N],dep[N],mark[N],endpo[N],roval[N],del[N];
  68. lf n[N],w[N],winrate[N];
  69. int qzw[32] = { -100,-3,-3,-3,-3,-7,-7,-15,-15,-10,-10,-1,-1,-1,-1,-1,100,3,3,3,3,7,7,15,15,10,10,1,1,1,1,1 };
  70. pair<int, int> limx[16] = { {0,2},{0,2},{0,2},{0,4},{0,4},{0,9},{0,9},{0,9},{0,9},{0,9},{0,9},{0,9},{0,9},{0,9},{0,9},{0,9}};
  71. pair<int, int> limy[16] = { {3,5},{3,5},{3,5},{0,8},{0,8},{0,8},{0,8},{0,8},{0,8},{0,8},{0,8},{0,8},{0,8},{0,8},{0,8},{0,8}};
  72. Chess prec;
  73. class cheess{
  74. public:
  75. lf c = 2;
  76. pair<int, int> POS[32];
  77. Chess base;
  78. inline int calval(Chess&u){
  79. int cn=0;
  80. for(int i=0;i<10;i++)for(int j=0;j<9;j++)
  81. if(u.des[i][j]>=0)cn+=qzw[u.des[i][j]];
  82. return cn;
  83. }
  84. void init() {
  85. POS[0] = { 0,4 }; POS[1] = { 0,3 }; POS[2] = { 0,5 }; POS[3] = { 0,2 }; POS[4] = { 0,6 };
  86. POS[5] = { 0,1 }; POS[6] = { 0,7 }; POS[7] = { 0,0 }; POS[8] = { 0,8 }; POS[9] = { 2,1 };
  87. POS[10] = { 2,7 }; POS[11] = { 3,0 }; POS[12] = { 3,2 }; POS[13] = { 3,4 }; POS[14] = { 3,6 };
  88. POS[15] = { 3,8 }; POS[16] = { 9,4 }; POS[17] = { 9,5 }; POS[18] = { 9,3 }; POS[19] = { 9,6 };
  89. POS[20] = { 9,2 }; POS[21] = { 9,7 }; POS[22] = { 9,1 }; POS[23] = { 9,8 }; POS[24] = { 9,0 };
  90. POS[25] = { 7,7 }; POS[26] = { 7,1 }; POS[31] = { 6,0 }; POS[30] = { 6,2 }; POS[29] = { 6,4 };
  91. POS[28] = { 6,6 }; POS[27] = { 6,8 };
  92. for (int i = 0; i < 10; i++)for (int j = 0; j < 9; j++)base.des[i][j] = -1;
  93. for (int i = 0; i < 32; i++) base.des[POS[i].first][POS[i].second] = i;
  94. //base.des[6][0]=base.des[6][2]=base.des[6][4]=base.des[6][6]=base.des[6][8]=-1;
  95. //base.des[3][0]=base.des[3][2]=base.des[3][4]=base.des[3][6]=base.des[3][8]=-1;
  96. }
  97. inline int Checkend(Chess &u){//查看是否结局
  98. int x=1;
  99. for(int i=limx[0].first;i<=limx[0].second;i++)
  100. for(int j=limy[0].first;j<=limy[0].second;j++)
  101. if(u.des[i][j]==0)x=0;
  102. return x;
  103. }
  104. inline Chess rev(Chess& a) {//局面旋转
  105. Chess k;
  106. for(int i=0;i<10;i++)for(int j=0;j<9;j++)k.des[i][j]=-1;
  107. for (int i = 0; i < 10; i++)for (int j = 0; j < 9; j++){
  108. if(a.des[9 - i][8 - j]>15)k.des[i][j] = a.des[9 - i][8 - j]-16;
  109. else if(a.des[9 - i][8 - j]>=0)k.des[i][j] = a.des[9 - i][8 - j]+16;
  110. }
  111. return k;
  112. }
  113. inline Chess Creatdes(int posxi, int posyi, int posx, int posy, Chess p) {//根据走子建立新局面
  114. int i = p.des[posxi][posyi];
  115. p.des[posx][posy] = i;
  116. p.des[posxi][posyi] = -1;
  117. return rev(p);
  118. }
  119. inline void creatnode(int u,Chess&son) {//建立节点
  120. int k=++siz;
  121. datree[u].push_back(k);
  122. datree[k].clear();
  123. fa[k]=u;
  124. chess[k]=son;
  125. w[k]=n[k]=winrate[k]=0;
  126. dep[k]=dep[u] + 1;
  127. mark[k]=!mark[u];
  128. endpo[k]=roval[k]=del[k]=0;
  129. }
  130. inline int judge(Chess& u, int i, int posx, int posy) {
  131. if (i == 0 && u.des[posx][posy] == 16)return 1;
  132. if (!(limx[i].first <= posx && posx <= limx[i].second && limy[i].first <= posy && posy <= limy[i].second))return 0;
  133. if (!(u.des[posx][posy] == -1 || u.des[posx][posy] > 15))return 0;
  134. return 1;
  135. }
  136. void newrate(int u) {
  137. winrate[u] = w[u] / (n[u]*100) + (lf)c * sqrt(max(log(n[fa[u]]) / n[u],0.0));
  138. }
  139. inline vector<Chess> step(Chess tmp, int sw) {//在tmp的局面里面获取走子可能,sw为1获取所有能
  140. pair<int, int> poi[32];
  141. for (int i = 0; i < 32; i++)poi[i] = { -1,-1 };
  142. for (int i = 0; i < 10; i++)for (int j = 0; j < 9; j++)if (tmp.des[i][j] >= 0)poi[tmp.des[i][j]] = { i,j };
  143. vector<Chess> ans;
  144. int nposx, nposy, posx, posy;
  145. auto work = [&](int i)-> void {
  146. if (judge(tmp, i, nposx, nposy))
  147. ans.push_back(Creatdes(posx, posy, nposx, nposy, tmp));
  148. };
  149. for (int i = 0; i <= 15; i++) {
  150. if(sw==0)i=e()%16;
  151. if (poi[i].first == -1)continue;
  152. posx = poi[i].first, posy = poi[i].second;
  153. if (i == 0) {
  154. nposx = posx - 1, nposy = posy;
  155. work(i);
  156. nposx = posx + 1, nposy = posy;
  157. work(i);
  158. nposx = posx, nposy = posy + 1;
  159. work(i);
  160. nposx = posx, nposy = posy - 1;
  161. work(i);
  162. if (posy == poi[16].second) {
  163. nposx = poi[16].first, nposy = poi[16].second;
  164. int x=0;
  165. for(int j=posx+1;j<=nposx-1;j++)if(tmp.des[j][posy]!=-1)x=1;
  166. if(x==0){
  167. work(i);
  168. }
  169. }
  170. }
  171. else if (i == 1 || i == 2) {
  172. nposx = posx - 1, nposy = posy - 1;
  173. work(i);
  174. nposx = posx + 1, nposy = posy + 1;
  175. work(i);
  176. nposx = posx - 1, nposy = posy + 1;
  177. work(i);
  178. nposx = posx + 1, nposy = posy - 1;
  179. work(i);
  180. }
  181. else if (i == 3 || i == 4) {
  182. if (posx - 1 >= 0 && posy - 1 >= 0 && tmp.des[posx - 1][posy - 1] == -1) {
  183. nposx = posx - 2, nposy = posy - 2;
  184. work(i);
  185. }
  186. if (posx + 1 <= 9 && posy + 1 <= 8 && tmp.des[posx + 1][posy + 1] == -1) {
  187. nposx = posx + 2, nposy = posy + 2;
  188. work(i);
  189. }
  190. if (posx + 1 <= 9 && posy - 1 >= 0 && tmp.des[posx + 1][posy - 1] == -1) {
  191. nposx = posx + 2, nposy = posy - 2;
  192. work(i);
  193. }
  194. if (posx - 1 >= 0 && posy + 1 <= 8 && tmp.des[posx - 1][posy + 1] == -1) {
  195. nposx = posx - 2, nposy = posy + 2;
  196. work(i);
  197. }
  198. }
  199. else if (i == 5 || i == 6) {
  200. if (posx - 1 >= 0 && tmp.des[posx - 1][posy] == -1) {
  201. nposx = posx - 2, nposy = posy - 1;
  202. work(i);
  203. nposx = posx - 2, nposy = posy + 1;
  204. work(i);
  205. }
  206. if (posx + 1 <= 9 && tmp.des[posx + 1][posy] == -1) {
  207. nposx = posx + 2, nposy = posy + 1;
  208. work(i);
  209. nposx = posx + 2, nposy = posy - 1;
  210. work(i);
  211. }
  212. if (posy - 1 >= 0 && tmp.des[posx][posy - 1] == -1) {
  213. nposx = posx - 1, nposy = posy - 2;
  214. work(i);
  215. nposx = posx + 1, nposy = posy - 2;
  216. work(i);
  217. }
  218. if (posy + 1 <= 8 && tmp.des[posx][posy + 1] == -1) {
  219. nposx = posx - 1, nposy = posy + 2;
  220. work(i);
  221. nposx = posx + 1, nposy = posy + 2;
  222. work(i);
  223. }
  224. }
  225. else if (i == 7 || i == 8) {
  226. for (int j = 1; j <= 9; j++) {
  227. nposx = posx + j, nposy = posy;
  228. work(i);
  229. if (posx + j > 9 || tmp.des[posx + j][posy] != -1)break;
  230. }
  231. for (int j = 1; j <= 9; j++) {
  232. nposx = posx - j, nposy = posy;
  233. work(i);
  234. if (posx - j < 0 || tmp.des[posx - j][posy] != -1)break;
  235. }
  236. for (int j = 1; j <= 8; j++) {
  237. nposx = posx, nposy = posy + j;
  238. work(i);
  239. if (posy + j > 8 || tmp.des[posx][posy + j] != -1)break;
  240. }
  241. for (int j = 1; j <= 8; j++) {
  242. nposx = posx, nposy = posy - j;
  243. work(i);
  244. if (posy - j < 0 || tmp.des[posx][posy - j] != -1)break;
  245. }
  246. }
  247. else if (i == 9 || i == 10) {
  248. for (int j = 1; j <= 9; j++) {
  249. if (posx + j > 9)break;
  250. if (tmp.des[posx + j][posy] == -1) {
  251. nposx = posx + j, nposy = posy;
  252. work(i);
  253. }
  254. if (tmp.des[posx + j][posy] != -1) {
  255. j++;
  256. while (posx + j <= 9 && tmp.des[posx + j][posy] == -1)j++;
  257. nposx = posx + j, nposy = posy;
  258. work(i);
  259. break;
  260. }
  261. }
  262. for (int j = 1; j <= 9; j++) {
  263. if (posx - j < 0)break;
  264. if (tmp.des[posx - j][posy] == -1) {
  265. nposx = posx - j, nposy = posy;
  266. work(i);
  267. }
  268. if (tmp.des[posx - j][posy] != -1) {
  269. j++;
  270. while (posx - j >= 0 && tmp.des[posx - j][posy] == -1)j++;
  271. nposx = posx - j, nposy = posy;
  272. work(i);
  273. break;
  274. }
  275. }
  276. for (int j = 1; j <= 8; j++) {
  277. if (posy + j > 8)break;
  278. if (tmp.des[posx][posy + j] == -1) {
  279. nposx = posx, nposy = posy + j;
  280. work(i);
  281. }
  282. if (tmp.des[posx][posy + j] != -1) {
  283. j++;
  284. while (posy + j <= 8 && tmp.des[posx][posy + j] == -1)j++;
  285. nposx = posx, nposy = posy + j;
  286. work(i);
  287. break;
  288. }
  289. }
  290. for (int j = 1; j <= 8; j++) {
  291. if (posy - j < 0)break;
  292. if (tmp.des[posx][posy - j] == -1) {
  293. nposx = posx, nposy = posy - j;
  294. work(i);
  295. }
  296. if (tmp.des[posx][posy - j] != -1) {
  297. j++;
  298. while (posy - j >= 0 && tmp.des[posx][posy - j] == -1)j++;
  299. nposx = posx, nposy = posy - j;
  300. work(i);
  301. break;
  302. }
  303. }
  304. }
  305. else {
  306. nposx = posx + 1, nposy = posy;
  307. work(i);
  308. if (posx > 4) {
  309. nposx = posx, nposy = posy + 1;
  310. work(i);
  311. nposx = posx, nposy = posy - 1;
  312. work(i);
  313. }
  314. }
  315. if(sw==0&&ans.size())return ans;
  316. }
  317. return ans;
  318. }
  319. int rollout(Chess u,int dep) {
  320. int ans = 0;
  321. if (Checkend(u)) {
  322. return 1e9;
  323. }
  324. for (int tp = 1; tp <= thinktime; tp++) {
  325. auto tmp = u;
  326. int cnt = maxstep - dep;
  327. int lun=1;
  328. while (cnt>=0) {
  329. vector<Chess> mulp;
  330. while(mulp.size()<1)mulp=step(tmp,0);
  331. int fe = 1;
  332. lun=!lun;
  333. for (auto& v : mulp) {
  334. if(!Checkend(v))continue;
  335. if (lun==0)ans -= calval(v);
  336. else ans+=calval(v);
  337. fe=0;
  338. }
  339. if(fe==0)break;
  340. random_shuffle(mulp.begin(), mulp.end());
  341. tmp=mulp.back();
  342. cnt--;
  343. if(cnt<0){
  344. if (lun==0)ans -= calval(tmp);
  345. else ans+= calval(tmp);
  346. }
  347. }
  348. }
  349. return ans;
  350. }
  351. void creat(int u) {
  352. auto p=step(chess[u],1);
  353. vector<pll> snf(p.size());
  354. #pragma omp parallel for num_threads(maxnumcore)
  355. for(int i=0;i<p.size();i++){
  356. auto&v=p[i];
  357. snf[i]={rollout(v,dep[u]+1),i};
  358. }
  359. sort(snf.begin(), snf.end(), greater<pll>());
  360. for(int i=0;i<nodelimt&&i<snf.size();i++)
  361. creatnode(u,p[snf[i].second]);
  362. }
  363. int explor(int u) {
  364. if (datree[u].empty())creat(u);
  365. vector<pair<lf,int>> snf;
  366. for (auto& v : datree[u]) {
  367. if (!n[v])snf.push_back({ roval[v]+1e8,v });
  368. else newrate(v),snf.push_back({ winrate[v],v });
  369. }
  370. sort(snf.begin(), snf.end());
  371. return snf.back().second;
  372. }
  373. void spreadback(int end) {
  374. lf cn = 0;
  375. int v = end;
  376. while (v != 0) {
  377. n[v]++;
  378. if (mark[v] == mark[end])cn+=calval(chess[v]);
  379. else cn-=calval(chess[v]);
  380. if (mark[v] == mark[end])w[v] += cn;
  381. else w[v] -= cn;
  382. newrate(v);
  383. v = fa[v];
  384. }
  385. }
  386. inline void sendmessage(int rx,int ry,int px,int py){
  387. ofstream outFile;
  388. outFile.open("rec.txt", std::ios::out);
  389. outFile << rx<<' '<<ry<<'\n';
  390. outFile << px<<' '<<py<<'\n';
  391. outFile.close();
  392. outFile.open("message.txt", std::ios::out);
  393. outFile<<1<<'\n';
  394. outFile.close();
  395. }
  396. Chess cal(Chess u) {
  397. siz=0;
  398. chess[0]=u; datree[0].clear();
  399. n[0]=w[0]=winrate[0]=0;
  400. fa[0]=-1; dep[0]=mark[0]=endpo[0]=roval[0]=del[0]=0;
  401. int cnt=0,root=0;
  402. while (1) {
  403. cout<< siz <<"\n";
  404. cout << cnt <<"\n";
  405. root = explor(root);
  406. cnt++;
  407. if (cnt>= maxcal)break;
  408. if (endpo[root] || cnt>= maxcal) {
  409. spreadback(root);
  410. root = 0;
  411. if (cnt>= maxcal)break;
  412. continue;
  413. }
  414. else if (dep[root] > maxstep || cnt>= maxcal) {
  415. spreadback(root);
  416. root = 0;
  417. if (cnt>= maxcal)break;
  418. continue;
  419. }
  420. if (cnt>= maxcal)break;
  421. }
  422. Chess ans;
  423. lf maxr = -1e9;
  424. for (auto& v : datree[0]) {
  425. if (n[v] == 0)continue;
  426. newrate(v);
  427. if (w[v]/n[v] > maxr) {
  428. maxr = w[v]/n[v];
  429. ans = chess[v];
  430. }
  431. }
  432. return ans;
  433. }
  434. void cp() {
  435. Chess now=base,tmp;
  436. prec=base;
  437. while (1) {
  438. tmp=now;
  439. now = cal(now);
  440. prec=tmp;
  441. tmp=rev(now);
  442. int readx,ready,px,py;
  443. for(int i=0;i<10;i++)for(int j=0;j<9;j++)if(prec.des[i][j]!=tmp.des[i][j]){
  444. if(tmp.des[i][j]!=-1){
  445. px=i,py=j;
  446. }
  447. else readx=i,ready=j;
  448. }
  449. sendmessage(readx,ready,px,py);
  450. if(Checkend(now)){
  451. cout<<"ERO!!!!!!!!!!!!\n";
  452. system("pause");
  453. break;
  454. }
  455. tmp=now;
  456. now = cal(now);
  457. prec=rev(tmp);
  458. tmp=now;
  459. for(int i=0;i<10;i++)for(int j=0;j<9;j++)if(prec.des[i][j]!=tmp.des[i][j]){
  460. if(tmp.des[i][j]!=-1){
  461. px=i,py=j;
  462. }
  463. else readx=i,ready=j;
  464. }
  465. sendmessage(readx,ready,px,py);
  466. if(Checkend(now)){
  467. cout<<"ERO!!!!!!!!!!!!\n";
  468. system("pause");
  469. break;
  470. }
  471. }
  472. }
  473. }tester;
  474. int main()
  475. {
  476. maxnumcore = omp_get_num_procs();
  477. tester.init();
  478. e.seed(time(0));
  479. while (1) {
  480. tester.cp();
  481. }
  482. while(1);
  483. return 0;
  484. }
  1. /*棋盘easyx实现*/
  2. // includes
  3. #include<iostream>
  4. #include<graphics.h>
  5. #include<bits/stdc++.h>
  6. using namespace std;
  7. // 使用到的 WCHAR 字符
  8. class CKind {
  9. public:
  10. WCHAR ROOKS = *(_T("车"));
  11. WCHAR KNIGHTS = *_T("马");
  12. WCHAR ELEPHANTS = *_T("象");
  13. WCHAR MINISTERS = *_T("相");
  14. WCHAR MANDARINS = *_T("士");
  15. WCHAR GUARDS = *_T("仕");
  16. WCHAR KING = *_T("将");
  17. WCHAR GENERALS = *_T("帅");
  18. WCHAR CANNONS = *_T("炮");
  19. WCHAR PAWNS = *_T("卒");
  20. WCHAR SOLDIERS = *_T("兵");
  21. WCHAR PLAYER_1 = *_T("BLACK");
  22. WCHAR PLAYER_2 = *_T("RED");
  23. };
  24. // 落子点
  25. class Grid {
  26. int x, y;
  27. public:
  28. Grid() {};
  29. virtual WCHAR get_name() { return NULL; }
  30. virtual void drowReady(int x, int y) {}
  31. virtual void setPlayer(WCHAR player) {}
  32. virtual WCHAR getPlayer() { return NULL; }
  33. void set_xy(int x, int y)
  34. {
  35. this->x = x;
  36. this->y = y;
  37. }
  38. pair<int, int>get_xy()
  39. {
  40. pair<int, int>p(x, y);
  41. return p;
  42. }
  43. };
  44. // 棋子
  45. class Chess :public Grid
  46. {
  47. WCHAR player;
  48. WCHAR name;
  49. public:
  50. Chess(WCHAR name)
  51. {
  52. this->name = name;
  53. }
  54. WCHAR get_name()
  55. {
  56. return name;
  57. }
  58. void setPlayer(WCHAR player)
  59. {
  60. this->player = player;
  61. }
  62. WCHAR getPlayer()
  63. {
  64. return player;
  65. }
  66. void drowReady(int x, int y)
  67. {
  68. setfillcolor(RGB(51, 205, 219));
  69. fillcircle(x, y, 27);
  70. RECT r = { x - 18, y - 18, x + 18, y + 18 };
  71. setbkcolor(RGB(51, 205, 219));
  72. if (player == *_T("BLACK"))
  73. {
  74. settextcolor(BLACK);
  75. }
  76. else
  77. settextcolor(RED);
  78. drawtext(name, &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  79. }
  80. };
  81. // 棋盘
  82. class PaneBoard {
  83. CKind ckind;
  84. int PERLENGTH;//单位长度
  85. Grid* grid[10][9];
  86. public:
  87. PaneBoard()
  88. {
  89. PERLENGTH = 60;
  90. }
  91. //开始游戏
  92. void startGame()
  93. {
  94. initPaneGrid();
  95. CreateMap();
  96. repaint();
  97. messagewhile();
  98. closegraph();
  99. }
  100. //初始化棋盘格
  101. void initPaneGrid()
  102. {
  103. for (int i = 0; i < 9; i++)
  104. {
  105. for (int j = 0; j < 10; j++)
  106. {
  107. grid[i][j] = NULL;
  108. }
  109. }
  110. //敌方
  111. grid[0][0] = new Chess(ckind.ROOKS);
  112. grid[0][1] = new Chess(ckind.KNIGHTS);
  113. grid[0][2] = new Chess(ckind.ELEPHANTS);
  114. grid[0][3] = new Chess(ckind.MANDARINS);
  115. grid[0][4] = new Chess(ckind.KING);
  116. grid[0][5] = new Chess(ckind.MANDARINS);
  117. grid[0][6] = new Chess(ckind.ELEPHANTS);
  118. grid[0][7] = new Chess(ckind.KNIGHTS);
  119. grid[0][8] = new Chess(ckind.ROOKS);
  120. grid[2][1] = new Chess(ckind.CANNONS);
  121. grid[2][7] = new Chess(ckind.CANNONS);
  122. for (int i = 0; i <= 8; i += 2)
  123. {
  124. grid[3][i] = new Chess(ckind.PAWNS);
  125. }
  126. //设置棋盘格坐标与属性
  127. for (int j = 0; j <= 8; j++)
  128. {
  129. grid[0][j]->set_xy(PERLENGTH * (j + 1), PERLENGTH);
  130. grid[0][j]->setPlayer(ckind.PLAYER_1);
  131. }
  132. grid[2][1]->set_xy(2 * PERLENGTH, 3 * PERLENGTH);
  133. grid[2][7]->set_xy(8 * PERLENGTH, 3 * PERLENGTH);
  134. grid[2][1]->setPlayer(ckind.PLAYER_1);
  135. grid[2][7]->setPlayer(ckind.PLAYER_1);
  136. for (int i = 0; i <= 8; i += 2)
  137. {
  138. grid[3][i]->set_xy((i + 1) * PERLENGTH, 4 * PERLENGTH);
  139. grid[3][i]->setPlayer(ckind.PLAYER_1);
  140. }
  141. //我方
  142. grid[9][0] = new Chess(ckind.ROOKS);
  143. grid[9][1] = new Chess(ckind.KNIGHTS);
  144. grid[9][2] = new Chess(ckind.MINISTERS);
  145. grid[9][3] = new Chess(ckind.GUARDS);
  146. grid[9][4] = new Chess(ckind.GENERALS);
  147. grid[9][5] = new Chess(ckind.GUARDS);
  148. grid[9][6] = new Chess(ckind.MINISTERS);
  149. grid[9][7] = new Chess(ckind.KNIGHTS);
  150. grid[9][8] = new Chess(ckind.ROOKS);
  151. grid[7][1] = new Chess(ckind.CANNONS);
  152. grid[7][7] = new Chess(ckind.CANNONS);
  153. for (int i = 0; i <= 8; i += 2)
  154. {
  155. grid[6][i] = new Chess(ckind.SOLDIERS);
  156. }
  157. //设置棋盘格坐标与属性
  158. for (int j = 0; j <= 8; j++)
  159. {
  160. grid[9][j]->set_xy(PERLENGTH * (j + 1), 10 * PERLENGTH);
  161. grid[9][j]->setPlayer(ckind.PLAYER_2);
  162. }
  163. grid[7][1]->set_xy(2 * PERLENGTH, 8 * PERLENGTH);
  164. grid[7][7]->set_xy(8 * PERLENGTH, 8 * PERLENGTH);
  165. grid[7][1]->setPlayer(ckind.PLAYER_2);
  166. grid[7][7]->setPlayer(ckind.PLAYER_2);
  167. for (int i = 0; i <= 8; i += 2)
  168. {
  169. grid[6][i]->set_xy((i + 1) * PERLENGTH, 7 * PERLENGTH);
  170. grid[6][i]->setPlayer(ckind.PLAYER_2);
  171. }
  172. }
  173. //创建窗口
  174. void CreateMap()
  175. {
  176. initgraph(10 * PERLENGTH, 11 * PERLENGTH);//单位宽度
  177. setbkcolor(WHITE);
  178. cleardevice();
  179. }
  180. //重绘棋盘
  181. void repaint()
  182. {
  183. setbkcolor(WHITE);
  184. cleardevice();
  185. setlinecolor(BLACK);
  186. setlinestyle(PS_SOLID | PS_JOIN_BEVEL, 3);
  187. line(PERLENGTH - 5, PERLENGTH - 5, PERLENGTH * 9 + 5, PERLENGTH - 5);
  188. line(PERLENGTH - 5, PERLENGTH - 5, PERLENGTH - 5, PERLENGTH * 10 + 5);
  189. line(PERLENGTH - 5, PERLENGTH * 10 + 5, PERLENGTH * 9 + 5, PERLENGTH * 10 + 5);
  190. line(PERLENGTH * 9 + 5, PERLENGTH * 10 + 5, PERLENGTH * 9 + 5, PERLENGTH - 5);
  191. setlinestyle(PS_SOLID | PS_JOIN_BEVEL, 2);
  192. for (int i = 1; i <= 10; i++)
  193. {
  194. line(PERLENGTH, i * PERLENGTH, 9 * PERLENGTH, i * PERLENGTH);
  195. }
  196. for (int i = 1; i <= 9; i++)
  197. {
  198. line(i * PERLENGTH, PERLENGTH, i * PERLENGTH, 5 * PERLENGTH);
  199. line(i * PERLENGTH, 6 * PERLENGTH, i * PERLENGTH, 10 * PERLENGTH);
  200. }
  201. line(PERLENGTH, 5 * PERLENGTH, PERLENGTH, 6 * PERLENGTH);
  202. line(9 * PERLENGTH, 5 * PERLENGTH, 9 * PERLENGTH, 6 * PERLENGTH);
  203. line(4 * PERLENGTH, PERLENGTH, 6 * PERLENGTH, 3 * PERLENGTH);
  204. line(4 * PERLENGTH, 3 * PERLENGTH, 6 * PERLENGTH, PERLENGTH);
  205. line(4 * PERLENGTH, 8 * PERLENGTH, 6 * PERLENGTH, 10 * PERLENGTH);
  206. line(4 * PERLENGTH, 10 * PERLENGTH, 6 * PERLENGTH, 8 * PERLENGTH);
  207. settextcolor(RED);
  208. settextstyle(PERLENGTH * 2 / 3, 0, _T("楷体"));
  209. RECT r = { 2 * PERLENGTH, 5 * PERLENGTH, 4 * PERLENGTH, 6 * PERLENGTH };
  210. drawtext(_T("楚河"), &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  211. r = { 6 * PERLENGTH, 5 * PERLENGTH, 8 * PERLENGTH, 6 * PERLENGTH };
  212. drawtext(_T("汉界"), &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  213. for (int i = 3; i <= 7; i += 2)
  214. {
  215. //敌方
  216. line(i * PERLENGTH - 3, 4 * PERLENGTH - 3, i * PERLENGTH - 3, 4 * PERLENGTH - 10);
  217. line(i * PERLENGTH - 3, 4 * PERLENGTH - 3, i * PERLENGTH - 10, 4 * PERLENGTH - 3);
  218. line(i * PERLENGTH - 3, 4 * PERLENGTH + 3, i * PERLENGTH - 3, 4 * PERLENGTH + 10);
  219. line(i * PERLENGTH - 3, 4 * PERLENGTH + 3, i * PERLENGTH - 10, 4 * PERLENGTH + 3);
  220. line(i * PERLENGTH + 3, 4 * PERLENGTH - 3, i * PERLENGTH + 3, 4 * PERLENGTH - 10);
  221. line(i * PERLENGTH + 3, 4 * PERLENGTH - 3, i * PERLENGTH + 10, 4 * PERLENGTH - 3);
  222. line(i * PERLENGTH + 3, 4 * PERLENGTH + 3, i * PERLENGTH + 3, 4 * PERLENGTH + 10);
  223. line(i * PERLENGTH + 3, 4 * PERLENGTH + 3, i * PERLENGTH + 10, 4 * PERLENGTH + 3);
  224. //我方
  225. line(i * PERLENGTH - 3, 7 * PERLENGTH - 3, i * PERLENGTH - 3, 7 * PERLENGTH - 10);
  226. line(i * PERLENGTH - 3, 7 * PERLENGTH - 3, i * PERLENGTH - 10, 7 * PERLENGTH - 3);
  227. line(i * PERLENGTH - 3, 7 * PERLENGTH + 3, i * PERLENGTH - 3, 7 * PERLENGTH + 10);
  228. line(i * PERLENGTH - 3, 7 * PERLENGTH + 3, i * PERLENGTH - 10, 7 * PERLENGTH + 3);
  229. line(i * PERLENGTH + 3, 7 * PERLENGTH - 3, i * PERLENGTH + 3, 7 * PERLENGTH - 10);
  230. line(i * PERLENGTH + 3, 7 * PERLENGTH - 3, i * PERLENGTH + 10, 7 * PERLENGTH - 3);
  231. line(i * PERLENGTH + 3, 7 * PERLENGTH + 3, i * PERLENGTH + 3, 7 * PERLENGTH + 10);
  232. line(i * PERLENGTH + 3, 7 * PERLENGTH + 3, i * PERLENGTH + 10, 7 * PERLENGTH + 3);
  233. }
  234. for (int i = 2; i <= 8; i += 6)
  235. for (int j = 3; j <= 8; j += 5)
  236. {
  237. line(i * PERLENGTH - 3, j * PERLENGTH - 3, i * PERLENGTH - 3, j * PERLENGTH - 10);
  238. line(i * PERLENGTH - 3, j * PERLENGTH - 3, i * PERLENGTH - 10, j * PERLENGTH - 3);
  239. line(i * PERLENGTH - 3, j * PERLENGTH + 3, i * PERLENGTH - 3, j * PERLENGTH + 10);
  240. line(i * PERLENGTH - 3, j * PERLENGTH + 3, i * PERLENGTH - 10, j * PERLENGTH + 3);
  241. line(i * PERLENGTH + 3, j * PERLENGTH - 3, i * PERLENGTH + 3, j * PERLENGTH - 10);
  242. line(i * PERLENGTH + 3, j * PERLENGTH - 3, i * PERLENGTH + 10, j * PERLENGTH - 3);
  243. line(i * PERLENGTH + 3, j * PERLENGTH + 3, i * PERLENGTH + 3, j * PERLENGTH + 10);
  244. line(i * PERLENGTH + 3, j * PERLENGTH + 3, i * PERLENGTH + 10, j * PERLENGTH + 3);
  245. }
  246. for (int j = 4; j <= 7; j += 3)
  247. {
  248. line(PERLENGTH + 3, j * PERLENGTH - 3, PERLENGTH + 3, j * PERLENGTH - 10);
  249. line(PERLENGTH + 3, j * PERLENGTH - 3, PERLENGTH + 10, j * PERLENGTH - 3);
  250. line(PERLENGTH + 3, j * PERLENGTH + 3, PERLENGTH + 3, j * PERLENGTH + 10);
  251. line(PERLENGTH + 3, j * PERLENGTH + 3, PERLENGTH + 10, j * PERLENGTH + 3);
  252. }
  253. for (int j = 4; j <= 7; j += 3)
  254. {
  255. line(9 * PERLENGTH - 3, j * PERLENGTH - 3, 9 * PERLENGTH - 3, j * PERLENGTH - 10);
  256. line(9 * PERLENGTH - 3, j * PERLENGTH - 3, 9 * PERLENGTH - 10, j * PERLENGTH - 3);
  257. line(9 * PERLENGTH - 3, j * PERLENGTH + 3, 9 * PERLENGTH - 3, j * PERLENGTH + 10);
  258. line(9 * PERLENGTH - 3, j * PERLENGTH + 3, 9 * PERLENGTH - 10, j * PERLENGTH + 3);
  259. }
  260. for (int i = 0; i < 10; i++)
  261. {
  262. for (int j = 0; j < 9; j++)
  263. {
  264. if (grid[i][j] != NULL)
  265. {
  266. pair<int, int>p = grid[i][j]->get_xy();
  267. int x = p.first; int y = p.second;
  268. setfillcolor(RGB(200, 220, 250));
  269. setbkcolor(RGB(200, 220, 250));
  270. fillcircle(x, y, 27);
  271. RECT r = { x - 18, y - 18, x + 18, y + 18 };
  272. if (grid[i][j]->getPlayer() == *_T("BLACK"))
  273. {
  274. settextcolor(BLACK);
  275. }
  276. else
  277. settextcolor(RED);
  278. drawtext(grid[i][j]->get_name(), &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  279. }
  280. }
  281. }
  282. }
  283. //进入消息循环
  284. void messagewhile()
  285. {
  286. MOUSEMSG msg;
  287. pair<int, int>p;
  288. pair<int, int>readyChess;
  289. while (1) {
  290. ifstream data("message.txt", std::ios::in);
  291. int mm;
  292. data >> mm;
  293. if (mm != 1) {
  294. data.close();
  295. continue;
  296. }
  297. data.close();
  298. ofstream outFile;
  299. outFile.open("message.txt", std::ios::out);
  300. outFile << 0<<'\n';
  301. outFile.close();
  302. ifstream rec("rec.txt", std::ios::in);
  303. rec >> readyChess.first;
  304. rec >> readyChess.second;
  305. rec >> p.first;
  306. rec >> p.second;
  307. grid[p.first][p.second] = grid[readyChess.first][readyChess.second];
  308. pair<int, int>change = compute_xy(p.first, p.second);
  309. grid[p.first][p.second]->set_xy(change.first, change.second);
  310. grid[readyChess.first][readyChess.second] = NULL;
  311. repaint();
  312. rec.close();
  313. continue;
  314. }
  315. }
  316. pair<int, int>compute_xy(int i, int j)
  317. {
  318. pair<int, int>p((j + 1) * PERLENGTH, (i + 1) * PERLENGTH);
  319. return p;
  320. }
  321. };
  322. void main()
  323. {
  324. PaneBoard paneBoard;
  325. paneBoard.startGame();
  326. }

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

闽ICP备14008679号