扫雷游戏

一.题目分析

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

写这一模块时应该注重梳理,应该一步步写,如:绘制界面 --> 显示界面 --> 初始化盘 --> 检测雷周围的数字 --> 打印数字(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];

			}

		}

 

	}

 

}

 

三.总结感悟

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值