C语言实现经典游戏——扫雷!

风流意气都作罢 提交于 2020-04-18 12:06:01

前言

扫雷游戏是一款大众类的益智小游戏,于1992年发行。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷。我们可以通过C语言编程来实现游戏。我们可以把文件代码分别分在三个不同的文件下,game.h:头文件,game.c:用来具体完成函数代码,test.c:主要写逻辑函数。

写扫雷程序刚开始很多人可能没有思绪,我们可以先思考输入一个坐标而屏幕显示是否有雷,或者显示这个点的附近有几个雷,当然如果你还没学到这里。建议可以先去小编的C++交流.裙 :九起久伞吧起伞留伞(数字的谐音)转换下可以找到了,里面有最新C++教程项目,多跟里面的人交流,进步更快哦

仔细思考我们可以想到可以用两个数组完成,一个数组存放当,一个数组用来显示。当玩家输入坐标后,需判断这个坐标是有有雷然后把它信息存放在另一个数组显示出来。

 

  1.  
    int get_num(int x,int y)//雷的坐标
  2.  
    {
  3.  
    return rand() % (y - x + 1) + x;//x-y的随机数
  4.  
    }




  1.  
    void set_mine(char mine[ROWS][COLS])//初始化雷
  2.  
    {
  3.  
    int x = 0;
  4.  
    int y = 0;
  5.  
    int i = LEI;
  6.  
    srand((unsigned)time(NULL));
  7.  
     
  8.  
    while (i)
  9.  
    {
  10.  
    x = get_num(1, 9);
  11.  
    y = get_num(1, 9);
  12.  
     
  13.  
    if (mine[x][y] == '0')
  14.  
    {
  15.  
    mine[x][y] = '1';
  16.  
    i--;
  17.  
    }
  18.  
    }
  19.  
    }
雷的问题解决了,剩下的问题就好办了,开始时我们可以设置一个菜单函数供玩家选择是否进行游戏。

 

 

  1.  
    void menu()
  2.  
    {
  3.  
    printf("**********************************\n");
  4.  
    printf("******** 1.PLAY *************\n");
  5.  
    printf("******** 0.EXIT *************\n");
  6.  
    printf("**********************************\n");
  7.  
    }
当玩家开始玩游戏前,我们需要把两个数组进行初始化:
  1.  
    void init_game(char mine[ROWS][COLS], char show[ROWS][COLS])//数组初始化
  2.  
    {
  3.  
    memset(mine, '0', ROWS*COLS*sizeof(char));
  4.  
    set_mine(mine);//初始化雷的位置
  5.  
    memset(show, '*', ROWS*COLS*sizeof(char));
  6.  
     
  7.  
    }
然后我们可以把界面的数组打印出来(不要把雷的数组打印出来 偷笑

 

  1.  
    void display(char show[ROWS][COLS])//打印数组
  2.  
    {
  3.  
    int i = 0;
  4.  
    int j = 0;
  5.  
    // for (i = 0; i < ROWS; i++)
  6.  
    // {
  7.  
    //
  8.  
    // for (j = 0; j < COLS; j++)
  9.  
    // {
  10.  
    // printf(" %c ", mine[i][j]);
  11.  
    //
  12.  
    // }
  13.  
    // printf("\n");
  14.  
    // }
  15.  
    printf(" ");
  16.  
    for (i = 1; i < COLS - 1; i++)
  17.  
    {
  18.  
    printf(" %d ", i);
  19.  
    }
  20.  
    printf("\n");
  21.  
    for (i = 1; i < ROWS-1; i++)
  22.  
    {
  23.  
    printf("%d ", i);
  24.  
     
  25.  
    for (j = 1; j < COLS - 1; j++)
  26.  
    {
  27.  
     
  28.  
    printf(" %c ", show[i][j]);
  29.  
    }
  30.  
    printf("\n");
  31.  
    }
  32.  
     
  33.  
    }
下一步就是进行扫雷了,扫雷时我们需要判断是否猜到

 

  1.  
    void sweep(char mine[ROWS][COLS], char show[ROWS][COLS])//开始扫雷
  2.  
    {
  3.  
    int x = 0;
  4.  
    int y = 0;
  5.  
    int i = (ROWS-2)*(COLS-2)-LEI;
  6.  
     
  7.  
    while (i)
  8.  
    {
  9.  
    printf("请输入坐标:");
  10.  
    scanf("%d%d", &x, &y);
  11.  
    int ret = get_lei_nums(mine, x, y);
  12.  
    if ((x > 0 && x <ROWS - 1) && (y > 0 && y<COLS-1))
  13.  
    {
  14.  
    if (mine[x][y] == '1')
  15.  
    {
  16.  
    printf("您炸了,游戏结束\n");
  17.  
    return;
  18.  
    }
  19.  
    else
  20.  
    {
  21.  
    show[x][y]=ret+'0';
  22.  
    display(show);
  23.  
    i--;
  24.  
    }
  25.  
    }
  26.  
    else
  27.  
    {
  28.  
    printf("您输入的坐标不合法");
  29.  
    }
  30.  
    }
  31.  
    printf("Win!!!!!!!!!!!\n");
  32.  
    }
  33.  
    int get_lei_nums(char mine[ROWS][COLS],int x,int y)//判断附近雷的个数
  34.  
    {
  35.  
     
  36.  
    int count = 0;
  37.  
    if (mine[x - 1][y - 1] == '1')
  38.  
    count++;
  39.  
    if (mine[x][y - 1] == '1')
  40.  
    count++;
  41.  
    if (mine[x + 1][y - 1] == '1')
  42.  
    count++;
  43.  
    if (mine[x - 1][y] == '1')
  44.  
    count++;
  45.  
    if (mine[x + 1][y] == '1')
  46.  
    count++;
  47.  
    if (mine[x - 1][y + 1] == '1')
  48.  
    count++;
  49.  
    if (mine[x][y + 1] == '1')
  50.  
    count++;
  51.  
    if (mine[x + 1][y + 1] == '1')
  52.  
    count++;
  53.  
     
  54.  
    return count;
  55.  
    }

game.h

 

  1.  
    #define _CRT_SECURE_NO_WARNINGS 1
  2.  
    #ifndef __GAME__H__
  3.  
    #define __GAME__H__
  4.  
    #include <stdio.h>
  5.  
    #include <string.h>
  6.  
    #include <stdlib.h>
  7.  
    #include <time.h>
  8.  
    enum CH
  9.  
    {
  10.  
    EXIT,
  11.  
    PLAY
  12.  
    };
  13.  
    #define ROWS 11
  14.  
    #define COLS 11
  15.  
    #define LEI 10
  16.  
     
  17.  
     
  18.  
    void set_mine(char mine[ROWS][COLS]);
  19.  
    void init_game(char mine[ROWS][COLS], char show[ROWS][COLS]);
  20.  
    void display(char show[ROWS][COLS]);
  21.  
    void play_game(char mine[ROWS][COLS], char show[ROWS][COLS]);
  22.  
    void sweep(char mine[ROWS][COLS], char show[ROWS][COLS]);
  23.  
    int get_lei_nums(char mine[ROWS][COLS], int x,int y);
  24.  
     
  25.  
    #endif

game.c

 

  1.  
    #define _CRT_SECURE_NO_WARNINGS 1
  2.  
    #include "game.h"
  3.  
     
  4.  
    int get_num(int x,int y)//雷的坐标
  5.  
    {
  6.  
    return rand() % (y - x + 1) + x;//x-y的随机数
  7.  
    }
  8.  
    void set_mine(char mine[ROWS][COLS])//初始化雷
  9.  
    {
  10.  
    int x = 0;
  11.  
    int y = 0;
  12.  
    int i = LEI;
  13.  
    srand((unsigned)time(NULL));
  14.  
     
  15.  
    while (i)
  16.  
    {
  17.  
    x = get_num(1, 9);
  18.  
    y = get_num(1, 9);
  19.  
     
  20.  
    if (mine[x][y] == '0')
  21.  
    {
  22.  
    mine[x][y] = '1';
  23.  
    i--;
  24.  
    }
  25.  
    }
  26.  
    }
  27.  
    void init_game(char mine[ROWS][COLS], char show[ROWS][COLS])//数组初始化
  28.  
    {
  29.  
    memset(mine, '0', ROWS*COLS*sizeof(char));
  30.  
    set_mine(mine);//初始化雷的位置
  31.  
    memset(show, '*', ROWS*COLS*sizeof(char));
  32.  
     
  33.  
    }
  34.  
     
  35.  
    void display(char show[ROWS][COLS])
  36.  
    {
  37.  
    int i = 0;
  38.  
    int j = 0;
  39.  
    // for (i = 0; i < ROWS; i++)
  40.  
    // {
  41.  
    //
  42.  
    // for (j = 0; j < COLS; j++)
  43.  
    // {
  44.  
    // printf(" %c ", mine[i][j]);
  45.  
    //
  46.  
    // }
  47.  
    // printf("\n");
  48.  
    // }
  49.  
    printf(" ");
  50.  
    for (i = 1; i < COLS - 1; i++)
  51.  
    {
  52.  
    printf(" %d ", i);
  53.  
    }
  54.  
    printf("\n");
  55.  
    for (i = 1; i < ROWS-1; i++)
  56.  
    {
  57.  
    printf("%d ", i);
  58.  
     
  59.  
    for (j = 1; j < COLS - 1; j++)
  60.  
    {
  61.  
     
  62.  
    printf(" %c ", show[i][j]);
  63.  
    }
  64.  
    printf("\n");
  65.  
    }
  66.  
     
  67.  
    }
  68.  
    void sweep(char mine[ROWS][COLS], char show[ROWS][COLS])//开始扫雷
  69.  
    {
  70.  
    int x = 0;
  71.  
    int y = 0;
  72.  
    int i = (ROWS-2)*(COLS-2)-LEI;
  73.  
     
  74.  
    while (i)
  75.  
    {
  76.  
    printf("请输入坐标:");
  77.  
    scanf("%d%d", &x, &y);
  78.  
    int ret = get_lei_nums(mine, x, y);
  79.  
    if ((x > 0 && x<ROWS - 1) && (y > 0 && y<COLS-1))
  80.  
    {
  81.  
    if (mine[x][y] == '1')
  82.  
    {
  83.  
    printf("您炸了,游戏结束\n");
  84.  
    return;
  85.  
    }
  86.  
    else
  87.  
    {
  88.  
    show[x][y]=ret+'0';
  89.  
    display(show);
  90.  
    i--;
  91.  
    }
  92.  
    }
  93.  
    else
  94.  
    {
  95.  
    printf("您输入的坐标不合法");
  96.  
    }
  97.  
    }
  98.  
    printf("Win!!!!!!!!!!!\n");
  99.  
    }
  100.  
    int get_lei_nums(char mine[ROWS][COLS],int x,int y)//判断附近雷的个数
  101.  
    {
  102.  
     
  103.  
    int count = 0;
  104.  
    if (mine[x - 1][y - 1] == '1')
  105.  
    count++;
  106.  
    if (mine[x][y - 1] == '1')
  107.  
    count++;
  108.  
    if (mine[x + 1][y - 1] == '1')
  109.  
    count++;
  110.  
    if (mine[x - 1][y] == '1')
  111.  
    count++;
  112.  
    if (mine[x + 1][y] == '1')
  113.  
    count++;
  114.  
    if (mine[x - 1][y + 1] == '1')
  115.  
    count++;
  116.  
    if (mine[x][y + 1] == '1')
  117.  
    count++;
  118.  
    if (mine[x + 1][y + 1] == '1')
  119.  
    count++;
  120.  
     
  121.  
    return count;
  122.  
    }

test.c

 

  1.  
    #define _CRT_SECURE_NO_WARNINGS 1
  2.  
    #include"game.h"
  3.  
     
  4.  
    void play_game()
  5.  
    {
  6.  
    char mine[ROWS][COLS] = { 0 };
  7.  
    char show[ROWS][COLS] = { 0 };
  8.  
    init_game(mine, show);
  9.  
    display(show);
  10.  
    sweep(mine, show);
  11.  
     
  12.  
    }
  13.  
     
  14.  
    void menu()
  15.  
    {
  16.  
    printf("**********************************\n");
  17.  
    printf("******** 1.PLAY *************\n");
  18.  
    printf("******** 0.EXIT *************\n");
  19.  
    printf("**********************************\n");
  20.  
    }
  21.  
     
  22.  
    void game()
  23.  
    {
  24.  
     
  25.  
     
  26.  
    int input = 0;
  27.  
    menu();
  28.  
    printf("请选择:");
  29.  
    scanf("%d", &input);
  30.  
     
  31.  
    while (input)
  32.  
    {
  33.  
    switch (input)
  34.  
    {
  35.  
    case PLAY:
  36.  
    play_game();
  37.  
    break;
  38.  
    case EXIT:
  39.  
    break;
  40.  
    }
  41.  
    menu();
  42.  
    printf("请选择:");
  43.  
    scanf("%d", &input);
  44.  
    }
  45.  
    }
  46.  
     
  47.  
    int main()
  48.  
    {
  49.  
    game();
  50.  
    system("pause");
  51.  
    return 0;
  52.  
    }
注意:

1.在选择是否游戏时引用了枚举类型,方便以后对程序扩展

 

  1.  
    enum CH
  2.  
    {
  3.  
    EXIT,
  4.  
    PLAY
  5.  
    };
2.在设置雷的坐标时是随机数生成的。需要用到下面两条语句,头函数是<time.h>

 

srand((unsigned)time(NULL));
rand() % (y - x + 1) + x;//生成x-y的随机数。
3.再把数组初始化时用到了memset()函数:头文件是<string.h>

 

 

	memset(mine, '0', ROWS*COLS*sizeof(char));
                           数组  要赋值的值   数组的大小

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!