C++实现扫雷、排雷小游戏

时间:2022-01-30 14:02:08

本文实例为大家分享了C++实现扫雷、排雷小游戏的具体代码,供大家参考,具体内容如下

界面:

C++实现扫雷、排雷小游戏

游戏思想: 

扫雷游戏:

1.随机给定雷点坐标

2.判断每个点的雷情况

3.由用户根据上下左右键到达指定位置,点击enter,翻开该点
        如果该点是雷点,此时翻开所有雷点,告知游戏结束
        非雷点,翻开该点坐标

代码:

  1. #include<iostream>
  2. #include<vector>
  3. #include<sstream>
  4. #include<algorithm>
  5. #include<graphics.h>
  6. #include<ctime>
  7. #include<conio.h>
  8.  
  9. using namespace std;
  10.  
  11. #define WIDTH 500
  12. #define HEIGHT 500
  13. #define SIDE 50
  14. #define THUNDERNUM 10
  15. #define TOTALSCORE 100
  16. #define EVERY_OF_DESC 5
  17.  
  18. int score = TOTALSCORE;
  19. class Point {
  20. public:
  21. int x;
  22. int y;
  23. Point() {}
  24. Point(int _x, int _y)
  25. :x(_x), y(_y)
  26. {}
  27. void setPoint(int x, int y) {
  28. this->x = x;
  29. this->y = y;
  30. }
  31. Point(const Point& xy)
  32. :x(xy.x), y(xy.y)
  33. {}
  34. bool operator<(const Point& xy)const {
  35. if (x <= xy.x)
  36. return true;
  37. return y <= xy.y;
  38. }
  39. Point& operator=(const Point& xy) {
  40. if (this != &xy) {
  41. x = xy.x;
  42. y = xy.y;
  43. }
  44. return *this;
  45. }
  46. bool operator==(const Point& xy) {
  47. return ((x == xy.x) && (y = xy.y));
  48. }
  49. bool operator!=(const Point& xy) {
  50. return !(*this == xy);
  51. }
  52. };
  53.  
  54. class ThunderPoint {
  55. private:
  56. vector<Point> storage;
  57. int num;
  58. public:
  59. ThunderPoint(int _num = THUNDERNUM)
  60. :num(_num) {
  61. //初始化雷点位置
  62. int count = 0;
  63. while (count != num) {
  64. int x = (rand() % (WIDTH / SIDE)) * SIDE;//随机生成数据,使之在图形界面之中
  65. int y = (rand() % (HEIGHT / SIDE)) * SIDE;
  66. Point tem(x, y);
  67. int i = -1;
  68. bool flag = false;
  69. for (i = 0; i < storage.size(); i++) {
  70. if (tem == storage[i]) {
  71. flag = true;
  72. break;
  73. }
  74. }
  75. if (flag==false) {
  76. //说明没有重复
  77. storage.push_back(tem);
  78. count++;
  79. }
  80. }
  81. }
  82. vector<Point>& getThunderPoint() {
  83. //获得雷点位置
  84. return storage;
  85. }
  86. void drawThunderPoint() {
  87. auto it = storage.begin();
  88. while (it != storage.end()) {
  89. setfillcolor(RED);
  90. fillcircle((*it).x, (*it).y, SIDE / 2);
  91. ++it;
  92. }
  93. }
  94. };
  95.  
  96. class Grid {
  97. private:
  98. vector<vector<int>> nearbythunder;
  99. vector<vector<bool>> isopen;
  100. ThunderPoint thunder;
  101. Point currposition;
  102. Point preposition;
  103. vector<COLORREF> color;
  104. public:
  105. bool isOver;
  106. public:
  107. Grid()
  108. :thunder(10),currposition()
  109. {
  110. preposition.setPoint(0, 0);
  111. for (int i = 0; i < 10; ++i) {
  112. color.push_back(RGB(rand() % 256, rand() % 256, rand() % 256));
  113. }
  114. isOver = false;
  115. isopen.resize(HEIGHT / SIDE, vector<bool>(WIDTH / SIDE, false));
  116. nearbythunder.resize(HEIGHT/SIDE,vector<int>(WIDTH/SIDE,0));
  117. currposition.setPoint(0, 0);
  118. //先将雷点的位置标出来,标为数字 9
  119. // 任何一个点,他附近的雷点最多8个
  120. auto it = thunder.getThunderPoint().begin();
  121. while (it != thunder.getThunderPoint().end()) {
  122. int x = ((*it).x)/SIDE;
  123. int y = ((*it).y)/SIDE;
  124. nearbythunder[x][y] = 9;
  125. if (((y - SIDE/SIDE) >= 0) && (nearbythunder[x][y - SIDE/SIDE] != 9)) {
  126. nearbythunder[x][y - SIDE/SIDE]++;
  127. }
  128. if (((y - SIDE/SIDE) >= 0) && ((x - SIDE/SIDE) >= 0) && (nearbythunder[x - SIDE/SIDE][y - SIDE/SIDE] != 9)) {
  129. nearbythunder[x - SIDE/SIDE][y - SIDE/SIDE]++;
  130. }
  131. if (((y - SIDE/SIDE) >= 0) && ((x + SIDE/SIDE) < WIDTH/SIDE) && (nearbythunder[x + SIDE/SIDE][y - SIDE/SIDE] != 9)) {
  132. nearbythunder[x + SIDE/SIDE][y - SIDE/SIDE]++;
  133. }
  134. if (((x - SIDE/SIDE) >= 0) && (nearbythunder[x - SIDE/SIDE][y] != 9)) {
  135. nearbythunder[x - SIDE/SIDE][y]++;
  136. }
  137. if (((x + SIDE/SIDE) < WIDTH/SIDE) && (nearbythunder[x + SIDE/SIDE][y] != 9)) {
  138. nearbythunder[x + SIDE/SIDE][y]++;
  139. }
  140. if (((y + SIDE/SIDE) < HEIGHT/SIDE) && (nearbythunder[x][y + SIDE/SIDE] != 9)) {
  141. nearbythunder[x][y + SIDE/SIDE]++;
  142. }
  143. if (((y + SIDE/SIDE) < HEIGHT/SIDE) && ((x - SIDE/SIDE) >= 0) && (nearbythunder[x - SIDE/SIDE][y + SIDE/SIDE] != 9)) {
  144. nearbythunder[x - SIDE/SIDE][y + SIDE/SIDE]++;
  145. }
  146. if (((y + SIDE / SIDE) < HEIGHT / SIDE) && ((x + SIDE / SIDE) < WIDTH / SIDE) && (nearbythunder[x + SIDE / SIDE][y + SIDE / SIDE] != 9)) {
  147. nearbythunder[x + SIDE / SIDE][y + SIDE / SIDE]++;
  148. }
  149. ++it;
  150. }
  151. for (int i = 0; i < HEIGHT; i = i + SIDE) {
  152. setlinecolor(YELLOW);
  153. line(0, i, WIDTH, i);
  154. line(i, 0, i, HEIGHT);
  155. }
  156. }
  157. void keyDown()
  158. {
  159. char userKey = _getch();
  160. if (userKey == -32) // 表明这是方向键
  161. userKey = -_getch(); // 获取具体方向,并避免与其他字母的 ASCII 冲突
  162. setfillcolor(GREEN);
  163. preposition = currposition;
  164. switch (userKey)
  165. {
  166. case 'w':
  167. case 'W':
  168. case -72: //上
  169. {
  170. if (currposition.y - SIDE >= 0) {
  171. currposition.y -= SIDE;
  172. }
  173. }
  174. break;
  175. case 's':
  176. case 'S':
  177. case -80://下
  178. {
  179. if (currposition.y + SIDE < HEIGHT)
  180. currposition.y += SIDE;
  181. }
  182. break;
  183. case 'a':
  184. case 'A':
  185. case -75://左
  186. {
  187. if (currposition.x - SIDE >= 0)
  188. currposition.x -= SIDE;
  189. }
  190. break;
  191. case 'd':
  192. case 'D':
  193. case -77://右
  194. {
  195. if (currposition.x + SIDE < WIDTH) {
  196. currposition.x += SIDE;
  197. }
  198. }
  199. break;
  200. case '\r':
  201. {
  202. score -= EVERY_OF_DESC;
  203. settextstyle(10, 10, "楷体");
  204. settextcolor(GREEN);
  205. RECT rect;
  206. rect.left = WIDTH-100; rect.top = 100; rect.right = WIDTH; rect.bottom = 200;
  207. string ll = to_string(score);
  208. const char* str = ll.c_str();
  209. //drawtext(str, &rect, 1);
  210.  
  211. //现在开始翻
  212. openOne(currposition);
  213. }
  214. break;
  215. }
  216. setlinecolor(BLACK);
  217. setlinestyle(1, 0);
  218. line(preposition.x, preposition.y, preposition.x + SIDE, preposition.y);
  219. setfillcolor(GREEN);
  220. setlinecolor(WHITE);
  221. setlinestyle(1, 2);
  222. line(currposition.x, currposition.y, currposition.x + SIDE, currposition.y );
  223. }
  224. private:
  225. bool pred(bool x) {
  226. return x == true;
  227. }
  228. void openOne(const Point& cur) {
  229. //说明此时翻一个
  230. isopen[cur.x / SIDE][cur.y / SIDE] = true;
  231. //此时应该着色
  232. settextcolor(color[nearbythunder[cur.x/SIDE][cur.y/SIDE]]);
  233. RECT rect;
  234. settextstyle(SIDE, SIDE, "楷体");
  235. rect.left = cur.x; rect.top = cur.y; rect.right = cur.x + SIDE; rect.bottom = cur.y + SIDE;
  236. drawtext((to_string(nearbythunder[cur.x / SIDE][cur.y / SIDE])).c_str(), &rect, 1);
  237. int count = 0;
  238. for (int i = 0; i < HEIGHT / SIDE; ++i) {
  239. for (int j = 0; j < WIDTH / SIDE; ++j) {
  240. if (isopen[i][j] == true) {
  241. count++;
  242. }
  243. }
  244. }
  245. cout << count << endl;
  246. if (nearbythunder[cur.x / SIDE][cur.y / SIDE] == 9 || count==((WIDTH/SIDE)*(HEIGHT/SIDE)- THUNDERNUM)) {
  247. //说明游戏结束
  248. setfillcolor(RED);
  249. for (int i = 0; i < thunder.getThunderPoint().size(); i++) {
  250. fillcircle((thunder.getThunderPoint()[i]).x + SIDE / 2, (thunder.getThunderPoint()[i]).y + SIDE / 2, SIDE / 2);
  251. }
  252. settextcolor(WHITE);
  253. settextstyle(SIDE, SIDE, "楷体");
  254. rect.left = 0; rect.top = 4*SIDE; rect.right = WIDTH; rect.bottom = HEIGHT;
  255. drawtext("GAMEOVER!", &rect, 2);
  256. isOver = true;
  257. return;
  258. }
  259. }
  260. };
  261.  
  262. int main() {
  263. initgraph(WIDTH, HEIGHT);//初始化界面
  264. srand((unsigned)time(NULL));//设置随机数据种子,以当前的时间戳为种子
  265. setbkcolor(RED);
  266. srand((unsigned)time(NULL));
  267. settextcolor(BLUE);
  268. setbkmode(TRANSPARENT); // 设置文字输出模式为透明c
  269. setbkcolor(HSLtoRGB(100, 0.3, 7.5f));
  270. Grid gr;
  271. while (gr.isOver==false) {
  272. gr.keyDown();
  273. }
  274. system("pause");
  275. clearcliprgn();
  276. }

代码解读:

1.类之间的联系

C++实现扫雷、排雷小游戏

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

原文链接:https://blog.csdn.net/xinger_28/article/details/106174296