当前位置:   article > 正文

linux c 实现2048游戏_linux2048小游戏代码的每步解析

linux2048小游戏代码的每步解析

2048这个游戏相信大家应该都玩过,那么今天我在linux下用C语言实现一个2048游戏。


额。。实现完成后就长这个样子。

先来说一下游戏规则:

        每次通过【I】向上移动、【K】向下移动、【J】向左移动、【L】向右移动,每移动一次,所有的数字都会往移动方向靠拢,然后在其余空白的地方出现一个数字,我这里只给出 2 ,相同数字的靠拢、相撞会相加。玩家要想办法在这个16个格子中凑出2048这个数字块,即过关。

其实这里说的是移动,但是没有真的在移动,只是每次用清屏函数清一下屏,然后重新打印出来。4 * 4的格子可以用二维数组来存这些数字,那么我就用一维数组了。

先说一下大致思路,然后讲解代码。用一个整型数组存16个格子中的数字,数组该开始全部初始化为0,那么我在打印这个格子的时候做了一些处理,当数组当中数字是0的时候,打印的时候如果是数字0则用%c打印,出来是空白。刚开始随机两个格子填充为2,就是上面图片那个样子。按上下左右移动时都会往按的方向移动,如果数字相同,就会合成一个更大的数字,如果不同就移动就可以了。举个例子:

向左移动


可以看到原来的两个2合成了一个4,然后又随机出来一个2。向左移动发生了什么呢?现在只看第3行,向左移动,从左向右看,首先看第一个,判断数组当中的数字是否为0?那么很明显不是0,又因为已经到最左边了,不需要移动,那么看第二个数字,为0不用管,第3个也是0不用管,第4个不是0,那么这个数字移动首先和第3个数字比较,因为第3个数字是0,说明这个格子空着,可以移动到这个格子,所以把第三个格子中的数字设置为第4个格子中的数字,然后把第4个格子中的数字设置为0,表示这块空了,此时完成一步操作,然后继续和第2个比较,发现第2个格子还是空白,说明可以移动,然后交换,然后继续向左走,这时候第1个和第2个都有数字,那么看这两个数字相等吗?如果相等,进行合并,如果不相等 就不用移动了,也不需要合并,那么现在的情况是两个2是相等的,那么需要合并,因为是向左移动,所以把第1个格子中的数字乘以2,把第2个格子中的数字设置为0。此时完成一行的移动和合并操作,其余三行是一样的道理,并且上下左右也一样,只是方向不同。现在我把这个移动合并的动作分解为三步,第一次做移动操作,但是不合并数字,只是把数字中间的空白去除,第二次做合并操作,把相同数字合并,那么这时候就又会产生空白,那么第三步,再做一次移动操作就把空白去掉了。我画图解释一下:


这个就是第一步,移动,目的把空白去掉,不管数字是否相同全部移动到一边。然后做第二步合并:



可以看到此时合并过后又会产生空白,就是那个红圈圈,然后再做第三步,移动清除空白:

那么最后这个结果就是正确结果。下来通过代码讲解:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include <termios.h> //这个以及后面用到的请参考: https://www.cnblogs.com/zhouyinhui/archive/2010/10/12/1849011.html
  5. #define SIZE 16
  6. #define UP 0x69 // 小写 i
  7. #define UP_B 0x49 // 大写 I
  8. #define DOWN 0x6b // 小写 k
  9. #define DOWN_B 0x4b // 大写 K
  10. #define RIGHT 0x6c // 小写 l
  11. #define RIGHT_B 0x4c // 大写 L
  12. #define LEFT 0x6a // 小写 j
  13. #define LEFT_B 0x4a // 大写 J
  14. int arr[SIZE] = {0};
  15. int is_move = 0; // 这个标志是判断是否有移动过没有
  16. int is_merge = 0; // 这个标志是判断是否有合并过没有
  17. int max; // 当前最大数字
  18. int total; // 统计总分数
  19. static struct termios oldt;
  20. void restore_terminal_settings(void)
  21. {
  22. tcsetattr(0, TCSANOW, &oldt);
  23. }
  24. void disable_terminal_return(void)
  25. {
  26. struct termios newt;
  27. tcgetattr(0, &oldt);
  28. newt = oldt;
  29. newt.c_lflag &= ~(ICANON | ECHO);
  30. tcsetattr(0, TCSANOW, &newt);
  31. atexit(restore_terminal_settings);
  32. }
  33. //初始化数组,产生两个不同的随机数,从0-15产生,对应数组下标,然后把该下标数组的值设置为2
  34. void init(void)
  35. {
  36. int i, random1, random2;
  37. random1 = rand() % SIZE;
  38. for(i = 0; i < 1; i++)
  39. {
  40. random2 = rand() % SIZE;
  41. if(random1 == random2)
  42. {
  43. i--;
  44. }
  45. }
  46. arr[random1] = 2;
  47. arr[random2] = 2;
  48. }
  49. //判断是否不能移动并且合并,就是game over了
  50. int is_dead()
  51. {
  52. int i, j;
  53. for(i = 0; i < SIZE; i++)
  54. {
  55. if(!arr[i]) //如果数组当中还有0,说明还能移动,返回0,说明游戏还没结束呢
  56. {
  57. return 0;
  58. }
  59. }
  60. //到这里说明,的确在一个方向不能移动了,但是,有可能换个方向还可以移动,所以能到这里说明,16个格子全部有数字,都不为0,接下来判断4行,4列
  61. //每相邻两个数字,是否有相同的如果有说明通过移动还可以动,这时候还没死呢
  62. for(i = 0; i < SIZE; i += 4)
  63. {
  64. for(j = i; j < i + 3; j++)
  65. {
  66. if(arr[j] == arr[j + 1]) //这里就是判断4行,一行一行看,每相邻两个格子如果数字有相同的,return 0,说明游戏还可以继续
  67. {
  68. return 0;
  69. }
  70. }
  71. }
  72. for(i = 0; i < 4; i++)
  73. {
  74. for(j = i; j < i + 12; j += 4)
  75. {
  76. if(arr[j] == arr[j + 4]) //这里判断4列,一列一列看,每相邻两个格子如果有数字相同的,return 0,说明游戏还可以继续
  77. {
  78. return 0;
  79. }
  80. }
  81. }
  82. return 1; // 能到这里,说明16个格子全部都有数字,都不为0,而且各个方向无论怎么移动都不能合并,那么游戏结束game over,return 1
  83. }
  84. // 这个函数返回当前最大的数字
  85. int max_num(void)
  86. {
  87. int i;
  88. static int count = 0;
  89. for(i = 0; i < SIZE; i++)
  90. {
  91. if(arr[i] > max)
  92. {
  93. max = arr[i]; //找最大数
  94. }
  95. }
  96. if(!count && 2048 == max) //判断如果最大数==2048,过关,按任意键继续玩
  97. {
  98. count++;
  99. printf("恭喜过关,请按任意键继续!");
  100. getchar();
  101. }
  102. return max;
  103. }
  104. //这个函数,负责每次打印图形,每次移动操作都会修改数组,改一次,打印一次
  105. void print_game(void)
  106. {
  107. system("clear");
  108. int i;
  109. printf("按【I】向上移动\n按【K】向下移动\n按【J】向左移动\n按【L】向右移动\n按【Ctrl + Z】退出游戏\n最大的数是:%d\n总分是:%d\n", max_num(), total);
  110. printf("\n");
  111. printf("+------------- 2048 --------------+\n");
  112. printf("+-----------------------------------+\n");
  113. printf("| | | | |\n");
  114. for(i = 0; i < SIZE; i++)
  115. {
  116. if(0 == i || 4 == i || 8 == i || 12 == i)
  117. {
  118. printf("|");
  119. }
  120. printf(0 == arr[i] ? "%9c|" : "%8d|", arr[i]); //这里有个对数组中数字0的处理,如果是0 , 那么按%c格式打印是空白,好看些
  121. if(3 == i || 7 == i || 11 == i)
  122. {
  123. printf("\n");
  124. printf("|--------+--------+--------+--------|\n");
  125. printf("| | | | |\n");
  126. }
  127. }
  128. printf("\n");
  129. printf("+-----------------------------------+\n");
  130. printf("+------------ by chenxin -----------+\n");
  131. printf("\n\n\n");
  132. if(is_dead()) //如果能进这个if,说明game over,然后按任意键重新玩,
  133. {
  134. int i;
  135. printf("game over!\n");
  136. printf("请按任意键重新开始!\n");
  137. getchar();
  138. for(i = 0; i < SIZE; i++) //数组清0
  139. {
  140. arr[i] = 0;
  141. }
  142. init(); //重新初始化
  143. print_game();
  144. }
  145. }
  146. //这个函数是每次移动这个动作完成时,在剩下的格子中产生一个随机数字,对应数组下标,然后把该下标数组值设置为2,即每次移动完在剩下空白的地方出现一个2
  147. void rand_num(void)
  148. {
  149. while(is_move || is_merge) //如果可以移动,或者可以合并,那么才能产生数字,
  150. {
  151. int random = rand() % SIZE;
  152. if(!arr[random]) //这个就是保证产生的随机数是空白中的,已经格子中已经有的就不行,重新产生
  153. {
  154. arr[random] = 2;
  155. break;
  156. }
  157. }
  158. is_move = 0;
  159. is_merge = 0;
  160. }
  161. //移动的主要函数,最重要的地方,这个函数接收三个参数,loop_count,需要循环的次数,current_i,当前移动的元素数组下标,
  162. //direction这个是因为有上下左右四个方向,比如当前元素是 arr[5],那么它左边的格子就是arr[5-1],右边就是arr[5+1],
  163. //上边就是arr[5-4],下边就是arr[5+4],这里的 1,-1,4,-4就是direction,就是把四个方向的函数提取出相同的部分,公用这一个移动方法,用direction区分方向
  164. //移动是被move_up ...等等这些函数调用的,所以请先去看move_up ...等等函数的作用
  165. //先说一下,move_up_pre这个函数结合了移动、合并,这个函数调用了move_up这个函数,而move_up 又会调用move_go这个函数,所以先去看move_up_pre函数是干啥的
  166. //OK,从move_up 这个函数过来了,那么我举个例子吧:
  167. //比如现在当前的i是5 ,即第二行第2个数字2,需要向上移动,那么它的循环次数是1次,direction=-4,说明它上面的那个数字下标比当前这个小4
  168. //if(arr[current_i] && !arr[current_i + direction]) 如果当前这个数字不为0,并且它上面的那个数字为0那么就可以向上移动
  169. void move_go(int loop_count, int current_i, int direction)
  170. {
  171. int i;
  172. for(i = 0; i < loop_count; i++)
  173. {
  174. if(arr[current_i] && !arr[current_i + direction])
  175. {
  176. arr[current_i + direction] = arr[current_i]; //把它上面那个数字改成当前这个数字,
  177. arr[current_i] = 0; //把当前这个数字改成0
  178. current_i += direction; //再把当前的current_i ,-4,继续看它上面是什么情况,能移动就移动不能移动就算了
  179. is_move = 1; //能进来说明能移动,所以把标志 是否能移动 设置为1
  180. }
  181. }
  182. }
  183. //OK这个函数完了,就完成了一次单纯的移动操作,那么向左,向右,向下一个道理,我就不说了,下来去看move_up_pre函数去
  184. //好OK,这个函数就是负责向上移动,不用管数字是否相同还是不同,全部一个顶一个一个顶一个移动到一个方向
  185. void move_up(void)
  186. {
  187. // loop_count循环次数,为啥会有这个变量,因为向上移动有的数字需要移动一次,有的需要移动2,3次,而最上边的数字则不需要移动所以,
  188. //loop_count控制循环次数,direction,控制方向,向上移动所以是以从下往上的角度看的,那么direction=-4,意思就是上一个元素的下标比当前元素小4
  189. //所以是-4.
  190. int i, loop_count, direction;
  191. for(i = 0; i < SIZE; i++)
  192. {
  193. if(arr[i]) //移动时,如果这个格子的数字不为0才移动,为0的话不用管了,能进到这个if说明当前要移动的数字不为0,也就是不是空白,空白不需要移动
  194. {
  195. loop_count = i / 4;
  196. //计算循环次数,0 1 2 3,是最上层的数字不用移动,所以i /4=0,不用移动,第二行4,5,6,7,最多需要移动1次,i/4=1,依次类推
  197. direction = -4;
  198. //把当前格子中的数组下标,需要循环的次数,还有方向传给move_go 这个函数,接下来去看move_go 这个函数
  199. move_go(loop_count, i, direction);
  200. }
  201. }
  202. }
  203. void move_down(void)
  204. {
  205. int i, loop_count, direction;
  206. for(i = SIZE - 1; i >= 0; i--)
  207. {
  208. if(arr[i])
  209. {
  210. loop_count = (4 - 1) - i / 4;
  211. direction = 4;
  212. move_go(loop_count, i, direction);
  213. }
  214. }
  215. }
  216. void move_right(void)
  217. {
  218. int i, loop_count, direction;
  219. for(i = SIZE - 1; i >= 0; i--)
  220. {
  221. if(arr[i])
  222. {
  223. loop_count = (4 - 1) - (i + 4) % 4;
  224. direction = 1;
  225. move_go(loop_count, i, direction);
  226. }
  227. }
  228. }
  229. void move_left(void)
  230. {
  231. int i, loop_count, direction;
  232. for(i = 0; i < SIZE; i++)
  233. {
  234. if(arr[i])
  235. {
  236. loop_count = (i + 4) % 4;
  237. direction = -1;
  238. move_go(loop_count, i, direction);
  239. }
  240. }
  241. }
  242. //合并函数,只负责一次合并,把接收当前数字下标,把它上或者下或者左或者右的格子合并一个
  243. void merge(int current_i, int direction)
  244. {
  245. //如果当前这个格子和它四个方向相邻的格子都不为0时并且,这两个数字相等时才进行合并操作
  246. if(arr[current_i] && arr[current_i + direction] && arr[current_i] == arr[current_i + direction])
  247. {
  248. arr[current_i] = arr[current_i + direction] * 2;
  249. total += arr[current_i];
  250. arr[current_i + direction] = 0;
  251. is_merge = 1;
  252. }
  253. }
  254. //这个就是我之前说的分三步,第一步移动清楚空白,第二步合并,第三步移动清楚空白完成一次移动合并操作,下来我仔细讲一下
  255. void move_up_pre(void)
  256. {
  257. move_up(); //先调用移动方法去除空白,那么先去move_up 看这个函数是干啥的,OK看完move_up 函数,再往下看
  258. // 两个move_up 中间夹着的就是合并的动作,同样merge合并的这个函数也是接收一个direction参数,四个方向的合并公用一个方法
  259. // 继续上面的向上移动上去的那个接着画个图
  260. //那么合并操作完成,应该是这个样子,粉色的2其实已经合并了,是不存在的我先放在那里,是想说明我的合并方法会产生空白,所以需要再做一遍移动操作
  261. //向上合并,那么我从上往下看,现在先看第一行的第一个数字,当然如果没有数字那就不合并了,现在假设都有数字
  262. //和它下面的数字比较,就是竖着往下走,如果相同,把第一个数字乘2,第二个数字设置为0 ,然后看第二个数字
  263. //和第三个数字,那么这会其实没必要比较第二个和第三个,直接去比较第三个和第第四个就行了,但是
  264. //我不想分情况了,就直接往下比较吧,白做一次比较,然后就这样依次往后比较
  265. int i, j, direction = 4; //合并是从上往下看,所以direction=4,即它下面的那个格子数组下标比当前这个大4
  266. for(i = 0; i < 4; i++)
  267. // 这里的i从0 到3 ,即0,1,2,3,控制列数,即0开头的那一列,1开头的那一列,以此类推
  268. {
  269. for(j = i; j < i + 12; j += 4)
  270. // 当i=0时,j 是0,4,8,当i=1时,j是1,5,9以此类推,传给merge进行合并,关于下、左、右合并道理类似,我就不说了
  271. {
  272. merge(j, direction);
  273. }
  274. }
  275. move_up();
  276. }
  277. void move_down_pre(void)
  278. {
  279. move_down();
  280. int i, j, direction = -4;
  281. for(i = 4 - 1; i >= 0; i--)
  282. {
  283. for(j = i + 12; j >= 4; j -= 4)
  284. {
  285. merge(j, direction);
  286. }
  287. }
  288. move_down();
  289. }
  290. void move_right_pre(void)
  291. {
  292. move_right();
  293. int i, j, direction = -1;
  294. for(i = 4 - 1; i >= 0; i--)
  295. {
  296. for(j = 4 * i + 3; j > 4 * i; j--)
  297. {
  298. merge(j, direction);
  299. }
  300. }
  301. move_right();
  302. }
  303. void move_left_pre(void)
  304. {
  305. move_left();
  306. int i, j, direction = 1;
  307. for(i = 0; i <= 3; i++)
  308. {
  309. for(j = 4 * i; j < 4 * i + 3; j++)
  310. {
  311. merge(j, direction);
  312. }
  313. }
  314. move_left();
  315. }
  316. int main(void)
  317. {
  318. srand(time(NULL));
  319. init();
  320. print_game();
  321. disable_terminal_return();
  322. while(1)
  323. {
  324. switch(getchar())
  325. {
  326. case UP:
  327. case UP_B:
  328. move_up_pre();
  329. rand_num();
  330. print_game();
  331. break;
  332. case DOWN:
  333. case DOWN_B:
  334. move_down_pre();
  335. rand_num();
  336. print_game();
  337. break;
  338. case RIGHT:
  339. case RIGHT_B:
  340. move_right_pre();
  341. rand_num();
  342. print_game();
  343. break;
  344. case LEFT:
  345. case LEFT_B:
  346. move_left_pre();
  347. rand_num();
  348. print_game();
  349. break;
  350. default:
  351. break;
  352. }
  353. }
  354. return 0;
  355. }


下面附上没有注释的完成代码:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include <termios.h>
  5. #define SIZE 16
  6. #define UP 0x69
  7. #define UP_B 0x49
  8. #define DOWN 0x6b
  9. #define DOWN_B 0x4b
  10. #define RIGHT 0x6c
  11. #define RIGHT_B 0x4c
  12. #define LEFT 0x6a
  13. #define LEFT_B 0x4a
  14. int arr[SIZE] = {0};
  15. int is_move = 0;
  16. int is_merge = 0;
  17. int max;
  18. int total;
  19. static struct termios oldt;
  20. void restore_terminal_settings(void)
  21. {
  22. tcsetattr(0, TCSANOW, &oldt);
  23. }
  24. void disable_terminal_return(void)
  25. {
  26. struct termios newt;
  27. tcgetattr(0, &oldt);
  28. newt = oldt;
  29. newt.c_lflag &= ~(ICANON | ECHO);
  30. tcsetattr(0, TCSANOW, &newt);
  31. atexit(restore_terminal_settings);
  32. }
  33. void init(void)
  34. {
  35. int i, random1, random2;
  36. random1 = rand() % SIZE;
  37. for(i = 0; i < 1; i++)
  38. {
  39. random2 = rand() % SIZE;
  40. if(random1 == random2)
  41. {
  42. i--;
  43. }
  44. }
  45. arr[random1] = 2;
  46. arr[random2] = 2;
  47. }
  48. int is_dead()
  49. {
  50. int i, j;
  51. for(i = 0; i < SIZE; i++)
  52. {
  53. if(!arr[i])
  54. {
  55. return 0;
  56. }
  57. }
  58. for(i = 0; i < SIZE; i += 4)
  59. {
  60. for(j = i; j < i + 3; j++)
  61. {
  62. if(arr[j] == arr[j + 1])
  63. {
  64. return 0;
  65. }
  66. }
  67. }
  68. for(i = 0; i < 4; i++)
  69. {
  70. for(j = i; j < i + 12; j += 4)
  71. {
  72. if(arr[j] == arr[j + 4])
  73. {
  74. return 0;
  75. }
  76. }
  77. }
  78. return 1;
  79. }
  80. int max_num(void)
  81. {
  82. int i;
  83. static int count = 0;
  84. for(i = 0; i < SIZE; i++)
  85. {
  86. if(arr[i] > max)
  87. {
  88. max = arr[i];
  89. }
  90. }
  91. if(!count && 2048 == max)
  92. {
  93. count++;
  94. printf("恭喜过关,请按任意键继续!");
  95. getchar();
  96. }
  97. return max;
  98. }
  99. void print_game(void)
  100. {
  101. system("clear");
  102. int i;
  103. printf("按【I】向上移动\n按【K】向下移动\n按【J】向左移动\n按【L】向右移动\n按【Ctrl + Z】退出游戏\n最大的数是:%d\n总分是:%d\n", max_num(), total);
  104. printf("\n");
  105. printf("+------------- 2048 --------------+\n");
  106. printf("+-----------------------------------+\n");
  107. printf("| | | | |\n");
  108. for(i = 0; i < SIZE; i++)
  109. {
  110. if(0 == i || 4 == i || 8 == i || 12 == i)
  111. {
  112. printf("|");
  113. }
  114. printf(0 == arr[i] ? "%9c|" : "%8d|", arr[i]);
  115. if(3 == i || 7 == i || 11 == i)
  116. {
  117. printf("\n");
  118. printf("|--------+--------+--------+--------|\n");
  119. printf("| | | | |\n");
  120. }
  121. }
  122. printf("\n");
  123. printf("+-----------------------------------+\n");
  124. printf("+------------ by chenxin -----------+\n");
  125. printf("\n\n\n");
  126. if(is_dead())
  127. {
  128. int i;
  129. printf("game over!\n");
  130. printf("请按任意键重新开始!\n");
  131. getchar();
  132. for(i = 0; i < SIZE; i++)
  133. {
  134. arr[i] = 0;
  135. }
  136. init();
  137. print_game();
  138. }
  139. }
  140. void rand_num(void)
  141. {
  142. while(is_move || is_merge)
  143. {
  144. int random = rand() % SIZE;
  145. if(!arr[random])
  146. {
  147. arr[random] = 2;
  148. break;
  149. }
  150. }
  151. is_move = 0;
  152. is_merge = 0;
  153. }
  154. void move_go(int loop_count, int current_i, int direction)
  155. {
  156. int i;
  157. for(i = 0; i < loop_count; i++)
  158. {
  159. if(arr[current_i] && !arr[current_i + direction])
  160. {
  161. arr[current_i + direction] = arr[current_i];
  162. arr[current_i] = 0;
  163. current_i += direction;
  164. is_move = 1;
  165. }
  166. }
  167. }
  168. void move_up(void)
  169. {
  170. int i, loop_count, direction;
  171. for(i = 0; i < SIZE; i++)
  172. {
  173. if(arr[i])
  174. {
  175. loop_count = i / 4;
  176. direction = -4;
  177. move_go(loop_count, i, direction);
  178. }
  179. }
  180. }
  181. void move_down(void)
  182. {
  183. int i, loop_count, direction;
  184. for(i = SIZE - 1; i >= 0; i--)
  185. {
  186. if(arr[i])
  187. {
  188. loop_count = (4 - 1) - i / 4;
  189. direction = 4;
  190. move_go(loop_count, i, direction);
  191. }
  192. }
  193. }
  194. void move_right(void)
  195. {
  196. int i, loop_count, direction;
  197. for(i = SIZE - 1; i >= 0; i--)
  198. {
  199. if(arr[i])
  200. {
  201. loop_count = (4 - 1) - (i + 4) % 4;
  202. direction = 1;
  203. move_go(loop_count, i, direction);
  204. }
  205. }
  206. }
  207. void move_left(void)
  208. {
  209. int i, loop_count, direction;
  210. for(i = 0; i < SIZE; i++)
  211. {
  212. if(arr[i])
  213. {
  214. loop_count = (i + 4) % 4;
  215. direction = -1;
  216. move_go(loop_count, i, direction);
  217. }
  218. }
  219. }
  220. void merge(int current_i, int direction)
  221. {
  222. if(arr[current_i] && arr[current_i + direction] && arr[current_i] == arr[current_i + direction])
  223. {
  224. arr[current_i] = arr[current_i + direction] * 2;
  225. total += arr[current_i];
  226. arr[current_i + direction] = 0;
  227. //current_i += direction;
  228. is_merge = 1;
  229. }
  230. }
  231. void move_up_pre(void)
  232. {
  233. move_up();
  234. int i, j, direction = 4;
  235. for(i = 0; i < 4; i++)
  236. {
  237. for(j = i; j < i + 12; j += 4)
  238. {
  239. merge(j, direction);
  240. }
  241. }
  242. move_up();
  243. }
  244. void move_down_pre(void)
  245. {
  246. move_down();
  247. int i, j, direction = -4;
  248. for(i = 4 - 1; i >= 0; i--)
  249. {
  250. for(j = i + 12; j >= 4; j -= 4)
  251. {
  252. merge(j, direction);
  253. }
  254. }
  255. move_down();
  256. }
  257. void move_right_pre(void)
  258. {
  259. move_right();
  260. int i, j, direction = -1;
  261. for(i = 4 - 1; i >= 0; i--)
  262. {
  263. for(j = 4 * i + 3; j > 4 * i; j--)
  264. {
  265. merge(j, direction);
  266. }
  267. }
  268. move_right();
  269. }
  270. void move_left_pre(void)
  271. {
  272. move_left();
  273. int i, j, direction = 1;
  274. for(i = 0; i <= 3; i++)
  275. {
  276. for(j = 4 * i; j < 4 * i + 3; j++)
  277. {
  278. merge(j, direction);
  279. }
  280. }
  281. move_left();
  282. }
  283. int main(void)
  284. {
  285. srand(time(NULL));
  286. init();
  287. print_game();
  288. disable_terminal_return();
  289. while(1)
  290. {
  291. switch(getchar())
  292. {
  293. case UP:
  294. case UP_B:
  295. move_up_pre();
  296. rand_num();
  297. print_game();
  298. break;
  299. case DOWN:
  300. case DOWN_B:
  301. move_down_pre();
  302. rand_num();
  303. print_game();
  304. break;
  305. case RIGHT:
  306. case RIGHT_B:
  307. move_right_pre();
  308. rand_num();
  309. print_game();
  310. break;
  311. case LEFT:
  312. case LEFT_B:
  313. move_left_pre();
  314. rand_num();
  315. print_game();
  316. break;
  317. default:
  318. break;
  319. }
  320. }
  321. return 0;
  322. }

如果有任何问题,欢迎妹子打扰,男的就算了。

QQ:353120194



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

闽ICP备14008679号