C语言实现minesweeper扫雷

来源:互联网 发布:mysqlsla windows下载 编辑:程序博客网 时间:2024/04/30 01:24

首先说一下,我的这个小程序没有用什么算法,就是一个很小白的程序,求不喷。

先说一下思路,我是计划用一个二维数组来储存一切数据,即一个扫雷图的全部数据。一切都在这个二维数组里操作。废话不多说,先上程序。

#include <stdio.h>#include <stdlib.h>     //包含srand()和rand()函数#define SIZE 9          //数组大小(SIZE * SIZE)_Bool life = 1;         //标志是否Gameovervoid setbomb(char (*array)[SIZE]);              //设定炸弹的位置void setnum(char (*array)[SIZE]);      //计算炸弹数int countbomb_square(char (*array)[SIZE], int x, int y);   //计算每个九宫格的炸弹数void check(char (*array)[SIZE], int x, int y);        //接受输入和操作void printpic(char (*array)[SIZE]);              //打印图像int main(void){    int x = 0, y = 0;       //储存用户输入的位置    char array[SIZE][SIZE] = {{0}};    setbomb(array);    setnum(array);    while(1){        printpic(array);      //打印图像        if(0 == life)          //判断是否Gameover    break;        printf("Enter your chosen in formatted(x y): ");        if(0 == scanf("%d%d", &x, &y))            break;        check(array, x, y);   //处理输入    }    if(life)        printf("You win!\n");    else        printf("You lost!\n");    return 0;}void setbomb(char (*array)[SIZE]){    int index1 = 0, index2 = 0;    int temp;    srand((unsigned int)time(NULL));    for(index1 = 0; index1 < SIZE; index1++){        for(index2 = 0; index2 < SIZE; index2++){            temp = rand() % 90;            if((60 < temp) && (temp < 90))            // 1/3 的空格设有炸弹                array[index1][index2] = -1;        }    }}void setnum(char (*array)[SIZE]){    int index1 = 0, index2 = 0;    for(index1 = 0; index1 < SIZE; index1++){        for(index2 = 0; index2 < SIZE; index2++){            if(-1 == array[index1][index2])                array[index1][index2] += 10;              //数字大于8的空格不可见            else                array[index1][index2] = countbomb_square(array, index1, index2) + 10;        }    }}int countbomb_square(char (*array)[SIZE], int row, int column){    int count = 0;    int start_row, final_row;    int start_column, final_column, temp_column;    if(0 != row && SIZE - 1 != row)               //有三种可能,最大的可能是中间的空格        start_row = row - 1, final_row = row + 1;    else if(0 == row)                       //在第一行的空格        start_row = row, final_row = row + 1;    else if(SIZE - 1 == row)                //在最后一行的空格        start_row = row - 1, final_row = row;    if(0 != column && SIZE - 1 != column)               //也有三种可能,中间的空格        start_column = column - 1, final_column = column + 1;    else if(0 == column)                      //在第一列的空格        start_column = column, final_column = column + 1;    else if(SIZE - 1 == column)               //在最后一列的空格        start_column = column - 1, final_column = column;    temp_column = start_column;    for(; start_row <= final_row; start_row++){        start_column = temp_column;        for(; start_column <= final_column; start_column++){            if((-1 == array[start_row][start_column]) || ( -1 + 10 == array[start_row][start_column]))                count++;                              //未处理的炸弹格式-1,但处理过的炸弹格+10等于9        }    }    return count;}void check(char (*array)[SIZE], int x, int y){    if((0 <= array[x][y]) && (array[x][y] <= 8))       //空格已打开,已可见        return;    if(-1 == array[x][y] - 10){    //Gameover, 更改life的值        array[x][y] -= 10;        life = 0;    }    else if(8 < array[x][y])        array[x][y] -= 10;        //打开空格}void printpic(char (*array)[SIZE]){    int index1 = 0, index2 = 0;    system("cls");    printf("|*");    for(index1 = 0; index1 < SIZE; index1++)        printf("|%d", index1);    printf("|\n");    for(index1 = 0; index1 < SIZE; index1++){        for(index2 = 0; index2 < SIZE; index2++)            printf("---");        printf("\n|%d", index1);        for(index2 = 0; index2 < SIZE; index2++){            if(8 < array[index1][index2])              //大于8,不可见                printf("| ");            else if((0 <= array[index1][index2]) && (array[index1][index2] <= 8))  //非炸弹格                printf("|%d", array[index1][index2]);            else if(-1 == array[index1][index2])              //炸弹格                printf("|*");        }        printf("|\n");    }}



实现方法是在二维数组内随机填入炸弹(用值-1表示),再逐个元素计算在以它为中心的九宫格内的炸弹数并填入数字,之后把所有的格子隐藏起来,按玩家的输入打开,如果选中炸弹就游戏结束。

程序的核心是计算九宫格内的炸弹数,以下是详细讲解。

用FOR循环来遍历整个二维数组,对每个元素即格子计算炸弹数。


以每个格子为中心的九宫格就如上图所示,行从Row-1行开始到Row+1行,列从Column-1到Column+1,用两个FOR循环来实现九宫格的遍历。还有一个前提,中心的格子,即(Row,Column)没有炸弹,即如果格子有炸弹就跳过这个格子。

还有一些特殊情况,即第一行和最后一行,第一列和最后一列。因为行和列互不影响,所以可以分开处理。

先处理行。


如图所示,行有三种情况,第一行,最后一行和中间的格子。

    if(0 != row && SIZE - 1 != row)               //有三种可能,最大的可能是中间的空格        start_row = row - 1, final_row = row + 1;    else if(0 == row)                       //在第一行的空格        start_row = row, final_row = row + 1;    else if(SIZE - 1 == row)                //在最后一行的空格        start_row = row - 1, final_row = row;

接着是列的处理,也是三种情况,第一,最后,中间,和行的一样。


以下是代码

    if(0 != column && SIZE - 1 != column)               //也有三种可能,中间的空格        start_column = column - 1, final_column = column + 1;    else if(0 == column)                      //在第一列的空格        start_column = column, final_column = column + 1;    else if(SIZE - 1 == column)               //在最后一列的空格        start_column = column - 1, final_column = column;


确定行和列的起始和结束之后,就是九宫格内逐个遍历,计算过炸弹的数量并填入格子内。
    temp_column = start_column;    for(; start_row <= final_row; start_row++){        start_column = temp_column;        for(; start_column <= final_column; start_column++){            if((-1 == array[start_row][start_column]) || ( -1 + 10 == array[start_row][start_column]))                count++;                              //未处理的炸弹格式-1,但处理过的炸弹格+10等于9        }    }

因为列在每个内循环里都要重新开始,为了效率,添加了一个变量temp_column储存它。

核心的东西已经讲完了,这是一个简陋的扫雷程序,没有标志炸弹位置的功能,也没有打开空格的功能,但可以自己添加上去,自己完善它,就说到这里吧。


0 0
原创粉丝点击