栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

扫雷游戏的实现

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

扫雷游戏的实现

目录
  1. 文章目录
  2. 前言
  3. 一、函数库的引用
  4. 二、函数及其功能介绍
  5. 三、全部代码
  6. 总结


前言

本文章主要介绍扫雷游戏的代码实现,能实现大部分功能。


一、函数库的引用
#include 
#include 
#include 
二、函数及其功能介绍

1.meau() // 菜单

void meau()
{
	printf("***************************n");
	printf("***************************n");
	printf("********* 1.play **********n");
	printf("********* 0.exit **********n");
	printf("***************************n");
	printf("***************************n");
}

 2.Initboard() // 初始化棋盘

void Initboard(char board[ROWS][COLS], int rows, int cols, char ch)
{
	for (int i = 0; i < rows; i++) {
		for (int j = 0; j < cols; j++) {
			board[i][j] = ch;
		}
	}
}

 其中,代码中有两个棋盘,一个用于看雷的位置,一个用于给玩家看

第一个全部初始化为0,有雷的位置设为1,第二个全部设为*。

3.Displayboard() // 打印棋盘

void Displayboard(char board[ROWS][COLS], int row, int col)
{
	printf("-------------------n");
	for (int k = 0; k <= col; k++) {
		printf("%d ", k);
	}
	printf("n");
	for (int i = 1; i <= row; i++) {
		printf("%d ", i);
		for (int j = 1; j <= col; j++) {
			printf("%c ", board[i][j]);
		}
		printf("n");
	}
	printf("-------------------n");
}

4. Setboard() // 随机设雷

void Setboard(char board[ROWS][COLS], int row, int col)
{
	int x,y;
	int count = 0;

	while (count < COUNT) {
		x = rand() % row + 1;
		y = rand() % col + 1;
		if (board[x][y] == '0') {
			board[x][y] = '1';
			count++;
		}
	}

}

 5.get_mine_count() // 计算落子位置周围雷的个数

int get_mine_count(char board[ROWS][COLS], int x, int y)
{
	return board[x - 1][y - 1] + board[x][y - 1] + board[x + 1][y - 1] + board[x + 1][y] + board[x + 1][y + 1] + board[x][y + 1] + board[x - 1][y + 1] + board[x - 1][y] - 8 * '0';
}

 6.Fun() // 计算周围棋子的周围雷的个数,直到周围存在雷

void Fun(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y)
{
	int count;
	if (x >= 1 && x <= row && y >= 1 && y <= col) {
		if (show[x][y] != '*' && show[x][y] != '#') {
			return;
		}
		else if (mine[x - 1][y - 1] == '1' || mine[x][y - 1] == '1' || mine[x + 1][y - 1] == '1' || mine[x + 1][y] == '1' || mine[x + 1][y + 1] == '1' || mine[x][y + 1] == '1' || mine[x - 1][y + 1] == '1' || mine[x - 1][y] == '1') {
			count = get_mine_count(mine, x, y);
			show[x][y] = count + '0';
			return;
		}
		else
		{
			show[x][y] = '0';
			Fun(mine, show, ROW, COL, x - 1, y - 1);
			Fun(mine, show, ROW, COL, x, y - 1);
			Fun(mine, show, ROW, COL, x + 1, y - 1);
			Fun(mine, show, ROW, COL, x + 1, y);
			Fun(mine, show, ROW, COL, x + 1, y + 1);
			Fun(mine, show, ROW, COL, x, y + 1);
			Fun(mine, show, ROW, COL, x - 1, y + 1);
			Fun(mine, show, ROW, COL, x - 1, y);
		}
	}
	
}

 7.PlayerMove() // 玩家移动的逻辑实现以及标记功能

void PlayerMove(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x, y,win=0,a,b;
	char ch;
	Displayboard(show, ROW, COL);
	while (win < row*col-COUNT) {
		while (1) {
			printf("请输入你要下的位置:");
			scanf("%d %d", &x, &y);
			if (x >= 1 && x <= row && y >= 1 && y <= col) {
				break;
			}
			else {
				printf("你输入的坐标不规范,请重新输入!n");
			}
		}

		//判断游戏进行情况
		if (mine[x][y] == '1') {
			printf("你被炸死了,哈哈!n");
			Displayboard(mine, ROW, COL);
			break;
		}
		else {
			if (show[x][y] == '*' || show[x][y] == '#') {
				Fun(mine, show, ROW, COL, x, y);
				Displayboard(show, ROW, COL);

				//标记功能
				getchar();//吸取空格
				while (1) {
					printf("请选择是否进行标记(y/n):");
					scanf("%c", &ch);
					if (ch == 'y') {
						printf("请选择标记的位置:");
						scanf("%d %d", &a, &b);
						show[a][b] = '#';
						Displayboard(show, ROW, COL);
						break;
					}
					else if (ch == 'n') {
						break;
					}
					else {
						printf("选择有误,请重新进行选择!n");
					}
				}
			}
			else if(show[x][y] != '*' && show[x][y] != '#') {
				printf("这个位置已经下过了/这个位置已经知道了n");
			}

		}
	}
	if (win == row * col - COUNT)
		printf("恭喜你,赢了!n");
}

 8.game() // 游戏的整体逻辑

void game()
{
	//后台
	char mine[ROWS][COLS] = { 0 };
	//展示
	char show[ROWS][COLS] = { 0 };

	Initboard(mine, ROWS, COLS, '0');
	Initboard(show, ROWS, COLS, '*');

	Setboard(mine, ROW, COL);
	//Displayboard(mine, ROW, COL);
	PlayerMove(mine, show, ROW, COL);
}
 三、全部代码

game.h

#pragma once
#include 
#include 
#include 
#define ROW 9
#define COL 9
//ROWS COLS 在原有的基础上加2,将棋盘周围的空间初始化,防止出界判断
#define ROWS ROW+2
#define COLS COL+2
#define COUNT 20

void meau();
void game();

 game.c

#define _CRT_SECURE_NO_WARNINGS
#include "game.h"

//菜单
void meau()
{
	printf("***************************n");
	printf("***************************n");
	printf("********* 1.play **********n");
	printf("********* 0.exit **********n");
	printf("***************************n");
	printf("***************************n");
}

//初始化棋盘
void Initboard(char board[ROWS][COLS], int rows, int cols, char ch)
{
	for (int i = 0; i < rows; i++) {
		for (int j = 0; j < cols; j++) {
			board[i][j] = ch;
		}
	}
}

//打印棋盘
void Displayboard(char board[ROWS][COLS], int row, int col)
{
	printf("-------------------n");
	for (int k = 0; k <= col; k++) {
		printf("%d ", k);
	}
	printf("n");
	for (int i = 1; i <= row; i++) {
		printf("%d ", i);
		for (int j = 1; j <= col; j++) {
			printf("%c ", board[i][j]);
		}
		printf("n");
	}
	printf("-------------------n");
}

//随机设雷
void Setboard(char board[ROWS][COLS], int row, int col)
{
	int x,y;
	int count = 0;

	while (count < COUNT) {
		x = rand() % row + 1;
		y = rand() % col + 1;
		if (board[x][y] == '0') {
			board[x][y] = '1';
			count++;
		}
	}

}

//这是判断落子位置周围雷的个数
int get_mine_count(char board[ROWS][COLS], int x, int y)
{
	return board[x - 1][y - 1] + board[x][y - 1] + board[x + 1][y - 1] + board[x + 1][y] + board[x + 1][y + 1] + board[x][y + 1] + board[x - 1][y + 1] + board[x - 1][y] - 8 * '0';
}

//判断玩家落子的位置的周围位置的情况
//主要借助递归来实现判断
void Fun(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y)
{
	int count;
	if (x >= 1 && x <= row && y >= 1 && y <= col) {
		if (show[x][y] != '*' && show[x][y] != '#') {
			return;
		}
		else if (mine[x - 1][y - 1] == '1' || mine[x][y - 1] == '1' || mine[x + 1][y - 1] == '1' || mine[x + 1][y] == '1' || mine[x + 1][y + 1] == '1' || mine[x][y + 1] == '1' || mine[x - 1][y + 1] == '1' || mine[x - 1][y] == '1') {
			count = get_mine_count(mine, x, y);
			show[x][y] = count + '0';
			return;
		}
		else
		{
			show[x][y] = '0';
			Fun(mine, show, ROW, COL, x - 1, y - 1);
			Fun(mine, show, ROW, COL, x, y - 1);
			Fun(mine, show, ROW, COL, x + 1, y - 1);
			Fun(mine, show, ROW, COL, x + 1, y);
			Fun(mine, show, ROW, COL, x + 1, y + 1);
			Fun(mine, show, ROW, COL, x, y + 1);
			Fun(mine, show, ROW, COL, x - 1, y + 1);
			Fun(mine, show, ROW, COL, x - 1, y);
		}
	}
	
}

//玩家移动
void PlayerMove(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x, y,win=0,a,b;
	char ch;
	Displayboard(show, ROW, COL);
	while (win < row*col-COUNT) {
		while (1) {
			printf("请输入你要下的位置:");
			scanf("%d %d", &x, &y);
			if (x >= 1 && x <= row && y >= 1 && y <= col) {
				break;
			}
			else {
				printf("你输入的坐标不规范,请重新输入!n");
			}
		}

		//判断游戏进行情况
		if (mine[x][y] == '1') {
			printf("你被炸死了,哈哈!n");
			Displayboard(mine, ROW, COL);
			break;
		}
		else {
			if (show[x][y] == '*' || show[x][y] == '#') {
				Fun(mine, show, ROW, COL, x, y);
				Displayboard(show, ROW, COL);

				//标记功能
				getchar();//吸取空格
				while (1) {
					printf("请选择是否进行标记(y/n):");
					scanf("%c", &ch);
					if (ch == 'y') {
						printf("请选择标记的位置:");
						scanf("%d %d", &a, &b);
						show[a][b] = '#';
						Displayboard(show, ROW, COL);
						break;
					}
					else if (ch == 'n') {
						break;
					}
					else {
						printf("选择有误,请重新进行选择!n");
					}
				}
			}
			else if(show[x][y] != '*' && show[x][y] != '#') {
				printf("这个位置已经下过了/这个位置已经知道了n");
			}

		}
	}
	if (win == row * col - COUNT)
		printf("恭喜你,赢了!n");
}

//游戏的整体逻辑
void game()
{
	//后台
	char mine[ROWS][COLS] = { 0 };
	//展示
	char show[ROWS][COLS] = { 0 };

	Initboard(mine, ROWS, COLS, '0');
	Initboard(show, ROWS, COLS, '*');

	Setboard(mine, ROW, COL);
	//Displayboard(mine, ROW, COL);
	PlayerMove(mine, show, ROW, COL);
}

 test.c

#define _CRT_SECURE_NO_WARNINGS
#include "game.h"

int main()
{
    int input;
    do {
        meau();
        printf("请输入:");
        scanf("%d", &input);
        switch (input)
        {
        case 0:
            break;
        case 1:
            game();
            break;
        default:
            printf("输入错误,请重新输入。n");
        }
    } while (input);
    return 0;
}


总结

整体来说比较简单,相对较难的主要是实现算出落子位置周围棋子及棋周围棋子的周围棋子的周围雷的个数,这个可以采用递归的方法来实现,递归结束的条件是周围存在雷。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1026622.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号