#include <curses.h>
#include <time.h>
//定义行/列
#define ROWS 10
#define COLUMNS 10
//mine数组/矩阵就代表了屏幕上显示的雷区
bool mine[ROWS][COLUMNS];
//flag数组/矩阵用来记录雷区对应格子的状态,0:未标记,1:已被用户标记,2:已探索
int flag[ROWS][COLUMNS];
//初始化mine数组/矩阵,值为true的是雷,值为false的不是雷
void init_mine()
{
int i,j;
srand((unsigned)time(NULL));
for(i=0;i<ROWS;++i)
{
for(j=0;j<COLUMNS;++j)
{
int value=rand()%5;
if(value==4)
{
mine[i][j]=true;
}else{
mine[i][j]=false;
}
}
}
}
void init_flag()
{
int i,j;
for(i=0;i<ROWS;++i)
for(j=0;j<COLUMNS;++j)
flag[i][j]=0;
}
//获取当前格子周围8个格子中共有多少雷
int get_mines(const int current_row, const int current_col)
{
int offset[]={-1,0,1};
int i,j;
int count=0;
for(i=0;i<3;++i)
{
for(j=0;j<3;++j)
{
if(offset[i] || offset[j])
{
int tmp_row=current_row+offset[i];
int tmp_col=current_col+offset[j];
if(tmp_row>=0 && tmp_row<ROWS && tmp_col>=0 && tmp_col<COLUMNS)
{
count+=mine[tmp_row][tmp_col];
}
}
}
}
return count;
}
//探索指定格子,如果它周围有雷,则显示周围的雷的个数,否则在它周围8个格子中进行递归的探索
void check_mines(const int current_row, const int current_col)
{
//如果该格子已经被探索过,则不再重复探索
if(flag[current_row][current_col]==2)
{
return;
}
flag[current_row][current_col]=2;
int count=get_mines(current_row,current_col);
if(count)
{
move(current_row,current_col);
printw("%d",count);
}else {
move(current_row,current_col);
printw("%s","_");
int offset[]={-1,0,1};
int i,j;
for(i=0;i<3;++i)
{
for(j=0;j<3;++j)
{
if(offset[i] || offset[j])
{
int tmp_row=current_row+offset[i];
int tmp_col=current_col+offset[j];
if(tmp_row>=0 && tmp_row<ROWS && tmp_col>=0 && tmp_col<COLUMNS)
{
check_mines(tmp_row,tmp_col);
}
}
}
}
}
}
//检查当前格子,如果是雷则返回2,如果所有雷都已被用户标记,则返回1,否则探索格子并返回0
int scan_mines(const int current_row, const int current_col)
{
if(mine[current_row][current_col])
{
return 2;
}
int i,j;
bool is_all_scanned=true;
for(i=0;i<ROWS;++i)
{
for(j=0;j<COLUMNS;++j)
{
if(mine[i][j])
{
if(!flag[i][j])
{
is_all_scanned=false;
break;
}
}
}
}
if(is_all_scanned)
{
return 1;
}
check_mines(current_row, current_col);
return 0;
}
int main()
{
init_mine();
init_flag();
initscr();
noecho();
//向屏幕输出ROWS * COLUMNS的矩阵,用?表示未知区域,用_表示空区域,用*表示雷,用数组表示该位置周围有多少雷
int i,j;
for(i=0;i<ROWS;++i)
{
for(j=0;j<COLUMNS;++j)
{
move(i,j);
printw("%s","?");
}
}
//将光标移到矩阵的左上角
move(0,0);
refresh();
//开始与用户交互,直到没有未知区域(用?表示)或用户触雷结束。
int status=0;//0:正常游戏中,1:用户扫了所有的雷结束,2:用户触雷结束
int current_row=0;
int current_col=0;
while(!status)
{
//获取用户击键
int value=getch();
switch (value)
{
case 65:
current_row=(current_row-1)<0?0:(current_row-1);
break;
case 66:
current_row=(current_row+1)>(ROWS-1)?(ROWS-1):(current_row+1);
break;
case 67:
current_col=(current_col+1)>(COLUMNS-1)?(COLUMNS-1):(current_col+1);
break;
case 68:
current_col=(current_col-1)<0?0:(current_col-1);
break;
case 32:
if(flag[current_row][current_col]==1)
{
printw("%s","?");
flag[current_row][current_col]=0;
}else if (flag[current_row][current_col]==0){
printw("%s","F");
flag[current_row][current_col]=1;
}
break;
case 10:
status=scan_mines(current_row,current_col);
break;
}
move(current_row,current_col);
refresh();
}
if(status==2)
{
for(i=0;i<ROWS;++i)
{
for(j=0;j<COLUMNS;++j)
{
move(i,j);
printw("%s",mine[i][j]?"*":"-");
}
}
}
move(ROWS+1, COLUMNS+1);
printw("%s\n",(status==2)?"Game Over.":"You won!");
refresh();
sleep(10);
endwin();
return 0;
}
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
chapter5.tar.gz (4个子文件)
chapter5
example
mine.c 4KB
a.out 13KB
helloWorld.c 136B
a.out 9KB
共 4 条
- 1
资源评论
import_java_any
- 粉丝: 15
- 资源: 5
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功