c语言实现扫雷

实现在9乘9的格子内实现扫雷游戏,可修改格子的大小和雷的个数

思路:初始利用随机数种子生成10个雷的位置,通过输入x,y坐标来显示当前格子是否是雷,若是雷游戏结束,显示所有雷的位置,若不是雷则查找周围3乘3的方格内是否有雷,若有雷则显示当前格子周围雷的个数,若没有一个雷则显示为空格,并递归查看周围3乘3的格子。

游戏效果如下:

 

 

具体代码如下:

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1

#include <iostream>
#include<math.h>
#include<stdio.h>
#include<time.h>

#define rows 11
#define cols 11
#define row (rows-2)
#define col (cols-2)
#define size 10//雷的个数

typedef struct board
{
	char show;//展示
	int mine;//记录雷
	int visit;//记录访问次数
}board;


void game();//玩游戏

void print_board();//初始化棋盘

void put_mine();//放地雷

int illegal(int x, int y);//判断是否有雷

void initial_per_board(int x,int y);//初始雷

int print_mine(int x, int y);//改变周围,输出当前显示出来的个数

void print_board1();//游戏结束时打印的,显示雷的位置

 

#include"game.h"

board array[rows][cols];

void initial()
{
	//初始化

	for (int i = 0; i < rows; i++)
	{

		for (int j = 0; j < cols; j++)
		{
			array[i][j].visit = 0;
			array[i][j].mine = 0;
			array[i][j].show = '*';

		}


	}

	//周围一圈赋值1
	for (int i = 0; i < cols; i++)
	{
		array[0][i].visit = 1;
		array[cols- 1][i].visit = 1;
	}

	for (int j = 0; j < rows; j++)
	{
		array[j][0].visit = 1;
		array[j][rows - 1].visit = 1;
	}


}

void print_board()
{
	//打印棋盘
	for (int i = 0; i <= row; i++)
	{
		if (i == 0)
		{
			printf("   ");
			continue;
	    }
		printf("%d ", i);
	}
	printf("\n");
	for (int i = 0; i <= row; i++)
	{
		if (i == 0)
		{
			printf("   ");
			continue;
		}

		printf("--");
	}
	printf("\n");
	for (int i = 1; i <= row; i++)//只打印1-9
	{    
		printf("%d| ", i);
		for (int j = 1; j <=col; j++)
		{
			printf("%c ", array[i][j].show);

		}
		printf("|\n");

	}

	for (int i = 0; i <= row; i++)
	{
		if (i == 0)
		{
			printf("   ");
			continue;
		}

		printf("--");
	}

	printf("\n");

}


int illegal(int x, int y)
{
	if (array[x][y].mine == -1)
		return 0;
	else
		return 1;



}


void initial_per_board(int x, int y)
{  
	//有雷的地方为-1,显示#
	array[x][y].mine = -1;
	//array[x][y].show = '#';

}



void put_mine()
{
   //放size个地雷

	int count = size;
	while (count > 0)
	{
		int x = 0;
		int y = 0;
		x = rand() % row + 1;//产生1-9的数字
		y = rand() % col + 1;

		if (illegal(x, y)==0)//判断是否已经放地雷,0代表已经放
		{
			continue;

		}

		//初始化有雷的位置
		initial_per_board(x, y);

		count--;

	}



}



int print_mine(int x, int y)
{   
	//判断当前是否以更改
	if (array[x][y].visit == 1||(array[x][y].mine == -1))
		return 0;

	array[x][y].visit = 1;

    
	for (int i = x - 1; i <= x + 1; i++)
	{

		for (int j = y - 1; j <= y + 1; j++)
		{
			if (j == y && x == i)
				continue;

			if (array[i][j].mine == -1)
				array[x][y].mine++;

		}

	}


	if (array[x][y].mine == 0)
	{
		array[x][y].show = ' ';
		//不是数字,周围扩散

		return 1 + print_mine(x - 1, y - 1) + print_mine(x - 1, y) + print_mine(x - 1, y + 1) + print_mine(x, y - 1) + print_mine(x, y + 1) + print_mine(x + 1, y - 1) + print_mine(x + 1, y) + print_mine(x + 1, y + 1);

	}
	else
	{   
		//是数字,不再扩散
		array[x][y].show = "0123456789"[array[x][y].mine];
		return 1;
	}





}

void print_board1()
{
	//打印棋盘
	for (int i = 0; i <= row; i++)
	{
		if (i == 0)
		{
			printf("   ");
			continue;
		}
		printf("%d ", i);
	}
	printf("\n");
	for (int i = 0; i <= row; i++)
	{
		if (i == 0)
		{
			printf("   ");
			continue;
		}

		printf("--");
	}
	printf("\n");
	for (int i = 1; i <= row; i++)//只打印1-9
	{
		printf("%d| ", i);
		for (int j = 1; j <= col; j++)
		{   
			if (array[i][j].mine == -1)
			{
				array[i][j].show = '#';
			}
			printf("%c ", array[i][j].show);

		}
		printf("|\n");

	}

	for (int i = 0; i <= row; i++)
	{
		if (i == 0)
		{
			printf("   ");
			continue;
		}

		printf("--");
	}

	printf("\n");

}





void game()
{
	//初始化棋盘
	initial();


	//放地雷
	put_mine();



	//打印棋盘
	print_board();

	//开始输入
	int count = row * col;

	while (count > size)
	{
		puts("请输入坐标");

		int x = 0;
		int y = 0;

		scanf("%d %d", &x, &y);
		system("cls");

		while (x > row || x<1 || y>col || y < 1)
		{   
			
			print_board();
			puts("输入非法,重新输入");
		
			scanf("%d %d", &x, &y);
			system("cls");

		}

		if (array[x][y].mine == -1)
		{   //遇到雷,游戏结束
		
			break;
		}
		else
		{   //将那一片都变化
			int count1=print_mine(x, y);//输出当前已经显示出来的个数
			print_board();
			count -= count1;

		}



	}
	system("cls");
	print_board1();


	if (count <= size)
	{
		printf("恭喜你赢了\n");
	}
	else
	{
	   puts("很遗憾被炸死了");
	}


	system("pause");

}
#include"game.h"

int main()
{
    //完成扫雷游戏代码。
    srand((unsigned)time(NULL));

    int choose = 0;
    do
    {
        system("cls");
        //玩游戏
         game();
       // printf("play\n");
        //结束
        puts("是否重新游玩?");
        puts("是->1     否->2");

        printf("请输入你的选择>");
        scanf("%d", &choose);

        while (choose != 1 && choose != 2)
        {
            puts("输入非法,重新输入");
            scanf("%d", &choose);
        }

        
    } while (choose != 2);

     printf("欢迎下次游玩");

    return 0;

}

缺点:未实现标雷的小旗子,图形界面不够整洁美观,代码冗余程度高,如两个打印棋盘的代码高度重合。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值