c语言实现扫雷的基础功能
扫雷大家应该都玩过,这是一个十分经典的游戏,今天我用c语言实现一下最基本简单的简易扫雷游戏,有如下几个功能:
1. 显示该点周围雷的个数
2. 第一次下子,不炸死
3. 坐标周围没雷,可以实现展开
先附上效果图:
游戏的时候我们只需要输入1-10的横纵坐标来模拟点击,就能玩简易的扫雷游戏。
如图中打印的第一个1/0图是显示雷的位置,我们可以看到坐标(1,2)是1,代表有雷,但基于第一次不死的原则,在这里我是将雷移到后面没有雷的位置,并显示周围九宫格内雷的数量,没有雷就展开,实现的代码如下:
void PlayGame(char mine[][COLS], char show[][COLS], int _rows, int _cols)
{
int x, y;
int time=1;
int is_win = 0;
showBoard(mine, ROWS, COLS);//雷面板
showBoard(show, ROWS, COLS);//游戏面板
while (1){
printf("Please enter<rows, cols>:> ");
scanf("%d%d", &x, &y);
if ((x >= 1 && x <= _rows - 2) && (y >= 1 && y <= _cols - 2)){
if (mine[x][y] == '0'){
int num = GetIndexMines(mine, x, y);//计算周围雷数
show[x][y] = num + '0';
is_win++;//计数已点开的非雷格数
if (num == 0)//周围无雷,其它格以空格形式展开
{
show[x - 1][y - 1] = ' ';
show[x - 1][y] = ' ';
show[x - 1][y + 1] = ' ';
show[x][y - 1] = ' ';
show[x][y + 1] = ' ';
show[x + 1][y - 1] = ' ';
show[x + 1][y] = ' ';
show[x + 1][y + 1] = ' ';
}
showBoard(show, ROWS, COLS);
if ((_rows - 2)*(_cols - 2) - is_win == DEFAULT_MINES){//每次下完后判断剩下的格数是否等于雷数,若等于,玩家胜利
showBoard(mine, ROWS, COLS);//雷面板
printf("YOU WIN:)\n");
}
}
else{
if ( time == 1 && mine[x][y] == '1')
{
mine[x][y] = '0';//若第一次点到雷,移走雷
int a = ROWS - 2;
int b = COLS - 2;
//while (m<1)
for (; a > 0; a--)
{
for (; b > 0; b--)
{
if (a == x && b == y)
{
continue;
}
if (mine[a][b] == '0')
{
mine[a][b] = '1';//将雷放到后面非雷位置
a = 0;
b = 0;
break;
}
}
}
int num = GetIndexMines(mine, x, y);
show[x][y] = num + '0';
is_win++;
if (num == 0)
{
show[x - 1][y - 1] = ' ';
show[x - 1][y] = ' ';
show[x - 1][y + 1] = ' ';
show[x][y - 1] = ' ';
show[x][y + 1] = ' ';
show[x + 1][y - 1] = ' ';
show[x + 1][y] = ' ';
show[x + 1][y + 1] = ' ';
}
showBoard(show, ROWS, COLS);
//showBoard(mine, ROWS, COLS);//雷面板
if ((_rows - 2)*(_cols - 2) - is_win == DEFAULT_MINES){
showBoard(mine, ROWS, COLS);//雷面板
printf("YOU WIN:)\n");
}
}
else{
printf("Game Over!\n");
showBoard(mine, ROWS, COLS);//雷面板
break;
}
}
}
else{
printf("Enter error,Try Again!\n");
}
time++;
}
}
计算安全格周围雷数
int GetIndexMines(char mine[][COLS], int _x, int _y)
{
return mine[_x - 1][_y - 1] + mine[_x - 1][_y] + 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';
}
所有代码如下:
#ifndef _MINE_H_
#define _MINE_H_
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<windows.h>
#define ROWS 12
#define COLS 12
#define DEFAULT_MINES 15
#pragma warning(disable:4996)
void SetMines(char mine[][COLS], int _rows, int _cols);
void showBoard(char show[][COLS], int _rows, int _cols);
int GetIndexMines(char mine[][COLS], int _x, int _y);
void PlayGame(char mine[][COLS], char show[][COLS], int _rows, int _cols);
void game();
#endif
#include "mine.h"
static void menu()//打印菜单
{
printf("##########################\n");
printf("## 1.play ###### 0.exit ##\n");
printf("##########################\n");
printf("Please Select:>");
}
int main()
{
int select = 0;
menu();
scanf("%d", &select);
switch (select){
case 0:
exit(0);
break;
case 1:
game();
break;
default:
break;
}
system("pause");
return 0;
}
#include "mine.h"
int GetRandomIndex(int start, int end)//随机布雷
{
return rand() % (end - start + 1) + start;
}
void showBoard(char show[][COLS], int _rows, int _cols)//打印棋盘
{
printf(" ");
int i = 1;
for (; i <= _cols-2; i++){
printf("%d ", i);
}
printf("\n");
printf("---");
for (i =1; i <= _cols - 2; i++){
printf("--");
}
printf("\n");
for (i = 1; i <= _rows - 2; i++){
printf("%2d|", i);
int j = 1;
for (; j <= _cols-2; j++){
printf("%c ", show[i][j]);//打印棋盘数组
}
printf("\n");
}
}
void SetMines(char mine[][COLS], int _rows, int _cols)
{
int count = DEFAULT_MINES;
srand((unsigned long)time(NULL));
while (count){
int x = GetRandomIndex(1, _rows - 2);
int y = GetRandomIndex(1, _cols - 2);
if (mine[x][y] == '0'){
mine[x][y] = '1';
count--;
}
}
}
int GetIndexMines(char mine[][COLS], int _x, int _y)
{
return mine[_x - 1][_y - 1] + mine[_x - 1][_y] + 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 PlayGame(char mine[][COLS], char show[][COLS], int _rows, int _cols)
{
int x, y;
int time=1;
int is_win = 0;
showBoard(mine, ROWS, COLS);//雷面板
showBoard(show, ROWS, COLS);//游戏面板
while (1){
printf("Please enter<rows, cols>:> ");
scanf("%d%d", &x, &y);
if ((x >= 1 && x <= _rows - 2) && (y >= 1 && y <= _cols - 2)){
if (mine[x][y] == '0'){
int num = GetIndexMines(mine, x, y);
show[x][y] = num + '0';
is_win++;
if (num == 0)
{
show[x - 1][y - 1] = ' ';
show[x - 1][y] = ' ';
show[x - 1][y + 1] = ' ';
show[x][y - 1] = ' ';
show[x][y + 1] = ' ';
show[x + 1][y - 1] = ' ';
show[x + 1][y] = ' ';
show[x + 1][y + 1] = ' ';
}
showBoard(show, ROWS, COLS);
if ((_rows - 2)*(_cols - 2) - is_win == DEFAULT_MINES){
showBoard(mine, ROWS, COLS);//雷面板
printf("YOU WIN:)\n");
}
}
else{
if ( time == 1 && mine[x][y] == '1')
{
mine[x][y] = '0';
int a = ROWS - 2;
int b = COLS - 2;
//while (m<1)
for (; a > 0; a--)
{
for (; b > 0; b--)
{
if (a == x && b == y)
{
continue;
}
if (mine[a][b] == '0')
{
mine[a][b] = '1';
a = 0;
b = 0;
break;
}
}
}
int num = GetIndexMines(mine, x, y);
show[x][y] = num + '0';
is_win++;
if (num == 0)
{
show[x - 1][y - 1] = ' ';
show[x - 1][y] = ' ';
show[x - 1][y + 1] = ' ';
show[x][y - 1] = ' ';
show[x][y + 1] = ' ';
show[x + 1][y - 1] = ' ';
show[x + 1][y] = ' ';
show[x + 1][y + 1] = ' ';
}
showBoard(show, ROWS, COLS);
//showBoard(mine, ROWS, COLS);//雷面板
if ((_rows - 2)*(_cols - 2) - is_win == DEFAULT_MINES){
showBoard(mine, ROWS, COLS);//雷面板
printf("YOU WIN:)\n");
}
}
else{
printf("Game Over!\n");
showBoard(mine, ROWS, COLS);//雷面板
break;
}
}
}
else{
printf("Enter error,Try Again!\n");
}
time++;
}
}
void game()
{
char mine[ROWS][COLS];
char show[ROWS][COLS];
memset(mine, '0', sizeof(mine));
memset(show, '*', sizeof(show));
SetMines(mine, ROWS, COLS);
PlayGame(mine, show, ROWS, COLS);
}