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

简单扫雷小游戏

程序员文章站 2022-04-12 10:32:48
...


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;
}