欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

扫雷游戏

程序员文章站 2024-03-16 22:53:22
...

一.题目分析

扫雷游戏的具体实现思路:

写这一模块时应该注重梳理,应该一步步写,如:绘制界面 --> 显示界面 --> 初始化盘 --> 检测雷周围的数字 --> 打印数字(0或其他)--> 标记雷 --> 扩展功能

 

二.程序

头文件:game.h

#ifndef _GAME_H_

#define _GAME_H_

 

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

 

#define ROW 10

#define COL 10

 

void ShowaBoard (char panel[ROW][COL]);

void InitBoard (int num, char panel[ROW][COL], char panel2[ROW][COL]);

void FillNumber(char panel[][COL]);

void ShowNum(char panel[][COL], int row, int col, char panel2[][COL]);

int Find(char panel[][COL], char panel2[][COL], int row, int col, int flag);

int MoveMine(char panel[][COL], char panel2[][COL],int row,int col);

 

#endif //_GAME_H_

 


游戏的具体实现:game.c

#include "game.h"

 

 

//输出横向坐标

void PrintX() {

	int row = 0;

	printf("  ");

	for (row = 0; row < ROW; row++) 

	{

		printf("%4d", row + 1);

	}

	printf("\n");

}

 

//输出横向框

void PrintH() {

	int col = 0;

	printf("   +");

	for (col = 0; col < COL *2; col++) 

	{

		if (!((col + 1) % 2)){

			printf("+");

		}

		else {

			printf("---");

		}

	}

	printf("\n");

}

 

 

//显示盘

void ShowBoard(char panel[ROW][COL])

{

	int row = 0, col = 0;

	PrintX();

	PrintH();

	for (row = 0; row < ROW; row++) 

	{

		printf("%2d ", row + 1); //输出竖向坐标

		printf("| ");

		for (col = 0; col < COL; col++)

		{

			printf("%c ", panel[row][col]);

			printf("| ");

		}

		printf("%d\n", row +1); //输出竖向坐标

		PrintH();   //横向框

	}

	PrintX();

}

 

//初始化盘

void InitBoard(int num, char panel[ROW][COL], char panel2[ROW][COL])

{

	int i = 0;

	int row = 0;

	int col = 0;

	for (row = 0; row < ROW; row++) 

	{

		for (col = 0; col < COL; col++) 

		{

			panel[row][col] = ' ';

			panel2[row][col] = ' ';

		}

	}

	for (i = 0; i < num; i++) 

	{

		row = rand() % ROW;

		col = rand() % COL;

		if (panel[row][col] == '*') 

		{

			i--;

		}

		else 

		{

			panel[row][col] = '*';

		}

	}

}

 

//根据布置好的雷计算雷周围的数字

void FillNum(char panel[][COL]) 

{ 

	//填充数字

	int row = 0, col = 0;

	for (row = 0; row < ROW; row++) 

	{

		for (col = 0; col < COL; col++) 

		{

			int count = 0;

			//如果是雷,则不需要计算该位置周围的雷数

			if (panel[row][col] == '*')

				continue;

			if ((row - 1) >= 0 && (col - 1) >= 0)

			{

				//检测左上角是否在盘内

				if (panel[row - 1][col - 1] == '*') 

					count++;                           //检测到雷,则count加1

			}

 

			if ((row + 1) < ROW && (col - 1) >= 0)

			{

				//左下角

				if (panel[row + 1][col - 1] == '*')

					count++;

			}

 

			if ((row - 1) >= 0 && (col + 1) < COL)

			{

				//右上角

				if (panel[row - 1][col + 1] == '*')

					count++;

			}

 

			if ((row + 1) < ROW && (col + 1) < COL)

			{

				//右下角

				if (panel[row + 1][col + 1] == '*')

					count++;

			}

 

			if ((row - 1) >= 0) 

			{

				//正上方

				if (panel[row - 1][col] == '*') 

					count++;

			}

 

			if ((row + 1) < ROW)

			{

				//正下方

				if (panel[row + 1][col] == '*')

					count++;

			}

 

			if ((col - 1) >= 0)

			{

				//左边

				if (panel[row][col - 1] == '*')

					count++;

			}

 

			if ((col + 1) < COL)

			{

				//右边

				if (panel[row][col + 1] == '*')

					count++;

			}

 

			panel[row][col] = '0' + count;                     //将计算出的周围的雷数整型转换成字符型

		}

	}

}

 

 

//点到0,显示多个数字

void ShowNum(char panel[][COL], int row, int col, char panel2[][COL])

{

	panel2[row][col] = panel[row][col];        //显示数字

 

	//检测相邻点是否超出棋盘 若相邻点为0且没有雷则以该点为中心继续显示

 

	//正上方

	if ((row - 1) >= 0) 

	{

		if (panel[row - 1][col] == '0' && panel2[row - 1][col] == ' ')

			ShowNum(panel, row - 1, col, panel2);

		else 

			panel2[row - 1][col] = panel[row - 1][col];

	}

 

	//正下方

	if ((row + 1) < ROW)

	{

		if (panel[row + 1][col] == '0' && panel2[row + 1][col] == ' ')

			ShowNum(panel, row + 1, col, panel2);

		else 

			panel2[row + 1][col] = panel[row + 1][col];

	}

 

	//左边

	if ((col - 1) >= 0)

	{

		if (panel[row][col - 1] == '0' && panel2[row][col - 1] == ' ')

			ShowNum(panel, row, col - 1, panel2);

		else 

			panel2[row][col - 1] = panel[row][col - 1];

	}

 

	//右边

	if ((col + 1) < COL)

	{

		if (panel[row][col + 1] == '0' && panel2[row][col + 1])

			ShowNum(panel, row, col + 1, panel2);

		else panel2[row][col + 1] = panel[row][col + 1];

	}

 

	//左上角

	if ((row - 1) >= 0 && (col - 1) >= 0)

	{

		if (panel[row - 1][col - 1] == '0' && panel2[row - 1][col - 1] == ' ')

			ShowNum(panel, row - 1, col - 1, panel2);

		else

			panel2[row - 1][col - 1] = panel[row - 1][col - 1];

	}

	

	//左下角

	if ((row + 1) < ROW && (col - 1) >= 0)

	{	

		if (panel[row + 1][col - 1] == '0' && panel2[row + 1][col - 1] == ' ')

			ShowNum(panel, row + 1, col - 1, panel2);

		else panel2[row + 1][col - 1] = panel[row + 1][col - 1];

 

	}

 

	//右上角

	if ((row - 1) >= 0 && (col + 1) < COL)

	{

		if (panel[row - 1][col + 1] == '0' && panel2[row - 1][col + 1] == ' ')

			ShowNum(panel, row - 1, col + 1, panel2);

		else panel2[row - 1][col + 1] = panel[row - 1][col + 1];

	}	

 

	//右下角

	if ((row + 1) < ROW && (col + 1) < ROW) 

	{

		if (panel[row + 1][col + 1] == '0' && panel2[row + 1][col + 1] == ' ')

			ShowNum(panel, row + 1, col + 1, panel2);

		else

			panel2[row + 1][col + 1] = panel[row + 1][col + 1];

	}

}

 

 

//找雷

int Find(char panel[][COL],  char panel2[][COL],int row, int col, int flag) 

{

	if (flag == 1) 

	{ 

		//标记可能是雷的位置 

		//是雷返回 1 不是返回 0

		panel2[row][col] = 'F';       //如果是雷标记‘F' 

		if (panel[row][col] == '*') 

		{

			return 1;

		}

		else 

		{

			return 0;

		}

	}

	else

	{

		//猜测不是雷

		if (panel[row][col] == '*') 

		{ 

			//点到雷,游戏失败

			return 2;

		}

		else if (panel[row][col] == '0') 

		{ 

			//点击到0,显示多个数字

			ShowNum(panel, row, col, panel2);

			return 0;

		}

		else 

		{

			panel2[row][col] = panel[row][col];      //显示数字

			return 0;

		}

	}

}

 

//防止第一次踩雷

int MoveMine(char panel[][COL], char panel2[][COL], int row, int col)

{

 

	int row2 = 0;

	int col2 = 0;

	//找到没有雷的位置与输入位置交换

	for (row2 = 0; row2 < ROW; row++)

	{

		for (col2 = 0; col2 < COL; col++)

		{

			int tmp = 0;

			if (panel[row2][col2] == '*')

				continue;

			else

			{

				//将雷移走

				tmp = panel[row][col];

				panel[row][col] = panel[row2][col2];

				panel[row2][col2] = tmp;

				//更新

				FillNum(panel);

				//ShowBoard(panel);

                panel2[row][col] = panel[row][col];     

				return panel2[row][col];

			}

		}

 

	}

 

}

 

三.总结感悟

最初不能实现使第一次不会踩到雷的功能,后经借鉴代码,通过位置交换实现了此功能。

 

相关标签: 扫雷