Linux下的C之2048

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <curses.h>
  4 #include <time.h>
  5 #include <unistd.h>
  6 #include <signal.h>
  7 
  8 // 4*4方格
  9 int a[4][4] = {0};
 10 // 方格里空格的个数
 11 int empty;
 12 int old_y, old_x;
 13 
 14 void draw();
 15 void play();
 16 void init();
 17 void draw_one(int y, int x);
 18 void cnt_value(int *new_y, int *new_x);
 19 int game_over();
 20 int cnt_one(int y, int x);
 21 
 22 int main()
 23 {
 24     init();
 25     play();
 26     endwin();
 27 
 28     return 0;
 29 }
 30 
 31 void init()
 32 {
 33     int x, y;
 34 
 35     initscr();
 36     cbreak();
 37     noecho();
 38     curs_set(0);
 39 
 40     empty = 15;
 41     srand(time(0));
 42     x = rand() % 4;
 43     y = rand() % 4;
 44     a[y][x] = 2;
 45     draw();
 46 }
 47 
 48 void draw()
 49 {
 50     int n, m, x, y;
 51     char c[4] = {'0', '0', '0', '0'};
 52 
 53     clear();
 54     for(n = 0; n < 9; n += 2)   //横线
 55         for(m = 0; m < 21; m++) {
 56             move(n, m);
 57             addch('-');
 58             refresh();
 59         }
 60     for(m = 0; m < 22; m += 5)  //竖线
 61         for(n = 1; n < 8; n++) {
 62             move(n, m);
 63             addch('|');
 64             refresh();
 65         }
 66     for(y = 0; y < 4; y++)     //数字
 67         for(x = 0; x < 4; x++) {
 68             draw_one(y, x);
 69         }
 70 }
 71 
 72 void draw_one(int y, int x)
 73 {
 74     int i, m, k, j;
 75     char c[4] = {'0', '0', '0', '0'};
 76 
 77     i = a[y][x];
 78     m = 0;
 79     do {
 80         j = i % 10;
 81         c[m++] = j + '0';
 82         i = i / 10;
 83     }while(i > 0);
 84     m = 0;
 85     k = (x + 1) * 5 - 1;
 86     while(c[m] != '0') {
 87         move(2*y+1, k);
 88         addch(c[m++]);
 89         k--;
 90     }
 91 }
 92 
 93 void play()
 94 {
 95     int x, y, i, new_x, new_y, tmp;
 96     int old_empty, move;
 97     char ch;
 98 
 99     while(1) {
100         move = 0;
101         old_empty = empty;
102         //draw();
103         ch = getch();
104         switch(ch) {
105             case 'A':
106             case 'a':
107                 //从左向右消去相同方块
108                 for(y = 0; y < 4; y++)
109                     for(x = 0; x < 4; ) {
110                         if(a[y][x] == 0) {
111                             x++;
112                             continue;
113                         } else {
114                             for(i = x + 1; i < 4; i++) {
115                                 if(a[y][i] == 0) {
116                                     continue;
117                                 }
118                                 else {
119                                     if(a[y][x] == a[y][i]) {
120                                         a[y][x] += a[y][i];
121                                         a[y][i] = 0;
122                                         x = i + 1;
123                                         empty++;
124                                         break;
125                                     }
126                                     else {
127                                         x = i;
128                                         break;
129                                     }
130                                 }
131                             }
132                             x = i;
133                         }
134                     }
135                 //向左移动方块
136                 for(y = 0; y < 4; y++)
137                     for(x = 0; x < 4; x++) {
138                         if(a[y][x] == 0) {
139                             continue;
140                         } else {
141                             for(i = x; (i > 0) && (a[y][i-1] == 0); i--) {
142                                 a[y][i-1] = a[y][i];
143                                 a[y][i] = 0;
144                             move = 1;
145                             }
146                         }
147                     }
148                 break;
149             case 'D':
150             case 'd':
151                 //从右向左消去相同方块
152                 for(y = 0; y < 4; y++)
153                     for(x = 3; x >= 0; ) {
154                         if(a[y][x] == 0) {
155                             x--;
156                             continue;
157                         } else {
158                             for(i = x - 1; i >= 0; i--) {
159                                 if(a[y][i] == 0) {
160                                     continue;
161                                 } else if(a[y][x] == a[y][i]) {
162                                     a[y][x] += a[y][i];
163                                     a[y][i] = 0;
164                                     x = i - 1;
165                                     empty++;
166                                     break;
167                                 } else {
168                                     x = i;
169                                     break;
170                                 }
171                             }
172                             x = i;
173                         }
174                     }
175                 //向右移动方块
176                 for(y = 0; y < 4; y++)
177                     for(x = 3; x >= 0; x--) {
178                         if(a[y][x] == 0) {
179                             continue;
180                         } else {
181                             for(i = x; (i < 3) && (a[y][i+1] == 0); i++) {
182                                 a[y][i+1] = a[y][i];
183                                 a[y][i] = 0;
184                             move = 1;
185                             }
186                         }
187                     }
188                 break;
189             case 'W':
190             case 'w':
191                 //从上向下消去相同方块
192                 for(x = 0; x < 4; x++)
193                     for(y = 0; y < 4; ) {
194                         if(a[y][x] == 0) {
195                             y++;
196                             continue;
197                         } else {
198                             for(i = y + 1; i < 4; i++) {
199                                 if(a[i][x] == 0) {
200                                     continue;
201                                 } else if(a[y][x] == a[i][x]) {
202                                     a[y][x] += a[i][x];
203                                     a[i][x] = 0;
204                                     y = i + 1;
205                                     empty++;
206                                     break;
207                                 } else {
208                                     y = i;
209                                     break;
210                                 }
211                             }
212                             y = i;
213                         }
214                     }
215                 //向上移动方块
216                 for(x = 0; x < 4; x++)
217                     for(y = 0; y < 4; y++) {
218                         if(a[y][x] == 0) {
219                             continue;
220                         } else {
221                             for(i = y; (i > 0) && (a[i-1][x] == 0); i--) {
222                                 a[i-1][x] = a[i][x];
223                                 a[i][x] = 0;
224                             move = 1;
225                             }
226                         }
227                     }
228                 break;
229             case 'S':
230             case 's':
231                 //从下向上消去相同方块
232                 for(x = 0; x < 4; x++)
233                     for(y = 3; y >= 0; ) {
234                         if(a[y][x] == 0) {
235                             y--;
236                             continue;
237                         } else {
238                             for(i = y - 1; i >= 0; i--) {
239                                 if(a[i][x] == 0) {
240                                     continue;
241                                 } else if(a[y][x] == a[i][x]) {
242                                     a[y][x] += a[i][x];
243                                     a[i][x] = 0;
244                                     y = i -1;
245                                     empty++;
246                                     break;
247                                 } else {
248                                     y = i;
249                                     break;
250                                 }
251                             }
252                             y = i;
253                         }
254                     }
255                 //向下移动方块
256                 for(x = 0; x < 4; x++)
257                     for(y = 3; y >= 0; y--) {
258                         if(a[y][x] == 0) {
259                             continue;
260                         } else {
261                             for(i = y; (i < 3) && (a[i+1][x] == 0); i++) {
262                                 a[i+1][x] = a[i][x];
263                                 a[i][x] = 0;
264                             move = 1;
265                             }
266                         }
267                     }
268                 break;
269             case 'Q':
270             case 'q':
271                 game_over();
272                 break;
273             default:
274                 continue;
275                 break;
276         }
277 
278         if(empty <= 0)
279             game_over();
280         draw();
281         //生成新方块
282         if((empty != old_empty) || (move == 1)) {  //修复了不移动或消除方块也生成新方块的bug
283             do {
284                 new_x = rand() % 4;
285                 new_y = rand() % 4;
286             }while(a[new_y][new_x] != 0);
287 
288             cnt_value(&new_y, &new_x);
289 
290             do {
291                 tmp = rand() % 4;
292             }while(tmp == 0 || tmp == 2);
293             a[new_y][new_x] = tmp + 1;
294             empty--;
295 
296             draw_one(new_y, new_x);
297         }
298     }
299 }
300 
301 int cnt_one(int y, int x)
302 {
303     int value = 1;
304 
305                 if(y - 1 > 0)
306                     a[y-1][x] ? 0 : value++;
307                 if(y + 1 < 4)
308                     a[y+1][x] ? 0 : value++;
309                 if(x - 1 >= 0)
310                     a[y][x-1] ? 0 : value++;
311                 if(x + 1 < 4)
312                     a[y][x+1] ? 0 : value++;
313                 if(y - 1 >= 0 && x - 1 >= 0)
314                     a[y-1][x-1] ? 0 : value++;
315                 if(y - 1 >= 0 && x + 1 < 4)
316                     a[y-1][x+1] ? 0 : value++;
317                 if(y + 1 < 4 && x - 1 >= 0)
318                     a[y+1][x-1] ? 0 : value++;
319                 if(y + 1 < 4 && x + 1 < 4)
320                     a[y+1][x+1] ? 0 : value++;
321 
322     return value;
323 }
324 
325 void cnt_value(int *new_y, int *new_x)
326 {
327     int max_x, max_y, x, y, value;
328     int max = 0;
329 
330     max = cnt_one(*new_y, *new_x);
331     for(y = 0; y < 4; y++)
332         for(x = 0; x < 4; x++) {
333             if(!a[y][x]) {
334                 value = cnt_one(y, x);
335                 if(value > max && old_y != y && old_x != x) {  //避免在同一位置反复出现新方块
336                     *new_y = y;
337                     *new_x = x;
338                     old_x = x;
339                     old_y = y;
340                     break;
341                 }
342             }
343         }
344 }
345 
346 int game_over()
347 {
348     sleep(1);
349     endwin();
350     exit(0);
351 }

 vim game_2048.c,按下i进入编辑模式,然后将上面的代码复制进去,再按Esc退出编辑模式,按下:x保存并退出。

然后在终端运行:gcc game_2048.c -o 2048 -lcurses 进行编译,最后输入./2048即可运行2048。方向键是wasd。

效果截图:

原文地址:https://www.cnblogs.com/jacen789/p/5321663.html