C语言实现带图形化的扫雷游戏(自制)

1.先看效果图:

这些图片的素材都是自制的,如果感觉图片不适可以自己替换。雷的数量我设置是25个,在头文件中可以自行设置。在这之前要在编译器中加一个图形库easyx.h,这个可以在网上下载,不然其中的函数就会报错。由于本人英语水平有限,有些函数定义存在拼音拼写,请多多担待。

2.全部代码如下:

main.cpp

//#define _CRT_SECURE_NO_WARNINGS 1

#include"game.h"


/*int count_mine(int x, int y);
void avoid_mine();
void open_mine(int x, int y);
int sweep_mine();
int count_show_mine();*/
int main(){

	/*int n;
	printf("输入1开始游戏,输入0结束游戏\n");
	scanf("%d", &n);
	*/
	initgraph(300, 500);
	int n;
	MOUSEMSG m;
	IMAGE bk;
	loadimage(&bk, "扫雷素材自制\\bk.png", 300, 500, true);
	Lbutton play = creat_Btn(50, 250, 90, 25, "开始");
	Lbutton over = creat_Btn(160, 250, 90, 25, "退出");
	while (1){
		m = GetMouseMsg();
		BeginBatchDraw();
		putimage(0, 0, &bk);
		
		draw_button(play);
		draw_button(over);
		EndBatchDraw();
		if (inButton(play, m) && m.uMsg == WM_LBUTTONDOWN)
		{
			free(play);
			free(over);
			closegraph();
			n = 1;
			break;

		}
		else if(inButton(over,m)&&m.uMsg==WM_LBUTTONDOWN){
			free(play);
			free(over);
			closegraph();
			n = 0;
			break;
		}
	}
	switch (n){
	case 0:
		return 0;
		break;
	case 1:

		if (Game()){
			//	printf_s("踩到雷了\n");

			closegraph();
		}
		else {
			//printf_s("通关游戏\n");

			closegraph();
		}
		
			break;
			}

		
	
	return 0;
}

game.cpp

#include"game.h"

char show_mine[row][col];//玩家的地图
char real_mine[row][col];//后台(真正的)地图
IMAGE one, two, three, four, five, six, seven, eight, mine, bk, yes,no, zero;
HWND win1;
int ii[mn+1], jj[mn+1];  //存放雷的位置
int Game(){
	win1 = initgraph(win_w, win_h);
	srand((unsigned int)time(NULL));
	init_mine();
	set_mine();
	init_tu();

	//print_player();
	//print_mine();
	int nm = mn;

	avoid_mine();
	if (sweep_mine())
	{

		while (nm>=0){
			put_tu();
			if (nm > 0){
				show_mine[ii[nm]][jj[nm]] = '#';
				Sleep(100);
			}
			nm--;

		}
		/*mciSendString("open 奥利给.mp3", 0, 0, 0);
		mciSendString("play  奥利给.mp3", 0, 0, 0);*/
		mciSendString("open 神话.mp3", 0, 0, 0);
		mciSendString("play 神话.mp3", 0, 0, 0);
		MessageBox(win1, "踩雷了", "game over", MB_OK);
		mciSendString("close  神话.mp3", 0, 0, 0);
		//mciSendString("close 奥利给.mp3", 0, 0, 0);
		return 1;

	}
	else{
		while (nm>=0){
			put_tu();
			if (nm >= 0){
				show_mine[ii[nm]][jj[nm]] = '#';
				Sleep(100);
			}
			nm--;
		}
		/*mciSendString("open 牛逼.mp3", 0, 0, 0);
		mciSendString("play  牛逼.mp3", 0, 0, 0);*/
		MessageBox(win1, "赢了", "win", MB_OK);
		//mciSendString("close 牛逼.mp3", 0, 0, 0);
		return 0;

	}
}
Lbutton creat_Btn(int x, int y, int w, int h,const char *str){
	Lbutton btn = (Lbutton)malloc(sizeof(Button));
	assert(btn);
	btn->x = x;
	btn->y = y;
	btn->width=w;
	btn->height=h;
	btn->color = RGB(100, 100, 100);
	int length = strlen(str) + 1;
	btn->text = (char*)malloc(sizeof(char)+length);
	assert(btn->text);
	strcpy_s(btn->text, length, str);
	return btn;



}
void draw_button(Lbutton btn){  //画按钮
	setfillcolor(btn->color);
	fillrectangle(btn->x, btn->y, btn->x+btn->width,btn->y+ btn->height);
	settextcolor(RED);
	setbkmode(TRANSPARENT);
	settextstyle(25, 0, "楷体");
	int textw = textwidth(btn->text);
	int  texth = textheight(btn->text);
	int xx = btn->x + (btn->width - textw) / 2;
	int yy = btn->y + (btn->height - texth) / 2;
	outtextxy(xx, yy,btn->text);
	outtextxy(125, 200, "扫雷");
}
int inButton(Lbutton btn,MOUSEMSG m){
	if (m.x > btn->x&&m.y > btn->y&&m.x < btn->x + btn->width&&m.y < btn->y + btn->height)
	{
		btn->color = RGB(100, 50, 50);
		return 1;
	}
	btn->color = RGB(100, 100, 100);
	return 0;


}
void init_mine(){   //初始化
	int i, j;
	for (i = 1; i < row - 1; i++)
	for (j = 1; j < col - 1; j++){
		show_mine[i][j] = '*';
		real_mine[i][j] = '0';
	}

}
void init_tu(){


	loadimage(&one, "扫雷素材自制\\1.png", tu_w, tu_h, true);
	loadimage(&two, "扫雷素材自制\\2.png", tu_w, tu_h, true);
	loadimage(&three, "扫雷素材自制\\3.png", tu_w, tu_h, true);
	loadimage(&four, "扫雷素材自制\\4.png", tu_w, tu_h, true);
	loadimage(&five, "扫雷素材自制\\5.png", tu_w, tu_h, true);
	loadimage(&six, "扫雷素材自制\\6.png", tu_w, tu_h, true);
	loadimage(&seven, "扫雷素材自制\\7.png", tu_w, tu_h, true);
	loadimage(&eight, "扫雷素材自制\\8.png", tu_w, tu_h, true);
	loadimage(&mine, "扫雷素材自制\\雷.png", tu_w, tu_h, true);
	loadimage(&bk, "扫雷素材自制\\背景.png", tu_w, tu_h, true);
	loadimage(&yes, "扫雷素材自制\\yes.png", tu_w, tu_h, true);
	loadimage(&zero, "扫雷素材自制\\0.png", tu_w, tu_h, true);
	loadimage(&no, "扫雷素材自制\\no.png", tu_w, tu_h, true);

}
void put_tu(){

	int i, j;
	for (i = 1; i < row - 1; i++)
	  for (j = 1; j < col - 1; j++){
	
		if (show_mine[i][j] == '*'){

			putimage((j- 1)*tu_w, (i - 1)*tu_h, &bk);
		}
		else if (show_mine[i][j] == '1'){
			putimage((j - 1)*tu_w, (i - 1)*tu_h, &one);
		}
		else if (show_mine[i][j] == '2'){
			putimage((j - 1)*tu_w, (i - 1)*tu_h, &two);
		}
		else if (show_mine[i][j] == '3'){
			putimage((j - 1)*tu_w, (i- 1)*tu_h, &three);
		}
		else if (show_mine[i][j] == '4'){
			putimage((j - 1)*tu_w, (i - 1)*tu_h, &four);
		}
		else if (show_mine[i][j] == '5'){
			putimage((j - 1)*tu_w, (i - 1)*tu_h, &five);
		}
		else if (show_mine[i][j] == '6'){
			putimage((j - 1)*tu_w, (i - 1)*tu_h, &six);
		}
		else if (show_mine[i][j] == '7'){
			putimage((j - 1)*tu_w, (i - 1)*tu_h, &seven);
		}
		else if (show_mine[i][j] == '8'){
			putimage((j - 1)*tu_w, (i - 1)*tu_h, &eight);
		}
		else if (show_mine[i][j] == '#'){
			putimage((j - 1)*tu_w, (i- 1)*tu_h, &mine);
		}
		else if (show_mine[i][j] == '0'){
			putimage((j - 1)*tu_w, (i - 1)*tu_h, &zero);
		}
		else if (show_mine[i][j] == '!')
			putimage((j - 1)*tu_w, (i - 1)*tu_h, &yes);
		else if (show_mine[i][j] == '@')
			putimage((j - 1)*tu_w, (i - 1)*tu_h, &no);
	}

}
/*void print_player(){  //打印玩家地图
int i, j;
printf("0  ");

for (i = 1; i < col - 1; i++)
printf("%d  ", i);
printf("\n");
for (i = 1; i < row - 1; i++){
if (i<10)
printf("%d  ", i);
else  printf("%d ", i);

for (j = 1; j < col - 1; j++){

printf("%c  ", show_mine[i][j]);
}


printf("\n");
}
printf("\n");
printf("\n");

}
void print_mine(){   //打印后台数据
int i, j;
printf("0  ");

for (i = 1; i < col - 1; i++)
printf("%d  ", i);
printf("\n");
for (i = 1; i < row - 1; i++){
if (i < 10)
printf("%d  ", i);
else  printf("%d ", i);

for (j = 1; j < col - 1; j++){

printf("%c  ", real_mine[i][j]);
}


printf("\n");
}
printf("\n");
printf("\n");
}*/
void set_mine()  //布雷
{  
	int i, j;
	int n = 0;
	int count = mn;
	while (count){
		i = rand() % (row - 2) + 1;
		j = rand() % (col - 2) + 1;
		if (real_mine[i][j] == '0'){
			ii[n] = i;
			jj[n] = j;
			n++;
			real_mine[i][j] = '1';
		}
		count--;

	}
}
int count_mine(int x, int y){  //计算八个方向的雷数
	int count = 0;
	int i = x, j = y;
	if (real_mine[i - 1][j] == '1')//上
		count++;
	if (real_mine[i + 1][j] == '1')//下
		count++;
	if (real_mine[i][j - 1] == '1')//左
		count++;
	if (real_mine[i][j + 1] == '1')//右
		count++;
	if (real_mine[i - 1][j - 1] == '1')//左上
		count++;
	if (real_mine[i - 1][j + 1] == '1')//右上
		count++;
	if (real_mine[i + 1][j - 1] == '1')//左下
		count++;
	if (real_mine[i + 1][j + 1] == '1')//右下
		count++;
	return count;
}
void avoid_mine(){
	int i, j;
		
	MOUSEMSG m;
	
	/*printf_s("请输入:");
	scanf_s("%d,%d", &j, &i);
	printf_s("\n");*/
	while (1){
		put_tu();
		m = GetMouseMsg();
		i= m.y / tu_w + 1;
		j= m.x / tu_h + 1;
		if (  m.uMsg == WM_LBUTTONDOWN){


			if (real_mine[i][j] == '1'){

				real_mine[i][j] = '0';
				show_mine[i][j] = '0' + count_mine(i, j);
				open_mine(i, j);
				while (1){
					int xx = rand() % (row - 2) + 1;
					int yy = rand() % (col - 2) + 1;
					if (real_mine[xx][yy] == '0')
					{
						real_mine[xx][yy] = '1';
						
						return;
					}
				}
				
			}
			else{
				show_mine[i][j] = '0' + count_mine(i, j);
				open_mine(i, j);
				return;
			}
		}

		//print_player();
		//print_mine();
	}
}
void open_mine(int x, int y){   //打开无雷的区域
	int i = x, j = y;
	if (real_mine[i - 1][j] == '0'){//上
		show_mine[i - 1][j] = '0'+count_mine(i-1,j);

}
	if (real_mine[i + 1][j] == '0'){//下
		show_mine[i + 1][j] = '0' + count_mine(i + 1, j);
	}
	if (real_mine[i][j - 1] == '0'){//左
		show_mine[i][j - 1] = '0' + count_mine(i , j-1);
	}
	if (real_mine[i][j + 1] == '0'){//右
		show_mine[i][j + 1] = '0' + count_mine(i , j+1);
	}
	if (real_mine[i - 1][j - 1] == '0'){//左上
		show_mine[i - 1][j - 1] = '0';
	}
	if (real_mine[i - 1][j + 1] == '0'){//右上
		show_mine[i - 1][j + 1] = '0';
	}
	if (real_mine[i + 1][j - 1] == '0'){//左下
		show_mine[i + 1][j - 1] = '0';
	}
	if (real_mine[i + 1][j + 1] == '0'){//右下
		show_mine[i + 1][j + 1] = '0';
	}

}
int sweep_mine(){//扫雷
	int i, j;

	MOUSEMSG m;
	while (1){
		put_tu();
		
		/*printf_s("请输入:");
		scanf_s("%d,%d", &i, &j);
		printf_s("\n");*/
		
		m = GetMouseMsg();
		
		i= m.y / tu_w + 1;
		j = m.x / tu_h + 1;

		if (show_mine[i][j] == '*'&&m.uMsg==WM_RBUTTONDOWN )

			show_mine[i][j] = '!';
		
		else	if (show_mine[i][j] == '!'&&m.uMsg == WM_RBUTTONDOWN)
			
				show_mine[i][j] = '@';
		else if (show_mine[i][j] == '@'&&m.uMsg == WM_RBUTTONDOWN)
			show_mine[i][j] = '*';

		if (show_mine[i][j] == '*' && m.uMsg == WM_LBUTTONDOWN){

			if (real_mine[i][j] == '0'){
				show_mine[i][j] = '0' + count_mine(i, j);//显示此位置四周的雷数
				open_mine(i, j);   //打开四周的无雷区域
				if (count_show_mine() == 1)
					return 0;

			}
			else if (real_mine[i][j] == '1')
			{
				show_mine[i][j] = '#';
				return 1;
			}
		}
		
		FlushMouseMsgBuffer();

	}

	/*print_player();
	print_mine();*/
}

int count_show_mine(){
	int i, j;
	int count = 0;
	for (i = 1; i < row - 1; i++)
	for (j = 1; j < col - 1; j++){
		if (show_mine[i][j] == '*')
			count++;
	}
	if (count == mn)  //如果位置区域的数量等于雷数量  返回1
		return 1;
	return 0;
}

game.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#include<assert.h>
#include<conio.h>
#include<graphics.h>
#include<Windows.h>
#include<mmsystem.h>
#pragma comment(lib,"winmm.lib")
#define win_w 800
#define win_h 600
#define  row 17
#define  col 22
#define tu_w 40
#define tu_h 40
#define mn 25//雷的个数
typedef struct button{   //创建存放按钮的信息
	int x;
	int y;
	int width;
	int height;
	COLORREF color;
	char* text;

}Button, *Lbutton;
void init_mine();
//void print_player();
//void print_mine();
void set_mine();
int count_mine(int x, int y);
void avoid_mine();
void open_mine(int x, int y);
int sweep_mine();
int count_show_mine();
void init_tu();//加载图片
void  put_tu();//打印地图
int Game();//开始游戏
Lbutton creat_Btn(int x, int y, int w, int h, const char *str);//创建按钮
void draw_button(Lbutton btn);  //画
int inButton(Lbutton btn,MOUSEMSG m);//判断鼠标是否在对应位置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Attention__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值