简单扫雷小游戏


game.h

#ifndef __GAME_H__
#define __GAME_H__

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>

#define ROW 9
#define COL 9

#define ROWS ROW+2
#define COLS COL+2

#define EASY_COUNT 10
#define MID_COUNT  30
#define HARD_COUNT 40



void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
void DisplayBoard(char board[ROWS][COLS], int row, int col);
void SetMine(char board[ROWS][COLS], int row, int col,int mine);
int GetMineCount(char board[ROWS][COLS], int x, int y);
void Expand(char board_show[ROWS][COLS],char board_mine[ROWS][COLS], int x, int y);
int Check_mine(char board[ROWS][COLS], int row, int col);
void Change_mine(char board[ROWS][COLS],int row,int col,int x,int y);
void Mark_mine(char board[ROWS][COLS],int x,int y,char ch);
#endif//__GAME_H__



/////////////////////////////////////////////////////////////
//函数实现
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)               //初始化棋盘
{
	int i=0;
	int j=0;
	for (i=0;i<rows;i++)
	{
		for (j=0;j<cols;j++)
		{
			board[i][j]=set;
		}
	}
}
void DisplayBoard(char board[ROWS][COLS], int row, int col)             //打印棋盘
{
	int i=0;
	int j=0;
	printf("  ");
	for (i=1;i<=row;i++)
	{
		printf("%d ",i);
	}
	printf("\n");
	for (i=1;i<=row;i++)
	{
		printf("%d ",i);
		for (j=1;j<=col;j++)
		{
			printf("%c ",board[i][j]);
		}
		printf("\n");
	}
	printf("\n");
}
void SetMine(char board[ROWS][COLS], int row, int col,int mine)               //设置雷
{
	int x=0;
	int y=0;
	int count=mine;

	do 
	{
		x=rand()%10;
		y=rand()%10;
		if ((board[x][y]=='0')&&(x>=1)&&(x<=row)&&(y>=1)&&(y<=col))
		{
			board[x][y]='1';
			count--;
		}

	} while (count);

}
int GetMineCount(char board[ROWS][COLS], int x, int y)                 //获取当前坐标周围的雷的数目
{ 
	int ret=0;
	ret=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]+board[x+1][y-1]-8*'0';

	return ret;
}
void Expand(char board_show[ROWS][COLS],char board_mine[ROWS][COLS], int x, int y)          //周围没有雷,就展开(感觉此处代码臭长,可以优化)
{
	board_show[x][y]=' ';
	//↑
	if ((y-1)>=1&&GetMineCount(board_mine,x,y-1))
		board_show[x][y-1]='0'+GetMineCount(board_mine,x,y-1);
	else if((y-1)>=1&&(board_show[x][y-1]=='*')&&(GetMineCount(board_mine,x,y-1)==0)&&(board_mine[x][y-1]!='1'))
		Expand(board_show,board_mine,x,y-1);
	//↖
	if ((x-1)>=1&&(y-1)>=1&&GetMineCount(board_mine,x-1,y-1))
		board_show[x-1][y-1]='0'+GetMineCount(board_mine,x-1,y-1);
	else if(x-1>=1&&x-1<=ROW&&y-1>=1&&y-1<=COL&&(board_show[x-1][y-1]=='*')&&(GetMineCount(board_mine,x-1,y-1)==0)&&(board_mine[x-1][y-1]!='1'))
		Expand(board_show,board_mine,x-1,y-1);
	//←
	if ((x-1)>=1&&GetMineCount(board_mine,x-1,y))
		board_show[x-1][y]='0'+GetMineCount(board_mine,x-1,y);
	else if(x-1>=1&&x-1<=ROW&&(board_show[x-1][y]=='*')&&(GetMineCount(board_mine,x-1,y)==0)&&(board_mine[x-1][y]!='1'))
		Expand(board_show,board_mine,x-1,y);
	//
	//↙
	if ((x-1)>=1&&(y+1)<=COL&&GetMineCount(board_mine,x-1,y+1))
		board_show[x-1][y+1]='0'+GetMineCount(board_mine,x-1,y+1);
	else if(x-1>=1&&x-1<=ROW&&y+1>=1&&y+1<=COL&&(board_show[x-1][y+1]=='*')&&(GetMineCount(board_mine,x-1,y+1)==0)&&(board_mine[x-1][y+1]!='1'))
		Expand(board_show,board_mine,x-1,y+1);	
	//↓
	if ((y+1)<=COL&&GetMineCount(board_mine,x,y+1))
		board_show[x][y+1]='0'+GetMineCount(board_mine,x,y+1);
	else if(y+1>=1&&y+1<=COL&&(board_show[x][y+1]=='*')&&(GetMineCount(board_mine,x,y+1)==0)&&(board_mine[x][y+1]!='1'))
		Expand(board_show,board_mine,x,y+1);
	//↘
	if ((x+1)<=ROW&&(y+1)<=COL&&GetMineCount(board_mine,x+1,y+1))
		board_show[x+1][y+1]='0'+GetMineCount(board_mine,x+1,y+1);
	else if(x+1>=1&&x+1<=ROW&&y+1>=1&&y+1<=COL&&(board_show[x+1][y+1]=='*')&&(GetMineCount(board_mine,x+1,y+1)==0)&&(board_mine[x+1][y+1]!='1'))
		Expand(board_show,board_mine,x+1,y+1);
	//→
	if ((x+1)<=ROW&&GetMineCount(board_mine,x+1,y))
		board_show[x+1][y]='0'+GetMineCount(board_mine,x+1,y);
	else if(x+1>=1&&x+1<=ROW&&(board_show[x+1][y]=='*')&&(GetMineCount(board_mine,x+1,y)==0)&&(board_mine[x+1][y]!='1'))
		Expand(board_show,board_mine,x+1,y);
	//↗
	if ((x+1)<=ROW&&(y-1)>=1&&GetMineCount(board_mine,x+1,y-1))
		board_show[x+1][y-1]='0'+GetMineCount(board_mine,x+1,y-1);
	else if(x+1>=1&&x+1<=ROW&&y-1>=1&&y-1<=COL&&(board_show[x+1][y-1]=='*')&&(GetMineCount(board_mine,x+1,y-1)==0)&(board_mine[x+1][y-1]!='1'))
		Expand(board_show,board_mine,x+1,y-1);
}

int Check_mine(char board[ROWS][COLS], int row, int col)             //获取当前剩余的格子数
{
	int count=0;
	int i=0;
	int j=0;
	for (i=1;i<=row;i++)
	{
		for (j=1;j<=col;j++)
		{
			if (board[i][j]=='*'||board[i][j]=='?')
				count++;
		}
	}
	return count;
}
void Change_mine(char board[ROWS][COLS],int row,int col,int x,int y)           //如果的第一次走,踩雷,就移走当前坐标的雷
{
	int x1=x;
	int y1=y;
	board[x][y]='0';

	while (1)
	{
		x=rand()%10;
		y=rand()%10;
		if (x>0&&x<=row&&y>0&&y<=col&&x!=x1&&y!=y1&&board[x][y]!='1')
		{
			board[x][y]='1';
			break;
		}
	}
}
void Mark_mine(char board[ROWS][COLS],int x,int y,char ch)                 //标记
{
	int flag=1;
	do 
	{
		printf("please chose coordinates:>");
		scanf("%d %d",&x,&y);
		if(x<1||x>ROW||y<1||y>COL)
		{
			printf("coordinates error,chose agin!\n");
			continue;
		}
		if(ch=='m') 
		{
			board[x][y]='?';
			flag=0;
		}
		else if(ch=='c')
		{
			board[x][y]='*';
			flag=0;
		}

	} while (flag);



}

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void game()
{ 
	int r=0;
	int l=0;
	int count=0;
	char ch=0;
	int degree=0;
	int flag=1;
	int leo=0;
	char show[ROWS][COLS]={0};
	char mine[ROWS][COLS]={0};
	do                           //难度选择
	{
		system("cls");
		printf("**********  选择难度 **********\n");
		printf("1.普通(10个雷)\n");
		printf("2.很简单(30个雷)\n");
		printf("3.炒鸡煎蛋(很多雷)\n");
		scanf("%d",°ree);
		if(degree==1||degree==2||degree==3)
		{
			flag=0;
			switch(degree)
			{
			case 1:
				   leo=EASY_COUNT;
				   break;
			case 2:
				   leo=MID_COUNT;
				   break;
			case 3:
					leo=HARD_COUNT;
					break;
			default:
				break;

			}
		}
	} while (flag);
	
    

	InitBoard(show,ROWS,COLS,'*');
	InitBoard(mine,ROWS,COLS,'0');
	system("cls");  //清屏
	DisplayBoard(show,ROW,COL);
    SetMine(mine,ROW,COL,leo);
	
	
    while(1)
	{
		//DisplayBoard(mine,ROW,COL);  //打印雷区,便于调试
     	count++;
		printf("(mark(m) or cancel(c) mine)please chose coordinates>:");
		scanf("%d %d",&r,&l);
		ch=getchar();                     //如果接收到了一个字符,就进行标记或取消标记
		if(r<1||r>ROW||l<1||l>COL)
		{
			printf("coordinates error,chose agin!\n");
			continue;
		}
		if (ch=='m'||ch=='c')
		  Mark_mine(show,r,l,ch);		
		if (count==1)
		{
			if (mine[r][l]=='1')               //如果第一个是雷,就把雷移走,不会被炸死
			   Change_mine(mine,ROW,COL,r,l);
		}
		else if (mine[r][l]=='1')
		{
			printf("you die!\n");
			break;
		}
		if(count)
		{
			system("cls");  //清屏
		    show[r][l]='0'+GetMineCount(mine,r,l);
		}
		if (GetMineCount(mine,r,l)==0)
		     Expand(show,mine,r,l);
        DisplayBoard(show,ROW,COL);
		if(Check_mine(show,ROW,COL)==EASY_COUNT)
		{
			printf("you win!\n");
			break;
		}
		
    }
	
}
void menu()
{
	printf("******************************\n");
	printf("***  1.play       0.exit   ***\n");
	printf("******************************\n");
}

void test()
{
	int input;
	do{
		menu();
		printf("请选择>:");
		scanf("%d",&input);
		switch(input)
		{
		case 1:
			game();break;
		case 0:
			printf("退出!\n");break;
		default:
			break;
		}
	}while(input);
}

int main()
{
	srand((unsigned int)time(NULL));
	test();
	return 0;
}

 

猜你喜欢

转载自blog.csdn.net/qq_33279168/article/details/79883238