扫雷
堕落了一晚上,写了个扫雷,基于curses。
刚刚开始接触工程上的程序,风格还不好,请大家多指点指点。
mine.c
#include <stdio.h>
#include <ncurses.h>
#include <time.h>
#include <string.h>
#include <time.h>
#define MINE '*'
#define COVE '#'
#define MARK 'M'
#define UNVIS 0
#define VISIT 1
#define MARKED 2
#define UNMARK 3
extern char * optarg;
int MAXM,MAXR,MAXC,mp[100][100],stat[100][100],OPEN;
int ext[8][2]={1,0,-1,0,0,1,0,-1,1,1,1,-1,-1,1,-1,-1};
void creat_map()
{
memset(mp,0,sizeof(mp));
memset(stat,UNVIS,sizeof(stat));
srand(time(0));
int r,c,m=0;
while(m<MAXM)
{
r=rand()%MAXR;
c=rand()%MAXC;
if(mp[r][c]!=MINE)
{
mp[r][c]=MINE;
m++;
}
}
for(r=0;r<MAXR;r++)
for(c=0;c<MAXC;c++)
if(mp[r][c]==0)
{
mp[r][c]+= (r-1>=0 && mp[r-1][c]==MINE);
mp[r][c]+= (r+1<MAXR && mp[r+1][c]==MINE);
mp[r][c]+= (c-1>=0 && mp[r][c-1]==MINE);
mp[r][c]+= (c+1<MAXC && mp[r][c+1]==MINE);
mp[r][c]+= (r+1<MAXR && c+1<MAXC && mp[r+1][c+1]==MINE);
mp[r][c]+= (r+1<MAXR && c-1>=0 && mp[r+1][c-1]==MINE);
mp[r][c]+= (r-1>=0 && c+1<MAXC && mp[r-1][c+1]==MINE);
mp[r][c]+= (r-1>=0 && c-1>=0 && mp[r-1][c-1]==MINE);
}
return;
}
int main_game()
{
int r,c;
for(r=0;r<MAXR;r++)
for(c=0;c<MAXC;c++)
{
move(r,c);
addch(COVE);
}
refresh();
move(0,0);
int dir;
r=c=0;
while(1)
{
dir=getch();
if(dir==KEY_UP && r>0)
r--;
else if(dir==KEY_DOWN && r<MAXR-1)
r++;
else if(dir==KEY_LEFT && c>0)
c--;
else if(dir==KEY_RIGHT && c<MAXC-1)
c++;
else if(dir=='n')
{
if(mp[r][c]==MINE)
{
clear();
move(5,5);
return 0;
//return 0 ,if failed
}
if(stat[r][c]==VISIT)
continue;
if(mp[r][c]!=0)
{
move(r,c);
printw("%d",mp[r][c]);
stat[r][c]=VISIT;
OPEN++;
if(OPEN==MAXR*MAXC-MAXM)
return 1;
refresh();
}
else
{//BFS
int nr,nc,q[10000][2],qs=0,qe=1,t;
q[qs][0]=r,q[qs][1]=c;
stat[r][c]=VISIT;
while(qs<qe)
{
if(mp[q[qs][0]][q[qs][1]]!=0)
{
qs++;
continue;
}
for(t=0;t<8;t++)
{
nr=q[qs][0]+ext[t][1];
nc=q[qs][1]+ext[t][0];
if(nr>=0 && nr<MAXR &&
nc>=0 && nc<MAXC &&
stat[nr][nc]==UNVIS)
{
q[qe][0]=nr;
q[qe][1]=nc;
stat[nr][nc]=VISIT;
qe++;
}
}
qs++;
}
for(t=0;t<qe;t++)
{
OPEN++;
move(q[t][0],q[t][1]);
if(mp[q[t][0]][q[t][1]]==0)
printw(" ");
else
printw("%d",mp[q[t][0]][q[t][1]]);
}
if(OPEN==MAXR*MAXC-MAXM)
return 1;
}
}
else if(dir=='m')
{
if(stat[r][c]==MARKED)
{
stat[r][c]=UNMARK;
move(r,c);
printw("%c",COVE);
}
else if(stat[r][c]==UNMARK || stat[r][c]==UNVIS)
{
move(r,c);
printw("%c",MARK);
stat[r][c]=MARKED;
}
}
else if(dir=='q')
return 3;
move(r,c);
refresh();
}
return 1;
}
void helpmsg()
{
printf("Usage: mine -r N -c C -m M\n");
printf(" -r N:Number of rows,30 at most\n");
printf(" -c C:Number of colums,30 at most\n");
printf(" -m M:Number of mines,1 at lest,N*C at most\n");
printf(" -h:show this help message\n");
printf("press q to quit game\n");
return ;
}
void show_mine()
{
int r,c;
for(r=0;r<MAXR;r++)
for(c=0;c<MAXC;c++)
if(mp[r][c]==MINE)
{
move(r,c);
printw("%c",MINE);
}
else if(mp[r][c]!=0)
{
move(r,c);
printw("%d",mp[r][c]);
}
else
{
move(r,c);
printw(" ");
}
move(0,0);
refresh();
sleep(2);
return;
}
void init_prog(int argc,char * argv[])
{
int t;
if(argc!=7)
{
printf("Option Error!\n");
helpmsg();
exit(1);
}
while((t=getopt(argc,argv,"r:c:m:h"))!=-1)
{
switch(t)
{
case 'r':
{
MAXR=atoi(optarg);
break;
}
case 'c':
{
MAXC=atoi(optarg);
break;
}
case 'm':
{
MAXM=atoi(optarg);
break;
}
case 'h':
{
helpmsg();
break;
}
defalt:
{
printf("Undefined Option!\n");
exit(1);
}
}
}
if(MAXR<1 || MAXR>30 || MAXC<1 ||MAXC>30 ||
MAXM<1 || MAXM>MAXR*MAXC)
{
printf("Wrong number of R or C or M!\n");
helpmsg();
exit(1);
}
OPEN=0;
return;
}
int main(int argc,char *argv[])
{
int t,r,c;
init_prog(argc,argv);
initscr();
noecho();
cbreak();
keypad(stdscr,TRUE);
creat_map();
time_t st,end;
st=time(0);
t=main_game();
end=time(0);
if(t==1)
{
clear();
move(5,5);
printw(" Congratulations!");
move(7,5);
printw("Baby,you are the winer!");
int h,m;
end-=st;
h=end/3600;
end-=h*3600;
m=end/60;
end-=m*60;
move(9,5);
printw("You spend ");
if(h)
printw("%dh",h);
if(h || m)
printw("%dm",m);
printw("%ds in total!",end);
refresh();
t=getch();
}
else if(t==0)
{
show_mine();
clear();
move(5,5);
printw(" GAME OVER!");
move(7,5);
printw("Press any key to quit");
refresh();
t=getch();
}
endwin();
exit(0);
}
#include <stdio.h>
#include <ncurses.h>
#include <time.h>
#include <string.h>
#include <time.h>
#define MINE '*'
#define COVE '#'
#define MARK 'M'
#define UNVIS 0
#define VISIT 1
#define MARKED 2
#define UNMARK 3
extern char * optarg;
int MAXM,MAXR,MAXC,mp[100][100],stat[100][100],OPEN;
int ext[8][2]={1,0,-1,0,0,1,0,-1,1,1,1,-1,-1,1,-1,-1};
void creat_map()
{
memset(mp,0,sizeof(mp));
memset(stat,UNVIS,sizeof(stat));
srand(time(0));
int r,c,m=0;
while(m<MAXM)
{
r=rand()%MAXR;
c=rand()%MAXC;
if(mp[r][c]!=MINE)
{
mp[r][c]=MINE;
m++;
}
}
for(r=0;r<MAXR;r++)
for(c=0;c<MAXC;c++)
if(mp[r][c]==0)
{
mp[r][c]+= (r-1>=0 && mp[r-1][c]==MINE);
mp[r][c]+= (r+1<MAXR && mp[r+1][c]==MINE);
mp[r][c]+= (c-1>=0 && mp[r][c-1]==MINE);
mp[r][c]+= (c+1<MAXC && mp[r][c+1]==MINE);
mp[r][c]+= (r+1<MAXR && c+1<MAXC && mp[r+1][c+1]==MINE);
mp[r][c]+= (r+1<MAXR && c-1>=0 && mp[r+1][c-1]==MINE);
mp[r][c]+= (r-1>=0 && c+1<MAXC && mp[r-1][c+1]==MINE);
mp[r][c]+= (r-1>=0 && c-1>=0 && mp[r-1][c-1]==MINE);
}
return;
}
int main_game()
{
int r,c;
for(r=0;r<MAXR;r++)
for(c=0;c<MAXC;c++)
{
move(r,c);
addch(COVE);
}
refresh();
move(0,0);
int dir;
r=c=0;
while(1)
{
dir=getch();
if(dir==KEY_UP && r>0)
r--;
else if(dir==KEY_DOWN && r<MAXR-1)
r++;
else if(dir==KEY_LEFT && c>0)
c--;
else if(dir==KEY_RIGHT && c<MAXC-1)
c++;
else if(dir=='n')
{
if(mp[r][c]==MINE)
{
clear();
move(5,5);
return 0;
//return 0 ,if failed
}
if(stat[r][c]==VISIT)
continue;
if(mp[r][c]!=0)
{
move(r,c);
printw("%d",mp[r][c]);
stat[r][c]=VISIT;
OPEN++;
if(OPEN==MAXR*MAXC-MAXM)
return 1;
refresh();
}
else
{//BFS
int nr,nc,q[10000][2],qs=0,qe=1,t;
q[qs][0]=r,q[qs][1]=c;
stat[r][c]=VISIT;
while(qs<qe)
{
if(mp[q[qs][0]][q[qs][1]]!=0)
{
qs++;
continue;
}
for(t=0;t<8;t++)
{
nr=q[qs][0]+ext[t][1];
nc=q[qs][1]+ext[t][0];
if(nr>=0 && nr<MAXR &&
nc>=0 && nc<MAXC &&
stat[nr][nc]==UNVIS)
{
q[qe][0]=nr;
q[qe][1]=nc;
stat[nr][nc]=VISIT;
qe++;
}
}
qs++;
}
for(t=0;t<qe;t++)
{
OPEN++;
move(q[t][0],q[t][1]);
if(mp[q[t][0]][q[t][1]]==0)
printw(" ");
else
printw("%d",mp[q[t][0]][q[t][1]]);
}
if(OPEN==MAXR*MAXC-MAXM)
return 1;
}
}
else if(dir=='m')
{
if(stat[r][c]==MARKED)
{
stat[r][c]=UNMARK;
move(r,c);
printw("%c",COVE);
}
else if(stat[r][c]==UNMARK || stat[r][c]==UNVIS)
{
move(r,c);
printw("%c",MARK);
stat[r][c]=MARKED;
}
}
else if(dir=='q')
return 3;
move(r,c);
refresh();
}
return 1;
}
void helpmsg()
{
printf("Usage: mine -r N -c C -m M\n");
printf(" -r N:Number of rows,30 at most\n");
printf(" -c C:Number of colums,30 at most\n");
printf(" -m M:Number of mines,1 at lest,N*C at most\n");
printf(" -h:show this help message\n");
printf("press q to quit game\n");
return ;
}
void show_mine()
{
int r,c;
for(r=0;r<MAXR;r++)
for(c=0;c<MAXC;c++)
if(mp[r][c]==MINE)
{
move(r,c);
printw("%c",MINE);
}
else if(mp[r][c]!=0)
{
move(r,c);
printw("%d",mp[r][c]);
}
else
{
move(r,c);
printw(" ");
}
move(0,0);
refresh();
sleep(2);
return;
}
void init_prog(int argc,char * argv[])
{
int t;
if(argc!=7)
{
printf("Option Error!\n");
helpmsg();
exit(1);
}
while((t=getopt(argc,argv,"r:c:m:h"))!=-1)
{
switch(t)
{
case 'r':
{
MAXR=atoi(optarg);
break;
}
case 'c':
{
MAXC=atoi(optarg);
break;
}
case 'm':
{
MAXM=atoi(optarg);
break;
}
case 'h':
{
helpmsg();
break;
}
defalt:
{
printf("Undefined Option!\n");
exit(1);
}
}
}
if(MAXR<1 || MAXR>30 || MAXC<1 ||MAXC>30 ||
MAXM<1 || MAXM>MAXR*MAXC)
{
printf("Wrong number of R or C or M!\n");
helpmsg();
exit(1);
}
OPEN=0;
return;
}
int main(int argc,char *argv[])
{
int t,r,c;
init_prog(argc,argv);
initscr();
noecho();
cbreak();
keypad(stdscr,TRUE);
creat_map();
time_t st,end;
st=time(0);
t=main_game();
end=time(0);
if(t==1)
{
clear();
move(5,5);
printw(" Congratulations!");
move(7,5);
printw("Baby,you are the winer!");
int h,m;
end-=st;
h=end/3600;
end-=h*3600;
m=end/60;
end-=m*60;
move(9,5);
printw("You spend ");
if(h)
printw("%dh",h);
if(h || m)
printw("%dm",m);
printw("%ds in total!",end);
refresh();
t=getch();
}
else if(t==0)
{
show_mine();
clear();
move(5,5);
printw(" GAME OVER!");
move(7,5);
printw("Press any key to quit");
refresh();
t=getch();
}
endwin();
exit(0);
}