1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > 扫雷游戏 C语言实现

扫雷游戏 C语言实现

时间:2020-08-20 07:11:19

相关推荐

扫雷游戏 C语言实现

扫雷游戏 C语言实现

实现了如下功能:

鼠标控制

左键点开

右键标记

中键自动翻开(效果同windows扫雷)

首次点击不会中雷

下面是几张效果图:

这是初始界面,3种难度级别,难度同经典版windows扫雷

Beginner

不同颜色的数字和标记功能

赢了!

游戏结束,可以点击Restart重新开始

Expert级别难度

可以点击这里下载玩:

MineSweeper Version 1.0

最后是代码,VS编译运行成功(Release):

#include <windows.h>#include <conio.h>#include <stdio.h>#include <stdlib.h>#include <time.h>#define _X_ 0#define _Y_ 0#define GotoXY(x,y) CC.X=x,CC.Y=y,SetConsoleCursorPosition(hOut,CC)#define DoAt(x,y,p) tmpCC=CC,GotoXY(x,y),p,CC=tmpCC,SetConsoleCursorPosition(hOut,CC)#define SetColor(fc,bc) SetConsoleTextAttribute(hOut, fc|bc)//#define WHITESKIN //注释掉这一行就是黑色,否则就是白色#ifndef WHITESKIN#define F_BLACK 0 //前景黑色#define F_LBLACK FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE //前景灰色#define F_WHITE FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY //前景白色#define F_LRED FOREGROUND_RED|FOREGROUND_INTENSITY//前景浅红#define F_LBLUE FOREGROUND_BLUE|FOREGROUND_INTENSITY //前景浅蓝#define F_LGREEN FOREGROUND_GREEN|FOREGROUND_INTENSITY//前景浅绿#define F_LBLUEGREEN FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_INTENSITY//前景浅蓝绿#define F_LPURPLE FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_INTENSITY //前景浅紫#define F_LYELLOW FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY //前景浅黄#define B_BLACK 0 //背景黑色#define CORORSET#else#define F_BLACK FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY//前景白#define F_LBLACK FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE //前景灰色#define F_WHITE 0 //前景黑色#define F_LRED FOREGROUND_RED //前景红#define F_LBLUE FOREGROUND_BLUE //前景蓝#define F_LGREEN FOREGROUND_GREEN //前景绿#define F_LBLUEGREEN FOREGROUND_BLUE|FOREGROUND_GREEN //前景蓝绿#define F_LPURPLE FOREGROUND_RED|FOREGROUND_BLUE //前景紫#define F_LYELLOW FOREGROUND_RED|FOREGROUND_GREEN //前景黄#define B_BLACK BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE|BACKGROUND_INTENSITY //背景白#define CORORSET system("color f0")#endif//■□☆★●◎※①②③④⑤⑥⑦⑧⑨⑩┓┛━┗┏┫┣┻┳╋┃#define UNDIG "■"#define BLANK "□"#define MINE "●"#define MARKED "★"COORD CC = { 0, 0 };COORD tmpCC = { 0, 0 };HANDLE hOut, hIn;DWORD dwMode, nOER;INPUT_RECORD inRecord;SMALL_RECT rc;struct rfMouse{int Button;//1-left 2-right 3-midCOORD position;} rfmouse;int level[3][7] = {/*level[lv][0~1] w hlevel[lv][2] Number of Minelevel[lv][3~4] RemnantMines (X,Y)level[lv][5~6] Restart Back (X,Y)*/{ 8, 8, 10, 4, 12, 4, 14 },{ 16, 16, 40, 4, 20, 4, 22 },{ 30, 16, 99, 4, 20, 4, 22 },};int drc[8][2] = {{ -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 },{ -1, -1 }, { -1, 1 }, { 1, -1 }, { 1, 1 },};char *num[10] = {BLANK,"①", "②", "③", "④", "⑤", "⑥", "⑦", "⑧",MINE,};int numcolor[10] = {/*BLANK*/F_LBLACK,/*1~3*/F_LBLUEGREEN, F_LGREEN, F_LGREEN,/*4~6*/F_LYELLOW, F_LYELLOW, F_LYELLOW,/*7~8*/F_LPURPLE, F_LPURPLE,/*MINE*/F_LRED,};int point[30][16][2], rmines, numofundig, lv;//point[x][y][0]//0 覆盖状态//1 打开状态//2 标记状态//point[x][y][1]//0 周围无雷//1~8 周围有1~8个雷//9 自身为雷int dig(int x, int y);void mark(int x, int y);void drawmap(int w, int h);void initialization(void);int midButtonPress(int x, int y);void explode(void);void mouse_(int delay, struct rfMouse *rfm);void firstblood(void);int main(void){int x, y;hOut = GetStdHandle(STD_OUTPUT_HANDLE);hIn = GetStdHandle(STD_INPUT_HANDLE);CONSOLE_CURSOR_INFO CCI = { 100, 1 };SetConsoleCursorInfo(hOut, &CCI);SetConsoleTitle("MineSweeping V1.0 By BlackKitty");CORORSET;back:;lv = -1;system("mode con cols=34 lines=20");GetConsoleMode(hIn, &dwMode);dwMode |= ENABLE_MOUSE_INPUT;SetConsoleMode(hIn, dwMode);SetColor(F_WHITE, B_BLACK); DoAt(5, 2, printf("MineSweeper Version 1.0"));SetColor(F_LBLACK, B_BLACK); DoAt(17, 4, printf("By BlackKitty"));SetColor(F_LBLUEGREEN, B_BLACK); DoAt(11, 8, printf("- Beginner -"));SetColor(F_LYELLOW, B_BLACK); DoAt(9, 10, printf("- Intermediate -"));SetColor(F_LPURPLE, B_BLACK); DoAt(12, 12, printf("- Expert -"));SetColor(F_LBLACK, B_BLACK); DoAt(14, 17, printf("Control By Mouse"));while (lv < 0){mouse_(23, &rfmouse);if (rfmouse.Button == 1){if (rfmouse.position.Y == 8 && rfmouse.position.X > 12 && rfmouse.position.X < 21) lv = 0;else if (rfmouse.position.Y == 10 && rfmouse.position.X > 10 && rfmouse.position.X < 23) lv = 1;else if (rfmouse.position.Y == 12 && rfmouse.position.X > 13 && rfmouse.position.X < 20) lv = 2;}}Sleep(300);//防止过慢单击点穿菜单switch (lv){case 0:system("mode con cols=24 lines=16"); break;case 1:system("mode con cols=40 lines=24"); break;case 2:system("mode con cols=68 lines=24"); break;}GetConsoleMode(hIn, &dwMode);dwMode |= ENABLE_MOUSE_INPUT;SetConsoleMode(hIn, dwMode);restart:;initialization();while (1){if (numofundig == level[lv][2]){SetColor(F_LRED, B_BLACK); DoAt(level[lv][3], level[lv][4], printf(" - YOU WIN -"));SetColor(F_LRED, B_BLACK);for (x = 0; x < level[lv][0]; x++)for (y = 0; y < level[lv][1]; (point[x][y][0] != 1 && (point[x][y][0] = 1, DoAt(2 * x + 4, y + 2, printf(MARKED)))), y++);numofundig = -1;}mouse_(11, &rfmouse);if (rfmouse.Button == 1){if (rfmouse.position.Y == level[lv][6] && rfmouse.position.X >= level[lv][5] && rfmouse.position.X <= level[lv][5]+ 6) goto restart;if (rfmouse.position.Y == level[lv][6] && rfmouse.position.X >= level[lv][5] + 12 && rfmouse.position.X <= level[lv][5] + 15) goto back;if (numofundig + 1 && dig(rfmouse.position.X / 2 - 2, rfmouse.position.Y - 2)) explode();}if (rfmouse.Button == 2) mark(rfmouse.position.X / 2 - 2, rfmouse.position.Y - 2);if (rfmouse.Button == 3) if (midButtonPress(rfmouse.position.X / 2 - 2, rfmouse.position.Y - 2)) explode();}_getch();return 0;}void mouse_(int delay, struct rfMouse *rfm){/*响应鼠标操作*/while (1){Sleep(delay);//短暂延时ReadConsoleInput(hIn, &inRecord, 100, &nOER);GotoXY(inRecord.Event.MouseEvent.dwMousePosition.X + _X_, inRecord.Event.MouseEvent.dwMousePosition.Y + _Y_); //光标rfm->position.X = inRecord.Event.MouseEvent.dwMousePosition.X + _X_;rfm->position.Y = inRecord.Event.MouseEvent.dwMousePosition.Y + _Y_;if (inRecord.EventType == MOUSE_EVENT)switch (inRecord.Event.MouseEvent.dwButtonState){case FROM_LEFT_1ST_BUTTON_PRESSED:rfm->Button = 1; return; //左键按下case RIGHTMOST_BUTTON_PRESSED:rfm->Button = 2; return; //右键按下case FROM_LEFT_2ND_BUTTON_PRESSED:rfm->Button = 3; return; //左数第2个键(一般为中键)按下default:break;}}}int dig(int x, int y){int i;if (x >= 0 && x<level[lv][0] && y >= 0 && y<level[lv][1] && !point[x][y][0]){numofundig--;point[x][y][0] = 1;if (point[x][y][1] == 9) {if (numofundig + 1 == level[lv][0] * level[lv][1]){do{ initialization(); } while (point[x][y][1] == 9);numofundig--;}else {SetColor(numcolor[point[x][y][1]], B_BLACK); DoAt((x + 2) * 2, y + 2, printf(num[point[x][y][1]]));return 1;}}SetColor(numcolor[point[x][y][1]], B_BLACK); DoAt((x + 2) * 2, y + 2, printf(num[point[x][y][1]]));if (point[x][y][1] == 0)for (i = 0; i < 8; i++)dig(x + drc[i][0], y + drc[i][1]);}return 0;}void mark(int x, int y){if (x >= 0 && x < level[lv][0] && y >= 0 && y < level[lv][1]){if (!point[x][y][0]){SetColor(F_WHITE, B_BLACK); DoAt((x + 2) * 2, y + 2, printf(MARKED));point[x][y][0] = 2;DoAt(level[lv][3], level[lv][4], printf("RemnantMines: %d ", --rmines));}else if (point[x][y][0] == 2){SetColor(F_LBLACK, B_BLACK); DoAt((x + 2) * 2, y + 2, printf(UNDIG));point[x][y][0] = 0;SetColor(F_WHITE, B_BLACK); DoAt(level[lv][3], level[lv][4], printf("RemnantMines: %d ", ++rmines));}}return;}void drawmap(int w, int h){int ww, hh;for (printf("┏"), ww = 0; ww < w; printf("━"), ww++); printf("┓");for (hh = 1; hh <= h; printf("┃"), hh++)for (GotoXY(CC.X, CC.Y + 1), printf("┃"), ww = 0; ww < w; printf(UNDIG), ww++);for (GotoXY(CC.X, CC.Y + 1), printf("┗"), ww = 0; ww < w; printf("━"), ww++); printf("┛");return;}void initialization(void){int xx, yy, i;rmines = level[lv][2];numofundig = level[lv][0] * level[lv][1];srand((unsigned int)time(NULL) + rand());SetColor(F_LBLACK, B_BLACK); DoAt(2, 1, drawmap(level[lv][0], level[lv][1]));SetColor(F_WHITE, B_BLACK);DoAt(level[lv][3], level[lv][4], printf("RemnantMines: %d ", rmines));DoAt(level[lv][5], level[lv][6], printf("RestartBack"));for (xx = 0; xx < level[lv][0]; xx++)for (yy = 0; yy < level[lv][1]; point[xx][yy][0] = point[xx][yy][1] = 0, yy++);for (i = 0; i < level[lv][2];){xx = rand() % level[lv][0];yy = rand() % level[lv][1];if (point[xx][yy][1] == 0){point[xx][yy][1] = 9;i++;}}for (xx = 0; xx < level[lv][0]; xx++)for (yy = 0; yy < level[lv][1]; yy++)if (point[xx][yy][1] != 9)for (i = 0; i < 8; i++)if (xx + drc[i][0] < level[lv][0] && xx + drc[i][0] >= 0 &&yy + drc[i][1] < level[lv][1] && yy + drc[i][1] >= 0 &&point[xx + drc[i][0]][yy + drc[i][1]][1] == 9) point[xx][yy][1]++;return;}int midButtonPress(int x, int y){int i, tmp = 0;if (x >= 0 && x < level[lv][0] && y >= 0 && y < level[lv][1] &&point[x][y][0] == 1 && point[x][y][1] > 0 && point[x][y][1] < 9)for (i = 0, tmp = 0; i < 8; i++)if (x + drc[i][0] < level[lv][0] && x + drc[i][0] >= 0 &&y + drc[i][1] < level[lv][1] && y + drc[i][1] >= 0 &&point[x + drc[i][0]][y + drc[i][1]][0] == 2)tmp++;if (tmp == point[x][y][1])for (i = 0, tmp = 0; i < 8; tmp += dig(x + drc[i][0], y + drc[i][1]), i++);else tmp = 0;return (tmp) ? (1) : (0);}void explode(void){int x, y;for (x = 0; x < level[lv][0]; x++)for (y = 0; y < level[lv][1]; point[x][y][0] = 0, dig(x, y), y++);SetColor(F_LRED, B_BLACK); DoAt(level[lv][3], level[lv][4], printf(" - GAME OVER - "));return;}

注释不多,有疑问可以直接问~

如有不妥,欢迎指正~

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。