控制台小游戏MineSweeper
2018-06-27 10:05:22来源:未知 阅读 ()
控制台扫雷游戏。
材料:EasyX图形库
1 #include<set> 2 #include<array> 3 #include<string> 4 #include<time.h> 5 #include<graphics.h> 6 7 using namespace std; 8 #define Num 20 //小方块数量Num*Num //rand()使得Num数值太小进入死循环 9 #define Size 25 //每个小方块大小 10 using UInt16 = unsigned short int; 11 using TheMap = array<array<UInt16, Num + 2>, Num + 2>; //引索地图 12 #define Trap (UInt16)0X0000 //地雷 13 #define InitMap (UInt16)0X0001 //表示无地雷,每次X2表示周围地雷数+1 14 #define Asked (UInt16)0XFFFF //标志已询问 15 16 void Init(TheMap &Map); //生成Map、地雷,绘制窗口 17 bool MainLoop(TheMap &Map); //游戏循环 18 void DisplayEmpty(TheMap &Map, int i, int j); //对提示区0的绘制 19 void DisplayNum(TheMap &Map, int i, int j); //对提示区1-8的绘制 20 int DisplayFlag(TheMap &Map, int i, int j); //对标志的绘制 21 22 int main() { 23 auto hwnd = initgraph(Num * Size, Num * Size); 24 //游戏的实现 25 TheMap Map; 26 Init(Map); 27 if (MainLoop(Map)) 28 MessageBox(hwnd, L"Win", L"Mine Clerance", MB_OK); 29 else 30 MessageBox(hwnd, L"Defeated", L"Mine Clerance", MB_OK); 31 //离开游戏 32 closegraph(); 33 return 0; 34 } 35 void Init(TheMap &Map) { 36 //初始化Map 37 for (auto &It : Map) 38 It.assign(InitMap); 39 //随机生成地雷 40 srand((unsigned)time(NULL)); 41 for (UInt16 k = 0; k < 2 * Num;) { 42 auto i = rand() % Num + 1; 43 auto j = rand() % Num + 1; 44 if (Map[i][j] == InitMap) { 45 Map[i][j] = Trap; 46 for (int m = -1; m <= 1; ++m) 47 for (int n = -1; n <= 1; ++n) 48 Map[i + m][j + n] <<= 1; 49 ++k; 50 } 51 } 52 //赋值Asked,防止越界 53 for (size_t i = 0; i < Num + 2; ++i) { 54 Map[i][0] = Asked; 55 Map[i][Num + 1] = Asked; 56 Map[0][i] = Asked; 57 Map[Num + 1][i] = Asked; 58 } 59 //绘制可视地图 60 setlinecolor(LIGHTGREEN); 61 for (size_t i = Size; i < Size * Num; i += Size) { 62 line(i, 0, i, Size * Num); 63 line(0, i, Size * Num, i); 64 } 65 } 66 bool MainLoop(TheMap &Map) { 67 int Ret = 0; 68 MOUSEMSG Point; 69 while (Ret != 1) { 70 Point = GetMouseMsg(); 71 if (Point.mkLButton) { //鼠标左键--点开小方块 72 Point = GetMouseMsg(); 73 size_t i = Point.x / Size + 1; 74 size_t j = Point.y / Size + 1; 75 switch (Map[i][j]) { 76 case Trap: //按到地雷 77 for (size_t i = 1; i < Num + 1; ++i) 78 for (size_t j = 1; j < Num + 1; ++j) 79 if (Map[i][j] == Trap) 80 outtextxy(i*Size - Size / 2, j*Size - 3 * Size / 4, L"X"); 81 return false; 82 case InitMap: //按到0 83 DisplayEmpty(Map, i, j); 84 break; 85 case InitMap << 1: 86 case InitMap << 2: 87 case InitMap << 3: 88 case InitMap << 4: 89 case InitMap << 5: 90 case InitMap << 6: 91 case InitMap << 7: 92 case InitMap << 8: 93 DisplayNum(Map, i, j); //按到1-8 94 break; 95 } 96 } 97 else if (Point.mkRButton) { //鼠标右键--标记 98 Point = GetMouseMsg(); 99 auto i = Point.x / Size + 1; 100 auto j = Point.y / Size + 1; 101 Ret = DisplayFlag(Map, i, j); 102 if (Ret == -1) { 103 DisplayFlag(Map, i, j); 104 MessageBox(GetHWnd(), L"NO More Mark", L"MineSweeper", MB_OK); 105 } 106 } 107 } 108 return true; 109 } 110 void DisplayEmpty(TheMap &Map, int i, int j) { 111 //九宫格历遍,递归 112 for (int m = i - 1; m <= i + 1; ++m) 113 for (int n = j - 1; n <= j + 1; ++n) { 114 if (Map[m][n] == InitMap) { 115 Map[m][n] = Asked; 116 outtextxy(m*Size - Size / 2, n*Size - 3 * Size / 4, wstring(to_wstring(0)).c_str()); 117 DisplayEmpty(Map, m, n); 118 } 119 else if (Map[m][n] != Asked) 120 DisplayNum(Map, m, n); 121 } 122 } 123 void DisplayNum(TheMap &Map, int i, int j) { 124 UInt16 num = 8; 125 switch (Map[i][j]) { 126 case 2:--num; 127 case 4:--num; 128 case 8:--num; 129 case 16:--num; 130 case 32:--num; 131 case 64:--num; 132 case 128:--num; 133 case 256:num; 134 Map[i][j] = Asked; 135 outtextxy(i*Size - Size / 2, j*Size - 3 * Size / 4, wstring(to_wstring(num)).c_str()); 136 break; 137 } 138 } 139 int DisplayFlag(TheMap &Map, int i, int j) { 140 static UInt16 TrueFlags = 0; //定义被正确标志的地雷的数量 141 static UInt16 FlagTimes = 0; //定义被用户标志的地雷的数量 142 static set<UInt16> Record; //定义容器,用于记录标记点 143 if (Map[i][j] == Asked) //对已经访问点不做操作 144 return 0; 145 UInt16 ret = i << 8 | j; //适用:Map下标最大0XFFFF 146 auto Iter = Record.insert(ret); 147 if (Iter.second) {//标记 148 outtextxy(i*Size - Size / 2, j*Size - 3 * Size / 4, L"\?"); 149 if (Map[i][j] == Trap) 150 ++TrueFlags; 151 ++FlagTimes; 152 } 153 else {//清除标记 154 Record.erase(ret); 155 setfillcolor(BLACK); 156 fillrectangle(i*Size - Size, j*Size - Size, i*Size, j*Size); 157 if (Map[i][j] == Trap) 158 --TrueFlags; 159 --FlagTimes; 160 } 161 if (TrueFlags == 2 * Num) 162 return 1; 163 if (FlagTimes > 2 * Num) //控制标记数
164 return -1; 165 return 0; 166 }
2018-02-26
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 小游戏二之---------------五子棋 2020-03-23
- C++实现2048小游戏 2019-09-08
- 产生随机数与相应的猜拳小游戏 2018-09-01
- leetcode笔记(七)529. Minesweeper 2018-07-03
- C++实现的控制台-贪吃蛇 2018-06-27
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash