C初级_函数、分支、循环、图形库复习

(本次复习依托扫雷游戏的编写,对前文所学图形库、函数、分支、循环、等内容进行复习,重点内容及相关说明如下)

1.扫雷游戏规则

本次扫雷游戏规则及要求为:要求绘制500*500的地图,共100个格子。要求在这100个格子里随机分布10个雷,在初始状态下,玩家见到全部被方块覆盖的地图。鼠标左键一次,如果按到雷则提示游戏结束,如果非雷,则显示这个点显示四周(包括对角)的雷的数量;鼠标右键用来标记该地点可能有雷的存在,再次点击旗子则撤销旗子。游戏胜利为全部点完全部数无雷区域,游戏结束标志为点到雷。

2.鼠标操作

MOUSEMSG 定义一个鼠标结构体(相当于定义一边变量)

以下内容可以用 msg.XXX 的方式使用(msg为定义的鼠标名,XXX为可替代名)
uMsg; // 当前鼠标消息
mkCtrl; // Ctrl 键是否按下
mkShift; // Shift 键是否按下
mkLButton; // 鼠标左键是否按下
mkMButton; // 鼠标中键是否按下
mkRButton; // 鼠标右键是否按下
x; // 当前鼠标 x 坐标
y; // 当前鼠标 y 坐标
wheel; // 鼠标滚轮滚动值 (120 的倍数)

相关的鼠标消息
// WM_MOUSEMOVE 鼠标移动
// WM_MOUSEWHEEL 鼠标滚轮拨动
// WM_LBUTTONDOWN 左键按下
// WM_LBUTTONUP 左键弹起
// WM_LBUTTONDBLCLK 左键双击
// WM_MBUTTONDOWN 中键按下
// WM_MBUTTONUP 中键弹起
// WM_MBUTTONDBLCLK 中键双击
// WM_RBUTTONDOWN 右键按下
// WM_RBUTTONUP 右键弹起
// WM_RBUTTONDBLCLK 右键双击

3.图形库

图形库的使用包括定义一个画板、加载图形库函数、关闭图形姐妹三个部分(组成要完整,不然无法正确使用)
定义一个画版:initgraph(numb1,numb2);
加载图形库函数:
加载图片:loadimage(&image[],L"文件位置“);
输出图片:putimage(numb1i,numb2j,&image[]);
(更多常见函数请见easyx库)
关闭图形界面:closegraph();

4.循环结构、分支结构、函数、数组

格式占位符的详细内容请见格式站位符文末

if语句、switch语句的详细内容请见分支结构
需要说明的是:
if语句有三种写法,else后不加条件,if的条件后直接加; 则表示无执行语句
switch语句的default:后可以加执行语句,表示其他条件都不满足的情况下执行(前提是,每个条件后都有break;)

while、for、do while 语句的详细说明请见循环结构
需要说明的是:
三目运算符与for有着相似的作用,但是for写起来更加直观、易懂

上述的循环结构和分支结构均可相互嵌套

函数的详细说明请见函数-基本函数-传参
需要说明的是:
如果定义了全局变量,那么在函数中只要使用了全局变量,那么只要全局变量发生变化,函数的下次执行会按照新的值进行
(后文会学通过指针改变实参的值,需要注意区别)

数组详细的说明请见数组说明
数组需要注意的是:
数组的赋值通常与for循环进行搭配
数组与指针还有部分交集,请见数组说明

5.说明

1.存在一个bug
实例中的代码运行以及说明本次复习所需内容已经满足,但是存在持续右键出错的bug,未改2
2.循环的起始值、数组的起始值
循环的起始值,特别是for循环是自己定义的,
数组的起始值,都从下标为0开始(也就是下标为0,是数组的第一个元素)
4.本次扫雷的关键点
理解扫雷,除了应具备上述基础知识以外,还应该了解扫雷的游戏规则及设计思路,这样在写起来才知道每一步在做什么

6.代码实例

#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<time.h>
#include<easyx.h>

IMAGE image[12];
int map[10][10] = { 0 };
int flag = 0;//用于判断游戏是否结束

void inIt()
{
 //加载图片
 loadimage(&image[0], L"素材/数字0.jpg");
 loadimage(&image[1], L"素材/数字1.jpg");
 loadimage(&image[2], L"素材/数字2.jpg");
 loadimage(&image[3], L"素材/数字3.jpg");
 loadimage(&image[4], L"素材/数字4.jpg");
 loadimage(&image[5], L"素材/数字5.jpg");
 loadimage(&image[6], L"素材/数字6.jpg");
 loadimage(&image[7], L"素材/数字7.jpg");
 loadimage(&image[8], L"素材/数字8.jpg");
 loadimage(&image[9], L"素材/雷.jpg");
 loadimage(&image[10], L"素材/方块.jpg");
 loadimage(&image[11], L"素材/红旗.jpg");

 //用随机数生成10个雷
 srand((unsigned)time(NULL));
 int x, y;
 for (int i = 0; i < 10; )
 {
  x = rand() % 10;
  y = rand() % 10;
  if (map[x][y] != -1)
  {
   map[x][y] = -1;
   ++i;
  }
 }

 //计算每个格周围的雷数量
 for (int i = 0; i < 10; ++i)
 {
  for (int j = 0; j < 10; ++j)
  {
   if (map[i][j] == -1)
   {
    for (int q = i - 1; q < i + 1; ++q)
    {
     for (int w = j - 1; w < j + 1; ++w)
     {
      if (q >= 0 && q <= 10 && w >= 0 && w <= 10 && map[q][w] != -1)
      {
       map[q][w] += 1;
      }
     }
    }
   }
  }
 }
}

void draw()
{
 for (int i = 0; i < 10; ++i)
 {
  for (int j = 0; j < 10; ++j)
  {
   switch (map[i][j])
   {
    case 10:putimage(50 * i, 50 * j, &image[0]); break;
    case 11:putimage(50 * i, 50 * j, &image[1]); break;
    case 12:putimage(50 * i, 50 * j, &image[2]); break;
    case 13:putimage(50 * i, 50 * j, &image[3]); break;
    case 14:putimage(50 * i, 50 * j, &image[4]); break;
    case 15:putimage(50 * i, 50 * j, &image[5]); break;
    case 16:putimage(50 * i, 50 * j, &image[6]); break;
    case 17:putimage(50 * i, 50 * j, &image[7]); break;
    case 18:putimage(50 * i, 50 * j, &image[8]); break;//前面为数字0-8
    case 19:putimage(50 * i, 50 * j, &image[9]); break;//雷
    case 21:putimage(50 * i, 50 * j, &image[11]); break;//红旗
    default:putimage(50 * i, 50 * j, &image[10]); break;//方块
   }
  }
 }
}

void play()
{
 MOUSEMSG msg;
 int i, j;
 while (1)
 {
  msg = GetMouseMsg();
    switch (msg.uMsg)
  {
  case WM_LBUTTONDOWN:
    {
   i = msg.x / 50;
   j = msg.y / 50;
   if (map[i][j] == 0)
   {
       for (int q = i - 1; q <= i + 1; ++q)
    {
     for (int w = j - 1; w <= j + 1; ++w)
     {
      if (q >= 0 && q <= 9 && w >= 0 && w < 10 && map[q][w] != -1)
      {
       if (map[q][w] <= 8)
       {
        map[q][w] += 10;
        flag++;
               }
      }
     }
    }
   }
      else if (map[i][j] == -1)
   {
    flag = -1;
    return;
   }
      else if (map[i][j] <= 8)
   {
    map[i][j] += 10;
    flag++;
    return;
   }
  }
    break;
      case WM_RBUTTONDOWN:
   i = msg.x / 50;
   j = msg.y / 50;
   if (map[i][j] == 21)
   {
    putimage(50 * i, 50 * j, &image[10]);
    map[i][j] = 0;
   }
   else
   {
    putimage(50 * i, 50 * j, &image[11]);
    map[i][j] = 21;
   }
   break;
     }
 }
}

int main()
{
 initgraph(500, 500);
 inIt();
 while (1)
 {
  draw();
  play();
  if (flag == -1)
  {
   if (MessageBox(GetHWnd(), L"GAMEOVER", L"您输了!", MB_RETRYCANCEL) == IDRETRY)
   {
    for (int i = 0; i < 10; i++)
    {
     for (int j = 0; j < 10; j++)
     {
      map[i][j] = 0;
     }
    }
    inIt();
   }
   else
   {
    exit(0);
   }
  }
  else if (flag == 10 * 10 - 3)//3个雷
  {
   if (MessageBox(GetHWnd(), L"太厉害了", L"你赢了", MB_YESNO) == IDYES)
   {
    for (int i = 0; i < 10; i++)
    {
     for (int j = 0; j < 10; j++)
     {
      map[i][j] = 0;
     }
    }
    inIt();
   }
   else
   {
    exit(0);
   }
  }
 }
 system("pause");
 closegraph();
 return 0;
}   

猜你喜欢

转载自blog.csdn.net/weixin_41743247/article/details/88535236
今日推荐