首页 > 其他分享 >C语言扫雷游戏

C语言扫雷游戏

时间:2024-03-06 19:57:37浏览次数:23  
标签:map 游戏 img int C语言 格子 扫雷 loadimage SIZE

在给出的代码中,使用了以下库来实现游戏功能和图形界面:

graphics.h:这是一个基于BGI(Borland Graphics Interface)库的图形库,用于创建图形窗口、绘制图形等操作。

stdlib.h:这是C标准库中的一个头文件,提供了一些常用函数,例如srand()和rand()用于生成随机数,NULL用于表示空指针。

time.h:这是C标准库中的一个头文件,提供了时间相关的函数,例如time(NULL)用于获取当前时间的秒数。

当游戏开始时,会调用GameInit()函数进行游戏的初始化。这个函数的作用是随机布雷、计算周围雷的数量,并将地图中的每个格子初始化为特定的值。具体来说:

  • 使用srand((unsigned int)time(NULL))设置随机数种子,确保每次运行时生成的随机数不同。
  • 将地图数组map的所有元素初始化为0。
  • 通过随机数生成雷的位置,将指定数量(NUM)的雷(-1)放置在地图上。
  • 根据雷的分布情况,遍历地图数组,对于非雷区域,统计周围8个格子中雷的数量,并将该数字存储在当前格子中。
  • 最后,将地图中所有数字都加上一个偏移量(20),以便后续绘制时能够正确显示图片。

GameMap()函数用于绘制游戏地图,并根据地图中不同的值显示相应的图片:

  • 遍历地图数组,将每个格子的值打印出来,并根据格子的值选择合适的图片进行显示。具体规则如下:
    • 如果格子的值为-1,表示是雷,则显示雷的图片。
    • 如果格子的值在0到8之间,表示周围雷的数量,则显示对应数字的图片。
    • 如果格子的值在19到28之间,表示空白区域,则显示空白图片。
    • 如果格子的值大于30,表示标记区域,则显示标记图片。

OpenZero()函数用于打开周围的0格子:

  • 当玩家点击到一个值为0的格子时,程序会递归地打开周围的空白格子,直到边界或有数字的格子为止。

PlayGame()函数实现了游戏的主要逻辑:

  • 通过获取鼠标消息,判断玩家的鼠标操作。
  • 当玩家左键点击时,根据点击的位置打开格子或递归打开周围的空白格子。
  • 当玩家右键点击时,用于标记雷区或取消标记。
  • 函数返回点击的格子的值,以便后续判断游戏输赢条件。

main()函数中,程序初始化图形窗口、加载图片资源,然后进入游戏循环:

  • 不断绘制游戏地图、处理玩家操作,直到游戏结束。
  • 当游戏结束时,根据玩家胜负情况弹出相应的消息框提示。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <graphics.h>
#pragma comment(lib,"winmm.lib")

#define ROW 50	//行
#define COL 30	//列
#define NUM 100	//雷的个数
#define SIZE 20	//图片大小


//ROW*COL - NUM =count
int count = 0;	//点开的个数
int map[ROW+2][COL+2];
IMAGE img[12];	//img可以存放12张图片


void GameInit() {
	//随机数种子
	srand((unsigned int)time(NULL));

	//数组的赋初值为0
	for (int i = 0;i < ROW+2;i++) {
		for (int j = 0;j < COL+2;j++) {
			map[i][j]=0;
		}
	}
	//布雷,-1表示雷,NUM个雷
	int n=0;
	while (n < NUM) {
		//随机得到行和列
		int r = rand() % ROW+1;	//1到ROW
		int c = rand() % COL+1;	//1到COL
		if (map[r][c]==0) {
			map[r][c] = -1;
			n++;
		}	
	}
	//根据雷的分布,填充其他不为雷的数据
	for (int i = 1; i <=ROW; i++)
	{
		for (int j = 1;j <= COL;j++) {//遍历二维数组游戏区
			if (map[i][j] != -1) {//找到不为雷的元素
				//遍历九宫格
				for (int m = i - 1;m <= i + 1; m++) {
					for (int n = j - 1;n <= j + 1;n++) {
						if (map[m][n] == -1) {//找到一个雷
							map[i][j]++;
						}
					}
				}
			}
		}
	}
	for (int i = 1; i <= ROW; i++)
	{
		for (int j = 1;j <= COL;j++) {
			map[i][j] += 20;
		}
	}

}

//绘制函数,打印二维数组中所有的元素
void GameMap() {
	for (int i = 1;i <= ROW+1;i++) {
		for (int j=1;j <= COL+1;j++) {
			printf("%2d ", map[i][j]);
			if (map[i][j] == -1) {
				putimage((i - 1)*SIZE, (j - 1)*SIZE, &img[9]);

			}
			else if (map[i][j] >= 0 && map[i][j] <= 8) {
				//数字图片
				putimage((i - 1)*SIZE, (j - 1)*SIZE, &img[map[i][j]]);
			}
			else if (map[i][j] >= 19 && map[i][j] <= 28) {
				//空白图片
				putimage((i - 1)*SIZE, (j - 1)*SIZE, &img[10]);
			}
			else if (map[i][j] > 30) {
				//标记图片
				putimage((i - 1)*SIZE, (j - 1)*SIZE, &img[11]);
			}
		}
		printf("\n");
	}
}

void OpenZero(int r,int c) {
	//打开这个0
	map[r][c] -= 20;
	count++;

	//0 辅助区0
	for (int m = r - 1;m <= r + 1;m++) {				//九宫格
		for (int n = c - 1;n <= c + 1;n++) {
			if (m >= 1 && m <= ROW && n>=1 &&n <=COL) {//游戏区的内容
				if (map[m][n] >= 19 && map[m][n] <= 28) {//空白的
					if (map[m][n] != 20) {
						map[m][n] -= 20;
						count++;
					}
					else {
						OpenZero(m,n);
					}
				}
			}
		}
	}
}

int PlyaGame() {
	int r, c;

	//定义一个鼠标消息
	MOUSEMSG msg = { 0 };
	while (1) {
		msg = GetMouseMsg();
		switch (msg.uMsg) {
		case WM_LBUTTONDOWN:	//翻开扫雷空白图片
			r = msg.x / SIZE + 1;
			c = msg.y / SIZE + 1;
			if (map[r][c] >= 19 && map[r][c] <= 28) {
				if (map[r][c] == 20) {	//点到的是0
					OpenZero(r,c);
				}
				else {
					map[r][c] -= 20;
					count++;
				}
				map[r][c] -= 20;
				count++;
			}
			return map[r][c];

			break;
		case WM_RBUTTONDOWN:	//标记一个空白图片,取消一个空白图片
			r = msg.x / SIZE + 1;
			c = msg.y / SIZE + 1;
			if (map[r][c] >= 19 && map[r][c] <= 28) {
				map[r][c] += 30;

			}
			else if (map[r][c] > 30) {
				map[r][c] -= 50;
			}
			return map[r][c];
			break;
		}
	}
}




int main()
{
	//打开一个图形窗口
	HWND hwnd=initgraph(ROW*SIZE, COL*SIZE, SHOWCONSOLE);

	mciSendString(L"open 1.mp3 alias music", 0, 0, 0);
	mciSendString(L"play music", 0, 0, 0);
	//加载图片
	loadimage(&img[0], L"0.jpg", SIZE,SIZE);	//0
	loadimage(&img[1], L"1.jpg", SIZE, SIZE);
	loadimage(&img[2], L"2.jpg", SIZE, SIZE);
	loadimage(&img[3], L"3.jpg", SIZE, SIZE);
	loadimage(&img[4], L"4.jpg", SIZE, SIZE);
	loadimage(&img[5], L"5.jpg", SIZE, SIZE);
	loadimage(&img[6], L"6.jpg", SIZE, SIZE);
	loadimage(&img[7], L"7.jpg", SIZE, SIZE);
	loadimage(&img[8], L"8.jpg", SIZE, SIZE);//8
	loadimage(&img[9], L"9.jpg", SIZE, SIZE);//雷
	loadimage(&img[10], L"10.jpg", SIZE, SIZE);//空白
	loadimage(&img[11], L"11.jpg", SIZE, SIZE);//标记


	GameInit();

	while (1) {
		GameMap();
		if (PlyaGame() == -1) {
			GameMap();
			MessageBox(hwnd, L"You are a Low B!!", L"", MB_OK);
			break;
		}
		if (ROW*COL - NUM == count) {
			GameMap();
			MessageBox(hwnd, L"You are a Superman!!", L"", MB_OK);
			break;
		}
		
	}
	return 0;
}

/******************************************
	根据雷的分布填充,其他不为雷的数据
	1.遍历九宫格
	2.边上的数据遍历的时候会越界
	3.辅助区,游戏区
********************************************/

标签:map,游戏,img,int,C语言,格子,扫雷,loadimage,SIZE
From: https://www.cnblogs.com/luexiaomeng/p/18057403

相关文章

  • 2020蓝桥杯c语言省赛B组
    2020蓝桥杯省赛B组1.回文日期考点枚举+翻转完整代码#include<bits/stdc++.h>usingnamespacestd;boolrn(intt){ if((t%4==0&&t%100!=0)||t%400==0)returntrue; returnfalse;}注意:是整体翻转不是年月日变成日月年!boolf(intn,inty,intr){inth=n*10000+......
  • c语言四则运算小程序
    本文源程序代码来源于csdn一位博主:文章链接:http://t.csdnimg.cn/L29fs原程序简洁凝练,以简短的代码写出了一个加法运算器。以下是运行结果(本文全程用visualstudio2022进行代码的编写与运算):通过对该代码的运算,我个人认为有以下问题:(1)尽管该代码简洁明了,但只有加法运算,缺少减......
  • C语言常用工具函数
    整数/*atf/include/lib/utils_def.h*//**Thisvariantofdiv_round_upcanbeusedinmacrodefinitionbutshouldnot*beusedinCcodeasthe`div`parameterisevaluatedtwice.*/#defineDIV_ROUND_UP_2EVAL(n,d) (((n)+(d)-1)/(d))#definedi......
  • 基于蜘蛛纸牌游戏的二次开发
    摘要:蜘蛛纸牌是一款广为人知的单人纸牌游戏,但在实践中发现了一些存在的缺陷。本文将首先介绍蜘蛛纸牌游戏的规则,然后列举其存在的缺陷,最后提出了针对这些缺陷的二次开发解决方案,旨在提升游戏体验。引言蜘蛛纸牌游戏是一种使用两副牌(共104张扑克牌)进行的单人纸牌游戏,其目标是通......
  • 基于c语言的扫雷系统的二次开发
    原代码扫雷基本流程一、基本思路首先创建二维数组,来表示地图每一个格子要表示的信息:未翻开状态(草地)和已翻开状态(数字)该格子是地雷或者不是地雷(1表示是地雷,0表示不是地雷)使用两个二维数组来表示以上两组状态:第一组二维数组:charshowMap[9][9];表示每个格子的翻开和未翻开状......
  • 基于C语言中国象棋项目的二次开发
    这是一个由C语言所编写的中国象棋项目,以下给出原项目的链接、代码、运行截图。原项目链接:https://blog.csdn.net/weixin_45590872/article/details/109308798原C语言代码如下:点击查看代码#include<stdio.h>#include<conio.h>#include<string.h>#include<stdlib.h>#includ......
  • C语言-猜拳游戏二次开发
    引言当探究猜拳游戏的魅力时,人们往往会陶醉于其古老的历史和简单的规则之中。作为一种源远流长的竞技娱乐活动,猜拳游戏早已深入人们的生活,成为一种普遍且愉快的社交互动方式。然而,这看似简单的游戏背后却蕴含了深刻的智慧。在短暂的选择过程中,参与者不仅在思考自己的选择,更需要推......
  • 基于unity和c#的障碍跑酷游戏的二次开发
    一、设计背景近年来,虚拟现实技术取得了突飞猛进的发展,为游戏行业带来了新的机遇。通过将跑酷游戏与虚拟现实技术相结合,可以为玩家提供更加真实、沉浸式的游戏体验,让玩家仿佛置身于现实世界中的跑酷场景中。现代游戏越来越注重玩家之间的互动和竞技。跑酷游戏可以设置多人在线模......
  • 基于c++的排雷小游戏二次开发
    源代码地址https://blog.csdn.net/weixin_45906253/article/details/121237647?spm=1001.2101.3001.6650.9&utm_medium=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~Rate-9-121237647-blog-129464051.235^v43^pc_blog_bottom_relevance_base7&......
  • C语言基础-1、逻辑类型和运算
    一、逻辑类型和运算#include<stdbool.h>之后就可以使用bool和true、falseex1:#include<stdio.h>#include<stdbool.h>intmain(){ boolb=6>5; boolt=true; printf("%d\n",t); t=2; printf("%d\n",t); printf("%d\n&q......