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。
效果截图: