C語言實現經典游戲——掃雷!


前言

掃雷游戲是一款大眾類的益智小游戲,於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));
                           數組  要賦值的值   數組的大小

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM