扫雷游戏

来源:互联网 发布:java 防止xss攻击 编辑:程序博客网 时间:2024/05/20 18:55

用c语言编写扫雷游戏:
1.扫雷的基本功能
2.第一次扫,不被炸死
3.当周围没有雷的时候可以向外延伸扩展。

完成这个游戏需要构造几个函数:
a.初始化雷盘;
b.打印雷盘;
c.设雷的数目;
d.统计点击之处雷的个数;
e.重新布雷;
f.扩展式排雷

game.h //头文件部分

#ifndef __GAME_H__#define __GAME_H__#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <windows.h>#define ROW 12 //实际行数#define COL 12 //实际列数#define ROWS (ROW-2)//雷盘行数#define COLS (COL-2)//雷盘列数#define  MINE 10 //雷数void init_board(char arr[ROW][COL],char set,int row,int col);//初始化棋盘void print_board(char arr[ROW][COL],int row,int col);//打印棋盘void set_mine(char arr[ROW][COL],int row,int col);//布雷int get_count(char arr[ROW][COL],int x,int y);//统计点击之处雷的个数void reset_mine(char arr[ROW][COL],int x,int y,int row,int col);//重新布雷void expend(char arr1[ROW][COL], int x, int y, int *ret, char arr2[ROW][COL]);//扩展排雷#endif //__GAME_H__

game.c //游戏部分

#define _CRT_SECURE_NO_WARNINGS 1#include "game.h"void init_board(char arr[ROW][COL],char set,int row,int col)//初始化棋盘{        memset(arr,set,row*col*sizeof(arr[0][0]));//memset初始化,括号内为:数组名,初始化目标,初始化字节数}void print_board(char arr[ROW][COL],int row,int col)//打印棋盘{    int i = 0;    int j = 0;    printf("   ");    for(i=1;i<row-1;i++)//打印列号    {        printf("%d  ",i);    }     printf("\n");    for(i=1;i<row-1;i++)    {        printf("%2d ",i);        for(j=1;j<col-1;j++)        {            printf("%c  ",arr[i][j]);        }        printf("\n");    }}void set_mine(char arr[ROW][COL],int row,int col){    int count = MINE;    int x = 0;    int y = 0;    while(count>0)    {        x = rand() % ROWS+1;//产生随机数        y = rand() % COLS+1;        if(arr[x][y]=='0')        {            arr[x][y]='1';            count--;        }    }}void reset_mine(char arr[ROW][COL],int x,int y,int row,int col){    int count = 1;;    arr[x][y] = '0';    while (count)    {        int i = rand() % ROWS + 1;        int j = rand() % COLS + 1;        if ((arr[i][j] != '1') && (i != x) && (j != y))        {            arr[i][j] = '1';            count--;        }    }}int get_count(char arr[ROW][COL],int x,int y){    return arr[x-1][y-1]    +arr[x+1][y+1]+arr[x][y-1]    +arr[x][y+1]+arr[x-1][y]    +arr[x+1][y-1]+arr[x+1][y]    +arr[x-1][y+1]-8*'0';//雷周围8个数,返回雷数int值}void expend(char arr1[ROW][COL],int x,int y,int* ret,char arr2[ROW][COL]){    int i = 0;    int j = 0;    int count = 0;//点击之处周围雷数    if(arr2[x][y]=='*')//未被排雷    {        (*ret)++;        count = get_count(arr1,x,y);        if(count!=0)//周围雷数不为0        {            arr2[x][y]=count+'0';//显示雷数        }        else // 周围八个位置扩展排雷        {            arr2[x][y]='0';            for(i=-1;i<=1;i++)            {                for(j=-1;j<=1;j++)                {                    if((x+i>=1)&&(x+i<=ROWS)&&(y+j>=1)&&(y+j<=COLS))                    {                        if(i!=0||j!=0)                            expend(arr1,x+i,y+j,ret,arr2);                    }                }            }        }    }}

test.c //测试部分

#define _CRT_SECURE_NO_WARNINGS 1#include "game.h"void menu(){    printf("***********************\n");    printf("*****    1.play   *****\n");    printf("*****    0.exit   *****\n");    printf("***********************\n");}void game(){    int x = 0;    int y = 0;    int ret = 0;//找到非雷的次数    char mine[ROW][COL] = {0};    char show[ROW][COL] = {0};    init_board(mine,'0',ROW,COL);    init_board(show,'*',ROW,COL);    set_mine(mine,ROW,COL);//布雷    print_board(show,ROW,COL);    printf("\n");    print_board(mine,ROW,COL);//打印棋盘    while(ret<(ROWS*COLS-MINE))    //开始排雷    {        printf("请输入坐标(x,y)-> ");        scanf("%d%d",&x,&y);        if(((x>=1)&&(x<=ROWS))&&(y>=1)&&(y<=COLS))//输入有效坐标        {            if(mine[x][y]=='1')//所选位置有雷            {                if(ret!=0)                {                    printf("很遗憾,你被炸死了!\n");                    print_board(mine,ROW,COL);                    return;                }                else                {                    mine[x][y]='0';                    reset_mine(mine,x,y,ROWS,COLS);//重新布雷                    expend(mine,x,y,&ret,show);                }            }            else            {                expend(mine,x,y,&ret,show);            }            print_board(show,ROW,COL);        }        else        {            printf("输入的坐标无效,请重新输入!\n");        }    }    if(ret=(ROWS*COLS-MINE))    {        printf("恭喜你,排雷成功!\n");    }}    void test()    {        int input = 0;        srand((unsigned)time(NULL));//初始化时间种子        do        {            menu();            printf("请输入->");            scanf("%d",&input);            switch(input)            {            case 1:game();                break;            case 0:                break;            default:printf("输入错误,请重新输入!\n");                break;            }        }while(input);   }   int main()   {       test();       system("pause");       return 0;   }

游戏结果为:

这里写图片描述

这里写图片描述

#ifndef _GAME_H_

#endif // _GAME_H_

作用:防止头文件被重复引用

代码中用 memset函数初始化雷盘,
这里扩展一下此函数 memset函数原型为:

void *memset( void *dest,int c,size_t count );//扩号中分别为要初始化的目标,初始化内容,初始化个数

更多内容可以在MSDN上查询。

如代码:

#include <stdio.h>int main( void ){   char buffer[] = "This is a test of the memset function";   printf( "Before: %s\n", buffer );   memset( buffer, '*', 4 );   printf( "After:  %s\n", buffer );}

结果如图:
这里写图片描述

当我们写代码的时候会或多或少的遇到编译上的问题,这是我们不要急着去问老师或者度娘,应该自己先试着调试,这样下次就会避免再犯同类错误。vs2008上调试方法有:快捷键f5开始调试,f10 逐过程调试,f11逐语句调试。同样可以在窗口里看不同变量的变化,这些编译器里都有,我们应该熟练使用。

最后祝大家天天开心,下次再会!

原创粉丝点击