扫雷

堕落了一晚上,写了个扫雷,基于curses。

刚刚开始接触工程上的程序,风格还不好,请大家多指点指点。


ContractedBlock.gif ExpandedBlockStart.gif 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);
}

转载于:https://www.cnblogs.com/dosxp/archive/2008/12/11/1352834.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值