1. 程式人生 > >linux下 C編寫的 五子棋

linux下 C編寫的 五子棋

五子棋

//5.完善五子棋程式
#include <stdio.h>

#define     NR          8

void showBg(char bg[NR][NR]);
//能下返回真  不能下則返回假
int checkDown(char bg[NR][NR],int x,int y);
//如果發生勝負關係 則返回真  否則返回假
int checkWin(char bg[NR][NR],int x,int y,int flag);

int main(void)
{
    char bg[NR][NR]={0};
    int  x,y,flag=1;//1:表示A方'#'   -1表示B方'M'

    showBg(bg);
    while(1)
    {
        //提示某方下子
        printf("[%s方下子]:",flag==1?"A":"B");
        scanf("%d%d",&y,&x);
        //檢查yx處是否可下子
        if(!checkDown(bg,x,y))
        {
            printf("\033[31m此處不可下子,請重下!\033[0m\n");
            continue;
        }
        //能下則下
        bg[y][x]=flag;
        showBg(bg);
        //檢查勝負關係
        if(checkWin(bg,x,y,flag))
        {
            printf("\033[32m恭喜 %s 方勝利!!!!!!!\033[0m\n",flag==1?"A":"B");
            break;
        }
        //未發生勝負 則換對方下
        flag=-flag;
    }

    return 0;
}

void showBg(char bg[NR][NR])
{
    int x,y;
    system("clear");

    //列印列號
    printf("  ");
    for(x=0;x<NR;x++)
    {
       printf("\033[34m%d \033[0m",x);
    }
    putchar('\n');

    for(y=0;y<NR;y++)
    {
       printf("\033[34m%d \033[0m",y);//列印行號
       for(x=0;x<NR;x++)
       {
          switch(bg[y][x]){
              case 0 :printf("+ ");break;//空白區
              case 1 :printf("\033[36m# \033[0m");break;//A方
              case -1:printf("\033[31mM \033[0m");break;//B方
          }
       }
       putchar('\n');
    }
}
int checkDown(char bg[NR][NR],int x,int y)
{
    //是否在範圍內
    if(x<0||x>=NR||y<0||y>=NR)
        return 0;//no

    //是否已經有棋子
    if(bg[y][x]!=0)
        return 0;//no

    return 1;//yes
}
////////////////////////////////////////////////////
//水平方向(從左到右)
int __check_a(char bg[NR][NR],int x,int y,int flag)
{
    int i,count=0;
    for(i=x-4;i<=x+4;i++)
    {
       if(i<0||i>=NR)
          continue;
       //判斷是否為flag顏色的棋子
       if(bg[y][i]==flag)
       {
           count++;
           if(count>=5)   return 1;
       }
       else
       {
           count=0;
       }
    }
    return 0;
}
//垂直方向(從下到上)
int __check_b(char bg[NR][NR],int x,int y,int flag)
{
    int i,count=0;
    for(i=y-4;i<=y+4;i++)
    {
       if(i<0||i>=NR)
          continue;
       //判斷是否為flag顏色的棋子
       if(bg[i][x]==flag)
       {
           count++;
           if(count>=5)   return 1;
       }
       else
       {
           count=0;
       }
    }
    return 0;
}
//斜線方向<從左上到右下的方向檢查>
int __check_c(char bg[NR][NR],int x,int y,int flag)
{
    int i,j,count=0;
    for(i=y-4,j=x-4;i<=y+4 && j<=x+4;i++,j++)
    {
       if(i<0||i>=NR ||j<0||j>=NR)
          continue;
       //判斷是否為flag顏色的棋子
       if(bg[i][j]==flag)
       {
           count++;
           if(count>=5)   return 1;
       }
       else
       {
           count=0;
       }
    }
    return 0;
}

//反斜線方向<從右上到左下的方向檢查>
int __check_d(char bg[NR][NR],int x,int y,int flag)
{
    int i,j,count=0;
    for(i=y-4,j=x+4;i<=y+4 && j>=x-4;i++,j--)
    {
       if(i<0||i>=NR ||j<0||j>=NR)
          continue;
       //判斷是否為flag顏色的棋子
       if(bg[i][j]==flag)
       {
           count++;
           if(count>=5)   return 1;
       }
       else
       {
           count=0;
       }
    }
    return 0;
}




int checkWin(char bg[NR][NR],int x,int y,int flag)
{
#if 0
    int a=0,b=0,c=0,d=0;
    a=__check_a(bg,x,y,flag);
    if(a)   return 1;
    b=__check_b(bg,x,y,flag);
    if(b)   return 1;
    c=__check_c(bg,x,y,flag);
    if(c)   return 1;
    d=__check_d(bg,x,y,flag);
    return d;
#else

    //表示式短路
    return __check_a(bg,x,y,flag) ||\
           __check_b(bg,x,y,flag) ||\
           __check_c(bg,x,y,flag) ||\
           __check_d(bg,x,y,flag);
#endif //
}
////////////////////////////////////////////////////