以前写的一个命令行版扫雷,今天翻出来整理了下拿出来,写的有点乱= =
Codeblocks、VC6.0编译通过,只能在windows下运行,Linux不支持。不嫌蛋疼的可以用curses库来实现下Linux版本。。。
运行效果,比较简陋:
程序还是比较简单的,那这里就直接丢代码了:
1 /** 2 * 命令行版扫雷,方向键控制 3 * 作者:evangwt 4 */ 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <conio.h> 8 #include <time.h> 9 #include <windows.h> 10 #define bool int 11 #define true 1 12 #define false 0 13 #define ROW 9 14 #define COLUMN 9 15 #define TOTAL_MINE 10 16 // ASCII码 17 #define MINE 42 18 #define ESC 27 19 #define ENTER 13 20 #define SPACE 32 21 #define UP 72 22 #define DOWN 80 23 #define LEFT 75 24 #define RIGHT 77 25 typedef struct cursorPos_st 26 { 27 int x; 28 int y; 29 } cursorPos_t; 30 31 typedef struct block_st 32 { 33 bool bCover; 34 int nMine; 35 } block_t; 36 37 cursorPos_t cursorPos[ROW][COLUMN]; // 光标位置数组 38 39 block_t mine[ROW][COLUMN]; // 扫雷地图数组 40 41 int nLeftBlock = ROW * COLUMN; // 剩余的格数 42 43 int index_x = 0, index_y = 0; // 光标在光标位置数组、地图数组中的下标 44 45 void setColor(unsigned short Color); 46 47 void welcome(); 48 49 void init(); 50 51 void count(); // 计算附近雷数 52 53 void get(); // 获取键盘输入 54 55 void gotoPos(int y, int x); 56 57 void move(int y, int x); // 移动当前光标位置 58 59 bool check(int y, int x); // 检测是否踩雷 60 61 void print(); // 输出扫雷界面 62 63 void over(char *str); // 游戏结束 64 65 66 int main() 67 { 68 setColor(160); 69 system("cls"); 70 welcome(); 71 init(); 72 count(); 73 print(); 74 /*颜色测试 75 int i = 0; 76 for(i = 0; i < 256; ++i){ 77 setColor(i); 78 system("cls"); 79 print(); 80 gotoPos(0, 0); 81 printf("%d", i); 82 Sleep(100); 83 getch(); 84 } 85 */ 86 for (;;) 87 { 88 gotoPos(cursorPos[index_y][index_x].y, cursorPos[index_y][index_x].x); 89 get(); 90 } 91 return 0; 92 } 93 94 void setColor(unsigned short Color) 95 { 96 HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE); 97 SetConsoleTextAttribute(hCon, Color); 98 }; 99 100 void init() 101 { 102 int i = 0, j = 0; 103 int nMine = TOTAL_MINE; // 初始化地雷总数 104 srand((unsigned int)time(NULL)); 105 // 初始化地雷地图数组 106 for (i = 0; i < ROW; ++i) 107 { 108 for (j = 0; j < COLUMN; ++j) 109 { 110 mine[i][j].bCover = true; 111 mine[i][j].nMine = 0; 112 } 113 } 114 // 放置地雷 115 while (nMine) 116 { 117 //printf("%d\n", nMine); 118 i = rand() % ROW; 119 j = rand() % COLUMN; 120 if (mine[i][j].nMine == 0) 121 { 122 mine[i][j].nMine = -1; // -1为地雷 123 --nMine; 124 } 125 } 126 127 // 初始化光标位置数组 128 for (i = 0; i < ROW; ++i) 129 { 130 for (j = 0; j < COLUMN; ++j) 131 { 132 cursorPos[i][j].x = j * 6 + 3; 133 cursorPos[i][j].y = i * 2 + 1; 134 //printf("%d,%d;", cursorPos[i][j].x, cursorPos[i][j].y); 135 } 136 } 137 } 138 139 void count() 140 { 141 int i = 0, j = 0, m = 0, n = 0; 142 int nMine = 0; // 每个格子周围的雷数 143 for (i = 0; i < ROW; ++i) 144 { 145 for (j = 0; j < COLUMN; ++j) 146 { 147 if (mine[i][j].nMine == -1) 148 continue; 149 // 8方向 150 nMine = 0; 151 for (m = -1; m <= 1; ++m) 152 { 153 if (i + m < 0 || i + m >= ROW) // 行溢出 154 { 155 continue; 156 } 157 for (n = -1; n <= 1; ++n) 158 { 159 if (j + n < 0 || j + n >= COLUMN)// 列溢出 160 { 161 continue; 162 } 163 if (mine[i + m][j + n].nMine == -1) 164 { 165 ++nMine; 166 } 167 } 168 } 169 mine[i][j].nMine = nMine; 170 } 171 } 172 } 173 174 void get() { 175 bool lose; 176 int key1 = getch(); 177 if (key1 == 224) // 方向键两个字节,第一个字节ASCII 224 178 { 179 int key2 = getch(); 180 switch (key2) 181 { 182 case UP: 183 move(index_y - 1, index_x); 184 break; 185 case DOWN: 186 move(index_y + 1, index_x); 187 break; 188 case LEFT: 189 move(index_y, index_x - 1); 190 break; 191 case RIGHT: 192 //printf("right\n"); 193 move(index_y, index_x + 1); 194 break; 195 default: 196 break; 197 } 198 } 199 else 200 { 201 switch (key1) 202 { 203 case ENTER: 204 case SPACE: 205 lose = check(index_y, index_x); 206 system("cls"); 207 print(); 208 if (lose) 209 { 210 printf("| 诶哟我去,踩到一坨热翔! =。。= |\n"); 211 printf("| 按\"r\"重玩,其他键继续。 |\n"); 212 printf("[%c]-------------------------------------------------[%c]\n", MINE, MINE); 213 Sleep(1000); 214 char key3 = getch(); 215 if (key3 == 'r' || key3 == 'R') 216 { 217 setColor(160); 218 init(); 219 count(); 220 print(); 221 } 222 } 223 else if (nLeftBlock > TOTAL_MINE) 224 { 225 printf("| 哎哟,不错哦~ = v = |\n"); 226 printf("[%c]-------------------------------------------------[%c]\n", MINE, MINE); 227 } 228 else 229 { 230 printf("| 哟,居然赢了! =。。= |\n"); 231 printf("| 按\"r\"重玩,其他键继续。 |\n"); 232 printf("[%c]-------------------------------------------------[%c]\n", MINE, MINE); 233 Sleep(1000); 234 char key3 = getch(); 235 if (key3 == 'r' || key3 == 'R') 236 { 237 setColor(160); 238 init(); 239 count(); 240 print(); 241 } 242 } 243 break; 244 case ESC: 245 system("cls"); 246 over("\t\t\t\t\t白白~\n\n\n\n\n\n\n\n"); 247 default: 248 break; 249 } 250 } 251 } 252 253 void gotoPos(int y, int x) 254 { 255 COORD c; 256 c.X = x; 257 c.Y = y; 258 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c); 259 } 260 261 void move(int y, int x) 262 { 263 if ((x >= 0 && x < COLUMN) && (y >= 0 && y < ROW)) 264 { 265 gotoPos(cursorPos[y][x].y, cursorPos[y][x].x); 266 index_x = x; 267 index_y = y; 268 } 269 } 270 271 bool check(int y, int x) 272 { 273 int i = 0, j = 0; 274 // 下标溢出 275 if (x < 0 || x >= COLUMN || y < 0 || y >= ROW) 276 { 277 return false; 278 } 279 // 翻开选中的格子 280 mine[y][x].bCover = false; 281 // 踩中地雷 282 if (mine[y][x].nMine == -1) 283 { 284 mine[y][x].nMine = 9; 285 return true; 286 } 287 288 // 展开连片空格 289 if (mine[y][x].nMine > 0 && mine[y][x].nMine < 9) 290 { 291 return false; 292 } 293 for (i = -1; i <= 1; ++i) 294 { 295 if (y + i < 0 || y + i >= ROW) // 行溢出 296 { 297 continue; 298 } 299 for (j = -1; j <= 1; ++j) 300 { 301 if (x + j < 0 || x + j >= COLUMN) // 列溢出 302 { 303 continue; 304 } 305 if (mine[y + i][x + j].bCover) 306 { 307 mine[y + i][x + j].bCover = false; 308 check(y + i, x + j); 309 } 310 } 311 } 312 return false; 313 } 314 315 void print() 316 { 317 system("cls"); 318 char help0[] = "←↑↓→"; 319 char help1[] = "移动光标"; 320 char help2[] = "空格\\回车"; 321 char help3[] = " 挖雷"; 322 char help4[] = "Esc 退出"; 323 gotoPos(4, 62); 324 printf("%s", help0); 325 gotoPos(6, 62); 326 printf("%s", help1); 327 gotoPos(9, 62); 328 printf("%s", help2); 329 gotoPos(11, 62); 330 printf("%s", help3); 331 gotoPos(14, 62); 332 printf("%s", help4); 333 334 gotoPos(0, 0); 335 int i = 0, j = 0, k = 0; 336 nLeftBlock = 0; 337 printf("[M]---"); 338 for (k = 1; k < COLUMN - 1; ++k) 339 { 340 printf("+-----"); 341 } 342 printf("+---[I]\n"); 343 for (i = 0; i < ROW; ++i) 344 { 345 for (j = 0; j < COLUMN; ++j) 346 { 347 if (mine[i][j].bCover) 348 { 349 ++nLeftBlock; 350 printf("| %c ", 1); 351 } 352 else if (mine[i][j].nMine == -1 || mine[i][j].nMine == 9) 353 { 354 printf("| %c ", MINE); 355 } 356 else if (mine[i][j].nMine == 0) 357 { 358 printf("| %c ", ' '); 359 } 360 else 361 { 362 printf("| %d ", mine[i][j].nMine); 363 } 364 } 365 printf("|\n"); 366 if (i < ROW - 1) 367 { 368 for (k = 0; k < COLUMN; ++k) 369 { 370 printf("+-----"); 371 } 372 printf("+\n"); 373 } 374 } 375 printf("[N]---"); 376 for (k = 1; k < COLUMN - 1; ++k) 377 { 378 printf("+-----"); 379 } 380 printf("+---[E]\n"); 381 } 382 383 void welcome() { 384 int i = 0; 385 char words0[] = "《屌丝扫雷》"; 386 char words1[] = "之"; 387 char words2[] = "命令行版本"; 388 char words3[] = "版权所有 evangwt,谢谢 (=v = )"; 389 390 for (i = 0; i <= 5; ++i) 391 { 392 system("cls"); 393 gotoPos(i, (80 - strlen(words0)) / 2); 394 printf("%s", words0); 395 Sleep(50); 396 } 397 for (i = 78; i >= 39; --i) 398 { 399 gotoPos(7, i); 400 printf("%s", words1); 401 gotoPos(7, 78 - i); 402 printf("%s", words1); 403 Sleep(40); 404 } 405 for (i = 0; i <= (80 - strlen(words2)) / 2; ++i) 406 { 407 gotoPos(9, i); 408 printf("%s", words2); 409 Sleep(50); 410 } 411 for (i = 24; i >= 14; --i) 412 { 413 system("cls"); 414 gotoPos(5, (80 - strlen(words0)) / 2); 415 printf("%s", words0); 416 gotoPos(7, 39); 417 printf("%s", words1); 418 gotoPos(9, (80 - strlen(words2)) / 2); 419 printf("%s", words2); 420 gotoPos(i, (80 - strlen(words3)) / 2); 421 printf("%s", words3); 422 Sleep(50); 423 } 424 char help0[] = "{←↑↓→ 移动光标,空格\\回车 翻牌,Esc 退出}"; 425 char help1[] = "{其他暂停界面按任意键继续}"; 426 gotoPos(18, (80 - strlen(help0)) / 2); 427 printf("%s", help0); 428 gotoPos(19, (80 - strlen(help1)) / 2); 429 printf("%s", help1); 430 431 getch(); 432 } 433 434 void over(char *str) { 435 setColor(110); 436 system("cls"); 437 gotoPos(10, 0); 438 int i = 0; 439 do 440 { 441 printf("%c", str[i]); 442 Sleep(100); 443 } while(str[i++]); 444 system("pause"); 445 exit(0); 446 }