简单扫雷小游戏
程序员文章站
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;
}
上一篇: Python中的高级数据结构详解
下一篇: 如何实现tab栏的切换效果