歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

熱門游戲 2048 C++ 源代碼分享

這游戲前一段時間傳的很火,前幾天早上上課實在太無聊了,就決定把這游戲自己也寫一個。

前後寫了一個多小時吧,大概300行左右,沒什麼復雜算法,不過實在懶得去優化了,但估計優化完能控制在200行以下,有興趣的朋友可以自己優化一下。

說明:我一開始玩的是IOS APP版的TRHEES,後來才玩的2048,兩者在滑動的規則上有些區別,本人這個版本是這兩者的結合。

最後,祝試玩愉快!

界面丑陋,求不笑。

以下是 C++源代碼:

  1. /*By Reason*/
  2. #include<iostream>
  3. #include <iomanip>
  4. #include<math.h>
  5. #include<stdlib.h>
  6. #include<time.h>
  7. #include <conio.h> //為了讀取方向鍵
  8. #include<windows.h>
  9. usingnamespace std;   
  10. //srand( (unsigned)time( NULL ) ); //隨機數種子 不能用在這裡
  11. int pane[4][4]; //棋盤
  12. int N=1; //2的n次方
  13. void showpane() //顯示棋盤
  14. { 
  15. cout<<setw(46)<<"X2048 by Reason"<<endl; 
  16. cout<<setw(50)<<" |-----------------------|"<<endl; 
  17. for(int i=0;i<=3;i++) 
  18. { 
  19. cout<<setw(24)<<""; 
  20. for(int j=0;j<=3;j++) 
  21. { 
  22. //SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED); 
  23. cout<<setw(2)<<"|"<<setw(4)<<pane[i][j]; 
  24.  
  25. if(j==3) 
  26. { 
  27. cout<<setw(2)<<"|"<<endl; 
  28. cout<<setw(50)<<" |-----------------------|"<<endl; 
  29. } 
  30. } 
  31. } 
  32. } 
  33. void newgame() //開始游戲
  34. { 
  35. N=1; 
  36. for(int i=0;i<=3;i++) //初始化棋盤
  37. for(int j=0;j<=3;j++) 
  38. pane[i][j]=0; 
  39. srand( (unsigned)time( NULL ) ); 
  40. int m=rand()%4; 
  41. int n=rand()%4; 
  42. int p=rand()%4; 
  43. int q=rand()%4; 
  44. pane[m][n]=pane[p][q]=2; 
  45. showpane(); 
  46. } 
  47. int if2n(int x) //判斷x是否是2的n次方
  48. { 
  49. int flag=0; 
  50. for(int n=1;n<=11;n++) 
  51. { 
  52. if(x==pow(2,n)) 
  53. { 
  54. flag=1; 
  55. if(n>N) 
  56. N=n; 
  57. return flag; 
  58. } 
  59. } 
  60. return flag; 
  61. } 
  62. int upmove() //上移
  63. { 
  64. int flag=0; 
  65. for(int j=0;j<=3;j++) 
  66. for(int i=0;i<3;i++) 
  67. { 
  68. if(if2n(pane[i][j]+pane[i+1][j])==1) 
  69. { 
  70. pane[i][j]=pane[i][j]+pane[i+1][j]; 
  71. pane[i+1][j]=0; 
  72. flag=1; 
  73. } 
  74. } 
  75. return flag; 
  76. } 
  77. int downmove() //下移
  78. { 
  79. int flag=0; 
  80. for(int j=0;j<=3;j++) 
  81. for(int i=3;i>0;i--) 
  82. { 
  83. if(if2n(pane[i][j]+pane[i-1][j])==1) 
  84. { 
  85. pane[i][j]=pane[i][j]+pane[i-1][j]; 
  86. pane[i-1][j]=0; 
  87. flag=1; 
  88. } 
  89. } 
  90. return flag; 
  91. } 
  92. int leftmove() //左移
  93. { 
  94. int flag=0; 
  95. for(int i=0;i<=3;i++) 
  96. for(int j=0;j<3;j++) 
  97. { 
  98. if(if2n(pane[i][j]+pane[i][j+1])==1) 
  99. { 
  100. pane[i][j]=pane[i][j]+pane[i][j+1]; 
  101. pane[i][j+1]=0; 
  102. flag=1; 
  103. } 
  104. } 
  105. return flag; 
  106. } 
  107. int rightmove() //右移
  108. { 
  109. int flag=0; 
  110. for(int i=0;i<=3;i++) 
  111. for(int j=3;j>0;j--) 
  112. { 
  113. if(if2n(pane[i][j]+pane[i][j-1])==1) 
  114. { 
  115. pane[i][j]=pane[i][j]+pane[i][j-1]; 
  116. pane[i][j-1]=0; 
  117. flag=1; 
  118. } 
  119. } 
  120. return flag; 
  121. } 
  122. int testup() //能否上移測試
  123. { 
  124. int flag=0; 
  125. for(int j=0;j<=3;j++) 
  126. for(int i=0;i<3;i++) 
  127. { 
  128. if(if2n(pane[i][j]+pane[i+1][j])==1) 
  129. { 
  130. flag=1; 
  131. } 
  132. } 
  133. return flag; 
  134. } 
  135. int testdown() //測試能否下移
  136. { 
  137. int flag=0; 
  138. for(int j=0;j<=3;j++) 
  139. for(int i=3;i>0;i--) 
  140. { 
  141. if(if2n(pane[i][j]+pane[i-1][j])==1) 
  142. { 
  143. flag=1; 
  144. } 
  145. } 
  146. return flag; 
  147. } 
  148. int testleft() //測試能否左移
  149. { 
  150. int flag=0; 
  151. for(int i=0;i<=3;i++) 
  152. for(int j=0;j<3;j++) 
  153. { 
  154. if(if2n(pane[i][j]+pane[i][j+1])==1) 
  155. { 
  156. flag=1; 
  157. } 
  158. } 
  159. return flag; 
  160. } 
  161. int testright() //測試能否右移
  162. { 
  163. int flag=0; 
  164. for(int i=0;i<=3;i++) 
  165. for(int j=3;j>0;j--) 
  166. { 
  167. if(if2n(pane[i][j]+pane[i][j-1])==1) 
  168. { 
  169. flag=1; 
  170. } 
  171. } 
  172. return flag; 
  173. } 
  174. int panemax() //棋盤最大數
  175. { 
  176. int max=pane[0][0]; 
  177. for(int i=0;i<=3;i++) 
  178. for(int j=0;j<=3;j++) 
  179. if(pane[i][j]>max) 
  180. max=pane[i][j]; 
  181. return max; 
  182. } 
  183. int ifwin() //判斷是否勝利
  184. { 
  185. int flag=0; 
  186. if(panemax()==2048) 
  187. { 
  188. cout<<setw(45)<<"You Win!"<<endl; 
  189. flag=1; 
  190. } 
  191. return flag; 
  192. } 
  193. int ifGameOver() //判斷是否游戲結束
  194. { 
  195. int flag=0; 
  196. if(testup()+ testdown() + testleft() + testright() ==0) 
  197. { 
  198. cout<<setw(43)<<"Game Over!"<<endl; 
  199. flag=1; 
  200. } 
  201. return flag; 
  202. } 
  203. void addnewnumberup() //上移後添加新數
  204. { 
  205. srand( (unsigned)time( NULL ) ); 
  206. int n; 
  207. if(N==1) 
  208. n=1; 
  209. else
  210. n=(rand()%(N)+1); 
  211. int newnumber=pow(2,n); 
  212. for(int i=3;i>=0;i--) 
  213. for(int j=0;j<=3;j++) 
  214. if(pane[i][j]==0) 
  215. { 
  216. pane[i][j]=newnumber; 
  217. return; 
  218. } 
  219. } 
  220. void addnewnumberdown() //下移後添加新數
  221. { 
  222. srand( (unsigned)time( NULL ) ); 
  223. int n; 
  224. if(N==1) 
  225. n=1; 
  226. else
  227. n=(rand()%(N)+1); int newnumber=pow(2,n); 
  228. for(int i=0;i<=3;i++) 
  229. for(int j=0;j<=3;j++) 
  230. if(pane[i][j]==0) 
  231. { 
  232. pane[i][j]=newnumber; 
  233. return; 
  234. } 
  235. } 
  236. void addnewnumberleft() //左移後添加新數
  237. { 
  238. srand( (unsigned)time( NULL ) ); 
  239. int n; 
  240. if(N==1) 
  241. n=1; 
  242. else
  243. n=(rand()%(N)+1); 
  244. int newnumber=pow(2,n); 
  245. for(int j=3;j>=0;j--) 
  246. for(int i=0;i<=3;i++) 
  247. if(pane[i][j]==0) 
  248. { 
  249. pane[i][j]=newnumber; 
  250. return; 
  251. } 
  252. } 
  253. void addnewnumberright() //右移後添加新數
  254. { 
  255. srand( (unsigned)time( NULL ) ); 
  256. int n; 
  257. if(N==1) 
  258. n=1; 
  259. else
  260. n=(rand()%(N)+1); 
  261. int newnumber=pow(2,n); 
  262. for(int j=0;j<=3;j++) 
  263. for(int i=0;i<=3;i++) 
  264. if(pane[i][j]==0) 
  265. { 
  266. pane[i][j]=newnumber; 
  267. return; 
  268. } 
  269. } 
  270. int GetDirection() //讀取方向
  271. { 
  272.     int ret = 0; 
  273.  
  274.     do 
  275.     { 
  276.         int ch = _getch(); 
  277.         if(isascii(ch)) 
  278.             continue; 
  279.  
  280.         ch = _getch(); 
  281.         switch(ch) 
  282.         { 
  283.         case 72:   
  284.             ret = 2; // top
  285.             break; 
  286.         case 75:   
  287.             ret = 1; // left 
  288.             break; 
  289.         case 77:   
  290.             ret = 3; // right
  291.             break; 
  292.         case 80:   
  293.             ret = 4; // down
  294.             break; 
  295.         default:   
  296.             break; 
  297.         } 
  298.     } while (ret == 0); 
  299.      
  300.     return ret; 
  301. } 
  302. void main() //主函數
  303. { 
  304. system("color f9"); 
  305. int makesure=1; 
  306. while(makesure) 
  307. { 
  308. system("cls"); 
  309. newgame(); 
  310. while(ifwin()+ifGameOver()==0) 
  311. { 
  312. int c=GetDirection(); 
  313. switch(c) 
  314. { 
  315. case 2: 
  316. upmove(); 
  317. addnewnumberup(); 
  318. system("cls"); 
  319. showpane(); 
  320. break; 
  321. case 4: 
  322. downmove(); 
  323. addnewnumberdown(); 
  324. system("cls"); 
  325. showpane(); 
  326. break; 
  327. case 1: 
  328. leftmove(); 
  329. addnewnumberleft(); 
  330. system("cls"); 
  331. showpane(); 
  332. break; 
  333. case 3: 
  334. rightmove(); 
  335. addnewnumberright(); 
  336. system("cls"); 
  337. showpane(); 
  338. break; 
  339. default:   
  340. break; 
  341. } 
  342. } 
  343. cout<<setw(43)<<"你的最後成績為:"<<panemax()<<endl; 
  344. cout<<setw(60)<<"若要重新開始游戲請輸入1,若要結束請輸入0。"<<endl; 
  345. cin>>makesure; 
  346. while(makesure!=1&&makesure!=0) 
  347. { 
  348. cout<<"輸入不正確,請重新輸入!"<<endl; 
  349. cin>>makesure; 
  350. } 
  351. } 
  352. cout<<"再見!"<<endl; 
  353. system("pause"); 
  354.  
  355. }

Copyright © Linux教程網 All Rights Reserved