C++扫雷小游戏(附赠源代码)

本文附赠源代码,欢迎白嫖~

(一) 扫雷的c++实现方式

1.1 实现方式

扫雷,顾名思义就是在一片未知的区域寻找在其中的隐藏的地雷,每开启一个格点,如果这个点中不是雷,就能够知道其周围八个点中所蕴含的地雷总数。

当最终找到所有地雷的位置或者在这个过程中不慎踩到了地雷,游戏结束exit(0);

1.2 代码细节

1.2.1 完成时间的计算

当玩家扫雷成功时,这时需返回玩家单轮游戏的用时,实现方法:在玩家开启第一个雷时,标记t1=time(0);;在玩家扫雷成功时,标记t2=time(0);。最后,输出t2-t1就是总时间了。

1.2.2 地雷图的随机性

地雷的地图时用二维数组实现的,而玩家的每一轮游戏的地图都必须是不同的,因此,要用srand(time(NULL));以及rand()% x来实现。

1.2.3 关于游戏的合理性和流畅度

举个栗子:在10x10的扫雷地图中,若有99个雷,这时选中正确的概率非常低。为了避免这种情况,游戏的地图大小和雷的个数要由玩家自由决定,并且保证游戏的难度,地雷数目要在一定的范围内。

流畅度 -> 游戏转换的间隔(时间过渡)。Sleep(t)t为时间,以ms为单位。

1.2.3 键盘的操作与控制

游戏过程中选择格点需要用键盘来选择,并非输入。
实现方式:

  1. 头文件#include<conio.h>
  2. 调用Windows的system部分
HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO CursorInfo;
	GetConsoleCursorInfo(handle,&CursorInfo);//获取控制台光标信息     CursorInfo.bVisible = false; //隐藏控制台光标
  1. 判断char c=gecth()

1.3 注意事项

1.3.1 如何解决屏闪的问题

频闪是由system("cls")产生的,在运行时,会先清空屏幕,再输出内容,导致频闪。
解决方法:

SetConsoleCursorInfo(handle, &CursorInfo);//设置控制台光标状态

1.3.2 玩家试错的机会

为了避免玩家在第一步踩到雷,游戏结束。游戏设置会给予玩家一次复活的机会,继续游戏。

(二)游戏体验

2.1 游戏完整源代码

#include <bits/stdc++.h>
#include <windows.h>
#include <conio.h>
using namespace std;
const int p[8][2]= {{0,1},{1,0},{-1,0},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}};
char c;
char xmp[21][21];
int mp[21][21],n,m,k,t1,t2;
bool mpb[21][21],bo[21][21];
void dfs0(int x,int y) {
	mpb[x][y]=1;
	for(int i=0; i<8; i++) {
		if(x+p[i][0]<1 || x+p[i][0]>n || y+p[i][1]<1 || y+p[i][1]>m)
			continue;
		if(mp[x+p[i][0]][y+p[i][1]]==0) {
			xmp[x+p[i][0]][y+p[i][1]]='0';
			if(!mpb[x+p[i][0]][y+p[i][1]])
				dfs0(x+p[i][0],y+p[i][1]);
		}
		if(mp[x+p[i][0]][y+p[i][1]]>0)
			xmp[x+p[i][0]][y+p[i][1]]=mp[x+p[i][0]][y+p[i][1]]+'0';
	}
	return;
}
void bai(int x,int y) {
	system("cls");
	if(bo[x][y])
		return;
	bo[x][y]=1;
	system("color C");
	for(int k=1; k<=19; k++) {
		Sleep(260);
		system("cls");
		for(int i=1; i<=n; i++) {
			for(int j=1; j<=m; j++) {
				cout<<xmp[i][j]<<" ";
				if(xmp[i][j]=='*')
					xmp[i][j]='_';
			}
			cout<<endl<<endl;
		}
		int j=y+k;
		for(int i=x-k; i<=x+k; i++) {
			if(i<1 || i>n || j<1 || j>m)
				continue;
			if(mp[i][j]==-1) {
				xmp[i][j]='*';
				for(int l=0; l<8; l++)
					xmp[i+p[l][0]][j+p[l][1]]='_';
			}
		}
		j=y-k;
		for(int i=x-k; i<=x+k; i++) {
			if(i<1 || i>n || j<1 || j>m)
				continue;
			if(mp[i][j]==-1) {
				xmp[i][j]='*';
				for(int l=0; l<8; l++)
					xmp[i+p[l][0]][j+p[l][1]]='_';
			}
		}
		int i=x+k;
		for(int j=x-k; j<=x+k; j++) {
			if(i<1 || i>n || j<1 || j>m)
				continue;
			if(mp[i][j]==-1) {
				xmp[i][j]='*';
				for(int l=0; l<8; l++)
					xmp[i+p[l][0]][j+p[l][1]]='_';
			}
		}
		i=x-k;
		for(int j=x-k; j<=x+k; j++) {
			if(i<1 || i>n || j<1 || j>m)
				continue;
			if(mp[i][j]==-1) {
				xmp[i][j]='*';
				for(int l=0; l<8; l++)
					xmp[i+p[l][0]][j+p[l][1]]='_';
			}
		}
	}
	system("pause");
	system("color 7");
}
void win() {
	t2=time(0);
	for(int k=1; k<=n; k++) {
		Sleep(150);
		system("cls");
		for(int i=1; i<=m; i++) {
			if(mp[k-1][i]>0)
				xmp[k-1][i]=mp[k-1][i]+'0';
			else
				xmp[k-1][i]='*';
			xmp[k][i]=45;
		}
		for(int i=1; i<=n; i++) {
			for(int j=1; j<=m; j++)
				cout<<xmp[i][j]<<" ";
			cout<<endl<<endl;
		}
	}
	system("cls");
	cout<<"游戏成功,总共用时:"<<t2-t1<<"秒"<<endl<<endl;
	system("pause");
	system("cls");
}
void game() {
	memset(mp,0,sizeof mp);
	memset(mpb,0,sizeof mpb);
	while(1) {
		system("cls");
		cout<<"请输入长: ( >=5,<=20 )"<<endl;
		cin>>m;
		if(m<5 || m>20) {
			cout<<"您输入的数太大或太小了!重新输入"<<endl;
			Sleep(1200);
		} else
			break;
	}
	while(1) {
		system("cls");
		cout<<"请输入宽: ( >=5,<=12 )"<<endl;
		cin>>n;
		if(n<5 || n>12) {
			cout<<"您输入的数太大或太小了!重新输入"<<endl;
			Sleep(1200);
		} else
			break;
	}
	while(1) {
		system("cls");
		cout<<"请输入雷数: ( >=5,<="<<n*m-5<<" )"<<endl;
		cin>>k;
		if(k<5 || k>n*m-5) {
			cout<<"您输入的数太大或太小了!重新输入";
			Sleep(1200);
		} else
			break;
	}
	system("cls");
	for(int i=1; i<=3; i++) {
		cout<<"正在初始化.";
		Sleep(280);
		cout<<".";
		Sleep(280);
		cout<<".";
		Sleep(280);
		system("cls");
	}
	srand((unsigned)time(NULL));
	for(int i=1; i<=k; i++) {
		int x=rand()%n+1,y=rand()%m+1;
		if(mp[x][y]==-1) {
			i--;
			continue;
		} else
			mp[x][y]=-1;
	}
	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++) {
			if(mp[i][j]==-1)
				continue;
			for(int k=0; k<8; k++)
				if(mp[i+p[k][0]][j+p[k][1]]==-1)
					mp[i][j]++;
		}
	char s[21][21];
	for(int i=1; i<=20; i++)
		for(int j=1; j<=20; j++) {
			s[i][j]=' ';
			xmp[i][j]=22;
		}
	int x=1,y=1,sum=0;
	bool o=0,f=0,fir=0;
	while(1) {
		sum=0;
		system("cls");
		s[x][y]='<';
		for(int i=1; i<=n; i++) {
			for(int j=1; j<=m; j++) {
				if(xmp[i][j]==127)
					sum++;
				cout<<xmp[i][j]<<s[i][j];
			}
			cout<<endl<<endl;
		}
		cout<<"剩余雷数: "<<k-sum;
		if(o) {
			Sleep(2000);
			bai(x,y);
			system("cls");
			cout<<"游戏失败!";
			Sleep(2500);
			system("cls");
			return;
		}
		c=getch();
		switch(c) {
			case 'w': {
				s[x][y]=' ';
				if(--x<1)
					x=n;
				break;
			}
			case 's': {
				s[x][y]=' ';
				if(++x>n)
					x=1;
				break;
			}
			case 'a': {
				s[x][y]=' ';
				if(--y<1)
					y=m;
				break;
			}
			case 'd': {
				s[x][y]=' ';
				if(++y>m)
					y=1;
				break;
			}
			case 'j': {
				if(!fir) {
					t1=time(0);
					fir=1;
				}
				if(mp[x][y]==-1) {
					if(!f) {
						f=1;
						cout<<endl<<"您的rp太低,这是个雷!(仅提醒一次)";
						Sleep(2000);
					} else {
						xmp[x][y]='*';
						o=1;
					}
				}
				if(mp[x][y]==0) {
					xmp[x][y]='0';
					dfs0(x,y);
				}
				if(mp[x][y]>0)
					xmp[x][y]=mp[x][y]+'0';
				bool bo=0;
				for(int i=1; i<=n; i++) {
					for(int j=1; j<=m; j++) {
						if(mp[i][j]==-1)
							continue;
						if(xmp[i][j]!=mp[i][j]+'0')
							bo=1;
					}
				}
				if(bo)
					break;
				win();
				return;
			}
			case 'k': {
				if(xmp[x][y]==22) {
					xmp[x][y]=127;
					break;
				}
				if(xmp[x][y]==127) {
					xmp[x][y]='?';
					break;
				}
				xmp[x][y]=22;
				break;
			}
		}
	}
}
int main() {
	HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO CursorInfo;
	GetConsoleCursorInfo(handle,&CursorInfo);//获取控制台光标信息     CursorInfo.bVisible = false; //隐藏控制台光标
	SetConsoleCursorInfo(handle, &CursorInfo);//设置控制台光标状态
	cout<<"                           ----欢迎您来到扫雷----";
	Sleep(2500);
	system("cls");
	for(int i=1; i<=2; i++) {
		cout<<"加载中.";
		Sleep(300);
		cout<<".";
		Sleep(300);
		cout<<".";
		Sleep(300);
		system("cls");
	}
	string s[3]= {" "," "," "};
	int now=0;
	while(1) {
		s[now]='<';
		cout<<"自定义游戏 "<<s[0]<<endl;
		cout<<"游戏教程 "<<s[1]<<endl;
		cout<<"退出 "<<s[2]<<endl<<endl;
		cout<<"ws上下控制,j确定";
		c=getch();
		system("cls");
		switch(c) {
			case 'w': {
				s[now]=' ';
				if(--now<0)
					now=3;
				break;
			}
			case 's': {
				s[now]=' ';
				if(++now>3)
					now=0;
				break;
			}
			case 'j': {
				if(now==0)
					game();
				if(now==1) {
					system("cls");
					cout<<"wasd控制选中的单元格"<<endl;
					cout<<"j翻开单元格,k标记地雷格格"<<endl;
					cout<<"第一次翻到雷会给出一次提醒"<<endl<<endl;
					cout<<"如果您运气实在太差"<<endl;
					cout<<"翻出的是无法判断雷的图"<<endl;
					cout<<"接下来就看脸 ^_^"<<endl<<endl;
					system("pause");
					system("cls");
				}
				if (now==2)
					return 0;
				break;
			}
		}
	}
}

2.2 游戏画面

画面设计不够美观,请谅解!!

开始游戏
游戏进行中
游戏结束

2.3 游戏教程

  • wasd控制选中的单元格

  • j翻开单元格,k标记地雷格格

  • 第一次翻到雷会给出一次提醒

具体请见游戏内教程

(三)总结

这是一项智力游戏,同时考验了开发者的代码能力,看似非常简单,但实际上有很多细节需要考虑。

爆肝3天,代码白嫖,点赞请留下, T h a n k Thank Thank y o u ♪ ( ・ ω ・ ) ノ you♪(・ω・)ノ you(ω)

  • 78
    点赞
  • 111
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是简单的 Java 扫雷小游戏源代码: ``` import java.util.Random; import java.util.Scanner; public class Minesweeper { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); Random random = new Random(); int rows, columns, bombs; System.out.print("Enter number of rows: "); rows = scanner.nextInt(); System.out.print("Enter number of columns: "); columns = scanner.nextInt(); System.out.print("Enter number of bombs: "); bombs = scanner.nextInt(); boolean[][] board = new boolean[rows][columns]; int[][] counts = new int[rows][columns]; // randomly place bombs for (int i = 0; i < bombs; i++) { int row, column; do { row = random.nextInt(rows); column = random.nextInt(columns); } while (board[row][column]); board[row][column] = true; for (int dr = -1; dr <= 1; dr++) { for (int dc = -1; dc <= 1; dc++) { if (dr != 0 || dc != 0) { int r = row + dr; int c = column + dc; if (r >= 0 && r < rows && c >= 0 && c < columns) { counts[r][c]++; } } } } } boolean[][] revealed = new boolean[rows][columns]; int remaining = rows * columns - bombs; while (remaining > 0) { // print the board for (int c = 0; c < columns; c++) { System.out.print(" " + c); } System.out.println(); for (int r = 0; r < rows; r++) { System.out.print(r); for (int c = 0; c < columns; c++) { if (revealed[r][c]) { if (board[r][c]) { System.out.print("* "); } else { System.out.print(counts[r][c] + " "); } } else { System.out.print(". "); } } System.out.println(); } // ask for the next move int row, column; do { System.out.print("Enter row and column: "); row = scanner.nextInt(); column = scanner.nextInt(); } while (row < 0 || row >= rows || column < 0 || column >= columns || revealed[row][column]); revealed[row][column] = true; remaining--; // handle the move if (board[row][column]) { System.out.println("Boom! Game over."); break; } else if (counts[row][column] == 0) { // reveal all neighbors for (int dr = -1; dr <= 1; dr++) { for (int dc = -1; dc <= 1; dc++) { if (dr != 0 || dc != 0) { int r = row + dr; int c = column + dc; if (r >= 0 && r < rows && c >= 0 && c < columns && !revealed[r][c]) { revealed[r][c] = true; remaining--; } } } } } } if (remaining == 0) { System.out.println("Congratulations! You win!"); } scanner.close(); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值