C/C++知识点之基于c++控制台的扫雷游戏
小标 2019-01-10 来源 : 阅读 1376 评论 0

摘要:本文主要向大家介绍了 C/C++知识点之基于c++控制台的扫雷游戏,通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

本文主要向大家介绍了 C/C++知识点之基于c++控制台的扫雷游戏,通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

C/C++知识点之基于c++控制台的扫雷游戏

Screen   类用于与控制台交互
gotoxy(short x, short y)跳转到控制台的指定位置
void Init() 获取控制台 句柄
bool changeColor(WORD color)变更颜色

/*
0 = 黑色       8 = 灰色搜索
1 = 蓝色       9 = 淡蓝色
2 = 绿色       A = 淡绿色
3 = 浅绿色     B = 淡浅绿色
4 = 红色       C = 淡红色
5 = 紫色       D = 淡紫色
6 = 黄色       E = 淡黄色
7 = 白色       F = 亮白色

FOREGROUND_BLUE 字体颜色:蓝 1
FOREGROUND_GREEN 字体颜色:绿 2
FOREGROUND_RED 字体颜色:红 4
FOREGROUND_INTENSITY 前景色高亮显示 8
BACKGROUND_BLUE 背景颜色:蓝 16
BACKGROUND_GREEN 背景颜色:绿 32
BACKGROUND_RED 背景颜色:红 64
BACKGROUND_INTENSITY 背景色高亮显示 128
*/
class Screen {
public:
 void gotoxy(short x, short y) {
  COORD pos;
  pos.X = x;
  pos.Y = y;
  SetConsoleCursorPosition(hOut, pos);
 };
 void Init()
 {
  hOut = GetStdHandle(STD_OUTPUT_HANDLE);
  assert(hOut != 0);
 }
 bool changeColor(WORD color)
 {
  SetConsoleTextAttribute(hOut,color);
  return true;
 }
 static Screen* instance() {
  static Screen screen;
  return &screen;
 }
private:

 Screen() {
 }
 Screen(const Screen&);
 const Screen& operator=(const Screen&);
 HANDLE hOut;
 INPUT_RECORD inRec;/*  返回数据记录 */
 DWORD numRead; /*  返回已读取的记录数 */
};

  SL扫雷类
Init()初始化窗口高度宽度和类的数量,生成表格
InitTable() 有雷的地方值为-1,其它为周边雷的个数
DrawIn() 画窗口内部格子
DrawOut()画窗口边框
Run()运行游戏
bfs(int h,int w)对于值为0的格子,宽度搜索其周边的格子直到非0
show(int h,int w)当用户点击单击位置h,w 时被调用
完整代码:

#include
#include
#include
using std::cout;
using std::cin;
#include
#include
#include
#include
using std::pair;
using std::make_pair;
using std::queue;
using std::vector;

/*
0 = 黑色       8 = 灰色搜索
1 = 蓝色       9 = 淡蓝色
2 = 绿色       A = 淡绿色
3 = 浅绿色     B = 淡浅绿色
4 = 红色       C = 淡红色
5 = 紫色       D = 淡紫色
6 = 黄色       E = 淡黄色
7 = 白色       F = 亮白色

FOREGROUND_BLUE 字体颜色:蓝 1
FOREGROUND_GREEN 字体颜色:绿 2
FOREGROUND_RED 字体颜色:红 4
FOREGROUND_INTENSITY 前景色高亮显示 8
BACKGROUND_BLUE 背景颜色:蓝 16
BACKGROUND_GREEN 背景颜色:绿 32
BACKGROUND_RED 背景颜色:红 64
BACKGROUND_INTENSITY 背景色高亮显示 128
*/
class Screen {
public:
 void gotoxy(short x, short y) {
  COORD pos;
  pos.X = x;
  pos.Y = y;
  SetConsoleCursorPosition(hOut, pos);
 };
 void Init()
 {
  hOut = GetStdHandle(STD_OUTPUT_HANDLE);
  assert(hOut != 0);
 }
 bool changeColor(WORD color)
 {
  SetConsoleTextAttribute(hOut,color);
  return true;
 }
 static Screen* instance() {
  static Screen screen;
  return &screen;
 }
private:

 Screen() {
 }
 Screen(const Screen&);
 const Screen& operator=(const Screen&);
 HANDLE hOut;
 INPUT_RECORD inRec;/*  返回数据记录 */
 DWORD numRead; /*  返回已读取的记录数 */
};

class SL {
public:
 SL() {
  output = Screen::instance();
 };

 bool Init()
 {
  system("color 70");
  SetWidth();

  SetHeight();
  SetNum();
  InitTable();
  right = 0;
  return true;
 }

 void InitTable()
 {
  table.resize(Height);
  for (int h = 0; h < Height; h++)
  {
   table[h].resize(Width);
  }

  int n = num;
  for (int i = 0; i < Height; i++)
  {
   for (int j = 0; j < Width; j++)
   {
     n--;
     table[i][j] = -1;
     if (n <= 0) {
      j = Width;
      i = Height;
     }
   }
  }
  
  srand(time(0));
  for (int i = 0; i < Height; i++)
  {
   for (int j = 0; j < Width; j++)
   {
    int pi = rand() % Height;
    int pj = rand() % Width;
    std::swap(table[i][j], table[pi][pj]);
   }
  }

  for (int i = 0; i < Height; i++)
  {
   for (int j = 0; j < Width; j++)
   {
    if (table[i][j] == -1)
    {
     int pos[][2] = { {-1,-1},{-1,1},{-1,0},{0,1},{0,-1},{ 1,-1 },{ 1,1 },{ 1,0 } };

     for (int k = 0; k < 8; k++)
     {
      int hh = pos[k][0] + i;
      int ww = pos[k][1] + j;

      if (hh >= 0 && hh < Height && ww >= 0 && ww < Width && table[hh][ww] != -1)
      {
       table[hh][ww]++;
      }
     }

    }
   }
  }

  int a;
  a = 1;
 }

 void SetWidth()
 {
  output->gotoxy(0, 0);
  printf("%s", "请输入扫雷游戏的宽度:                              ");
  output->gotoxy(22, 0);

  cin >> Width;
  while (!check(Width, 20, 60)) {
   output->gotoxy(0, 0);
   printf("%s", "请重新输入扫雷游戏的宽度:                              ");
   output->gotoxy(26, 0);
   cin >> Width;
  }
 }

 void SetHeight()
 {
  output->gotoxy(0, 1);
  printf("%s", "请输入扫雷游戏的高度:                              ");
  output->gotoxy(22, 1);

  cin >> Height;
  while (!check(Height, 20, 60)) {
   output->gotoxy(0, 1);
   printf("%s", "请重新输入扫雷游戏的高度:                              ");
   output->gotoxy(26, 1);
   cin >> Height;
  }
 }

 void SetNum()
 {
  output->gotoxy(0, 2);
  printf("%s", "请输入雷的个数:                              ");
  output->gotoxy(22, 2);

  cin >> num;
  while ((num >= (Width*Height>>1))) {
   output->gotoxy(0, 2);
   printf("%s", "请重新输入雷的个数:                              ");
   output->gotoxy(26, 2);
   cin >> num;
  }
 }

 bool check(int val,int low,int height)
 {
  return val >= low && val <= height;
 }

 void DrawIn()
 {
  output->changeColor(0x76);
  for (int h = 0; h < Height; h++)
  {
   output->gotoxy(5, 4+h);
   for (int w = 0; w < Width; w++)
   {
    printf("%s", "■");
    /*
    if (table[h][w] == -1)
     printf("%s", "★");
    else
     printf("%c ", table[h][w]+‘0‘);    
    */

   }
  }  
 }

 void DrawOut()
 {
  output->changeColor(0x75);
  output->gotoxy(3, 3);
  //printf("%s\n", "■");
  for (int w = 0; w < (Width+2);w++)
   printf("%s", "■");
  output->gotoxy(3, 3 + Height + 1);
  for (int w = 0; w < (Width + 2); w++)
   printf("%s", "■");
  for (int h = 0; h < (Height + 2); h++)
  {
   output->gotoxy(3, 3 + h);
   printf("%s", "■");
   output->gotoxy(3+(Width+1)*2, 3 + h);
   printf("%s", "■");
  }

 }

 void Run()
 {
  COORD pos;
  pos.X = 5;
  pos.Y = 4;
  output->gotoxy(5, 4);
  bool run = true;
  while (run)
  {
   char ch = _getch();
   switch (ch)
   {
   case 72:  //printf("UP\n"); break;
   {
    pos.Y--;
    pos.Y = pos.Y < 4 ? 4 : pos.Y;
    output->gotoxy(pos.X, pos.Y);
   }break;
   case 80:  //printf("DOWN\n"); break;
   {
    pos.Y++;
    pos.Y = pos.Y > (4 + Height - 1) ? (4 + Height - 1) : pos.Y;
    output->gotoxy(pos.X, pos.Y);
   }break;
   case 75:  //printf("LEFT\n"); break;
   {
    pos.X-=2;
    pos.X = pos.X >= 5 ? pos.X : 5;
    output->gotoxy(pos.X, pos.Y);
   }break;
   case 77:  //printf("RIGHT\n"); break;
   {
    pos.X += 2;
    pos.X = pos.X <= 5+(Width-1)*2 ? pos.X : 5 + (Width - 1) * 2;
    output->gotoxy(pos.X, pos.Y);
   }break;
   case 13:  //Enter
   {
    int h = pos.Y - 4;
    int w = (pos.X - 5) >> 1;
    bool ret = show(h, w);
    if (!ret)
    {
     output->gotoxy(70, 0);
     printf("你输了!!!");
     return;
    }
    else if((right+num) == (Width*Height))
    {
     output->gotoxy(70, 0);
     printf("胜利!!!");
     for (int h = 0; h < Height; h++)
     {
      for (int w = 0; w < Width; w++)
      {
       show(h, w);
      }
     }
     return;
    }
   }
   }
  }
 }

 bool show(int h,int w)
 {
  int ret = true;
  output->gotoxy(5 + w * 2, 4 + h);
  switch (table[h][w])
  {
  case -2:break;//已处理过
  case -1:
   printf("%s", "★");
   ret = false;
   break;
  case 0:
   bfs(h,w);
   break;
  default:
   printf("%c ", table[h][w]+‘0‘);
   right++;
   table[h][w] = -2;
  }
  output->gotoxy(5 + w * 2, 4 + h);
  return ret;
 }

 void bfs(int h,int w)
 {
  using std::queue;
  queue<pair> q;
  q.push(make_pair(h, w));

  while (!q.empty())
  {
   pair n = q.front();
   q.pop();
   int h = n.first;
   int w = n.second;
   if (table[h][w] == -2)continue;
   output->gotoxy(5 + w * 2, 4 + h);
   if (table[h][w] == 0)
   {
    printf("%s", "  ");
    right++;
    int pos[][2] = { { -1,-1 },{ -1,1 },{ -1,0 },{ 0,1 },{ 0,-1 },{ 1,-1 },{ 1,1 },{ 1,0 } };

    for (int k = 0; k < 8; k++)
    {
     int hh = pos[k][0] + h;
     int ww = pos[k][1] + w;
     if (InWindow(hh, ww) && table[hh][ww]>=0)
     {
      q.push(make_pair(hh, ww));
     }
    }
   }
   else
   {
    printf("%c ", table[h][w] + ‘0‘);
    right++;
   }
   table[h][w] = -2;

  }
 }

 bool InWindow(int h, int w)
 {
  return h >= 0 && h < Height && w >= 0 && w < Width;
 }

private:
 Screen* output;
 int Width;  //窗口宽度
 int Height; //窗口高度
 int num;    //雷的数量
 int right;
 vector<vector> table;
};

int main()
{
 Screen::instance()->Init();
 Screen::instance()->gotoxy(20, 20);
 SL game;
 game.Init();
 game.DrawOut();
 game.DrawIn();
 game.Run();
 system("pause");
 return 0; 
}

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言C/C+频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 2 不喜欢 | 0
看完这篇文章有何感觉?已经有2人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程