数组应用之扫雷小游戏的设计

游戏准备

游戏介绍
扫雷游戏就是一个方格面上埋藏有雷,一旦玩家点击雷点即失败本轮游戏结束,只有成功将所有无雷点找出点击即为成功,每次点击到不是雷电的地方时,界面将会显示数字表示以该坐标为中心的周围至多8个点的雷个数
需要实现
需要准备游戏开局的菜单以及采用两个二维数组一个用来布雷,一个用来显示玩家每一步的雷点情况,将最初游戏界面初始化

开局界面布置

目的
实现菜单的输出以及采用循环的方式使玩家可以决定继续玩还是终止游戏
代码实现

void menu(){
    printf("***************************\n");
    printf("**********  1.play ********\n");
    printf("**********  0.exit ********\n");
    printf("***************************\n");
}
int main( ){
    srand((unsigned int)time(NULL));
    int input = 0;
    do{
        menu();
        printf("please choose:>");
        scanf("%d",&input);
        switch(input){
            case 1:
                game( );//三子棋游戏
                break;
            case 0:
                printf("quit a game\n");//退出游戏
                break;
            default:
                printf("please input again\n");//重新输入
                break;
        }
    }
    while(input);
    return 0;
}

布雷

目的
创建两个二维数组,并将棋盘随机安置上适量炸弹,游戏开始打印初始游戏界面
注意事项
1.创建二维数组时因为存在需要了解周围8个雷的布局情况,边上的元素较难讨论,因此在创建时将原来的格数+2,使游戏界面多一圈,如图所示
在这里插入图片描述
2.创建为字符数组较为合适
3.进行布雷时将有雷置为’1’,无雷置为’0’,原因后续会讲到
4.打印界面时为了美观易看,可以打上对应坐标,且打印时只需打印游戏界面的行列数即可
代码实现

#define EASY_COUNT 10//表示埋下的雷的个数

#define ROW 9//游戏界面的行数
#define COL 9//游戏界面的列数

#define ROWS ROW+2//将游戏界面扩大一圈,以便计算雷个数
#define COLS COL+2
//初始化棋盘
void initboard(char board[ROWS][COLS],int rows,int cols,char set){
    int i,j;
    for(i = 0;i < rows;i++){
        for(j = 0;j < cols;j++){
            board[i][j] = set; 
        }
    }
}
//打印棋盘
void displayboard(char board[ROWS][COLS],int row,int col){
    int i,j;
    printf("--------------------------------\n");
    for(i = 0;i <= col;i++){
        printf("%d ",i);
    }
    printf("\n");
    for(i = 1;i <= row;i++){
        printf("%d ",i);
        for(j = 1;j <= col;j++){
            printf("%c ",board[i][j]);
        }
        printf("\n");
    }
    printf("--------------------------------\n");
}
//布雷
void setmine(char mine[ROWS][COLS],int row,int col,int count){
    while(count){
        int x = rand()%row+1;//电脑随机值取雷点坐标
        int y = rand()%col+1;
        if(mine[x][y] == '0'){//座标处不是雷
            mine[x][y] = '1';
            count--;
        }
    }
}

输出
在这里插入图片描述

游戏过程

排查雷

目的
用另一个show的数组来显示每次操作后的界面
关键点
1.由于采用的是字符0和1,所以可以将周围8个字符转化为整型数后相加,和即为玩家点击坐标的整型数,再将其转为字符类型即可
注:‘1’-‘0’= 1(数字),‘0’-‘0’=0(数字)
2.由于当所有非雷点被找到后为胜利,所以该函数实现时需要有一个判断条件
3.要考虑到坐标合法与否以及是否时雷点两方面
代码实现

//统计mine数组x,y坐标周围有几个雷
int getmine(char mine[ROWS][COLS],int x,int y){
    //'1'-'0'= 1(数字),'0'-'0'=0(数字),只需将八个周围相加即可
    return mine[x-1][y]+mine[x-1][y-1]+mine[x-1][y+1]+mine[x][y-1]+
    mine[x][y+1]+mine[x+1][y-1]+mine[x+1][y]+mine[x+1][y+1]-8*'0';//将字符转化为数字
}

void findmine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col){
    int win = 0;
    while(win < row*col-EASY_COUNT){///非雷点的个数
        printf("please input the coodinates:>");
        int x = 0;
        int y = 0;
        scanf("%d%d",&x,&y);
        //1.坐标合法性 2.排雷
        if(x >= 1 && x <= row && y >= 1 && y <= col){//坐标合法
            if(mine[x][y] == '1'){//如果该点为雷
                printf("sorry,you are boom\n");
                displayboard(mine,row,col);
                break;
            }
            else{//该点非雷点
                int count = getmine(mine,x,y);//统计周围雷的个数
                show[x][y] = count+'0';
                displayboard(show,row,col);
                win++;
            }
        }
        else{//坐标不合法
            printf("illegal,please input again:>");
        }
    }
    if(win == row*col-EASY_COUNT){//如果所有非雷点被找到,则胜利
        printf("congratulate! you win\n");
        displayboard(mine,row,col);
    }
}

输出
在这里插入图片描述

总体游戏代码的实现

void game( ){
    //创建对应数组
    char mine[ROWS][COLS];
    char show[ROWS][COLS];
    initboard(mine,ROWS,COLS,'0');
    initboard(show,ROWS,COLS,'*');
    //打印棋盘
    //displayboard(mine,ROW,COL);
    displayboard(show,ROW,COL);
    //布置雷
    setmine(mine,ROW,COL,EASY_COUNT);
    //排查雷
    findmine(mine,show,ROW,COL);
}

最终代码

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define EASY_COUNT 10//表示埋下的雷的个数

#define ROW 9//游戏界面的行数
#define COL 9//游戏界面的列数

#define ROWS ROW+2//将游戏界面扩大一圈,以便计算雷个数
#define COLS COL+2
//初始化棋盘
void initboard(char board[ROWS][COLS],int rows,int cols,char set){
    int i,j;
    for(i = 0;i < rows;i++){
        for(j = 0;j < cols;j++){
            board[i][j] = set; 
        }
    }
}
//打印棋盘
void displayboard(char board[ROWS][COLS],int row,int col){
    int i,j;
    printf("--------------------------------\n");
    for(i = 0;i <= col;i++){
        printf("%d ",i);
    }
    printf("\n");
    for(i = 1;i <= row;i++){
        printf("%d ",i);
        for(j = 1;j <= col;j++){
            printf("%c ",board[i][j]);
        }
        printf("\n");
    }
    printf("--------------------------------\n");
}
//布雷
void setmine(char mine[ROWS][COLS],int row,int col,int count){
    while(count){
        int x = rand()%row+1;//电脑随机值取雷点坐标
        int y = rand()%col+1;
        if(mine[x][y] == '0'){//座标处不是雷
            mine[x][y] = '1';
            count--;
        }
    }
}
//统计mine数组x,y坐标周围有几个雷
int getmine(char mine[ROWS][COLS],int x,int y){
    //'1'-'0'= 1(数字),'0'-'0'=0(数字),只需将八个周围相加即可
    return mine[x-1][y]+mine[x-1][y-1]+mine[x-1][y+1]+mine[x][y-1]+
    mine[x][y+1]+mine[x+1][y-1]+mine[x+1][y]+mine[x+1][y+1]-8*'0';//将字符转化为数字
}

void findmine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col){
    int win = 0;
    while(win < row*col-EASY_COUNT){///非雷点的个数
        printf("please input the coodinates:>");
        int x = 0;
        int y = 0;
        scanf("%d%d",&x,&y);
        //1.坐标合法性 2.排雷
        if(x >= 1 && x <= row && y >= 1 && y <= col){//坐标合法
            if(mine[x][y] == '1'){//如果该点为雷
                printf("sorry,you are boom\n");
                displayboard(mine,row,col);
                break;
            }
            else{//该点非雷点
                int count = getmine(mine,x,y);//统计周围雷的个数
                show[x][y] = count+'0';
                displayboard(show,row,col);
                win++;
            }
        }
        else{//坐标不合法
            printf("illegal,please input again:>");
        }
    }
    if(win == row*col-EASY_COUNT){//如果所有非雷点被找到,则胜利
        printf("congratulate! you win\n");
        displayboard(mine,row,col);
    }
}

void menu(){
    printf("***************************\n");
    printf("**********  1.play ********\n");
    printf("**********  0.exit ********\n");
    printf("***************************\n");
}
void game( ){
    //创建对应数组
    char mine[ROWS][COLS];
    char show[ROWS][COLS];
    initboard(mine,ROWS,COLS,'0');
    initboard(show,ROWS,COLS,'*');
    //打印棋盘
    //displayboard(mine,ROW,COL);
    displayboard(show,ROW,COL);
    //布置雷
    setmine(mine,ROW,COL,EASY_COUNT);
    //排查雷
    findmine(mine,show,ROW,COL);
}
int main( ){
    srand((unsigned int)time(NULL));
    int input = 0;
    do{
        menu();
        printf("please choose:>");
        scanf("%d",&input);
        switch(input){
            case 1:
                game( );//三子棋游戏
                break;
            case 0:
                printf("quit a game\n");//退出游戏
                break;
            default:
                printf("please input again\n");//重新输入
                break;
        }
    }
    while(input);
    return 0;
}

输出结果请自行尝试

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值