黑白棋游戏程序

#include
#include
#include
#include
#include
#include
using namespace std;


int qi[8][8];
#define SIZE 8


void display(char board[][SIZE])
{
    int row=0;
    int col=0;
    char col_label='a';
    printf("\n ");
    for(col=0;col         printf("   %c",col_label+col);
    printf("\n");


    for(row=0;row     {
        printf("  +");
        for(col=0;col             printf("---+");
        printf("\n%2d|",row+1);


        for(col=0;col             printf(" %c |",board[row][col]);
        printf("\n");
    }


    printf("  +");
    for(col=0;col     printf("---+");
    printf("\n");
}//布置棋盘


int valid_moves(char board[][SIZE],int moves[][SIZE],char player)//查找
{
    int rowdelta=0;
    int coldelta=0;
    int row=0;
    int col=0;
    int x=0;
    int y=0;
    int no_of_moves=0;
    char opponent=(player=='o')?'*':'o';//player与opponent符号不同
    for(row=0;row     for(col=0;col         moves[row][col]=0;
    for(row=0;row         for(col=0;col         {
            if(board[row][col]!=' ')
            continue;
            for(rowdelta=-1;rowdelta<=1;rowdelta++)
                for(coldelta=-1;coldelta<=1;coldelta++)//查找周围8个方向
                {
                    if(row+rowdelta<0||row+rowdelta>=SIZE||
                        col+coldelta<0||col+coldelta>=SIZE||
                        (rowdelta==0&&coldelta==0))
                    continue;
                    if(board[row+rowdelta][col+coldelta]==opponent)//与player不同的符号找到了
                    {
                        x=row+rowdelta;
                        y=col+coldelta;
                        for(;;)//接着判定往下的方向
                        {
                            x+=rowdelta;
                            y+=coldelta;
                            if(x<0||x>=SIZE||y<0||y>=SIZE)
                                break;
                            if(board[x][y]==' ')
                                break;
                            if(board[x][y]==player)//有player符号满足条件,player可以下
                            {
                                moves[row][col]=1;//查找全部可以下的地方并变为1
                                no_of_moves++;
                                break;
                            }
                        }
                    }
                }
        }
    return no_of_moves;
}


void make_move(char board[][SIZE],int row,int col,char player)//改变棋子
{
    int rowdelta=0;
    int coldelta=0;
    int x=0;
    int y=0;
    char opponent=(player=='o')?'*':'o';
    board[row][col]=player;
    for(rowdelta=-1;rowdelta<=1;rowdelta++)//查找棋子8个方向
        for(coldelta=-1;coldelta<=1;coldelta++)
        {
            if(row+rowdelta<0||row+rowdelta>=SIZE||
                col+coldelta<0||col+coldelta>=SIZE||
                (rowdelta==0&&coldelta==0))
            continue;
            if(board[row+rowdelta][col+coldelta]==opponent)
            {
                x=row+rowdelta;
                y=col+coldelta;


                for(;;)
                {
                    x+=rowdelta;
                    y+=coldelta;
                    if(x<0||x>=SIZE||y<0||y>=SIZE)
                        break;
                    if(board[x][y]==' ')
                        break;
                    if(board[x][y]==player)
                    {
                        while(board[x-=rowdelta][y-=coldelta]==opponent)
                        board[x][y]=player;//改动棋子
                        break;
                    }
                }
            }
        }
}


int get_score(char board[][SIZE],char player)
{
    int score=0;
    int row=0;
    int col=0;
    char opponent=player=='o'?'*':'o';
    for(row=0;row         for(col=0;col         {
            score-=board[row][col]==opponent;//如果与player一样就加1
            score+=board[row][col]==player;//如果与player不一样就减1
        }
    return score;
}


int best_move(char board[][SIZE],int moves[][SIZE],char player)
{
    int row=0;
    int col=0;
    int i=0;
    int j=0;
    char opponent=player=='o'?'*':'o';
    char new_board[SIZE][SIZE]={0};
    int score=0;
    int new_score=0;
    for(row=0;row         for(col=0;col         {
            if(!moves[row][col])
                continue;
            for(i=0;i                 for(j=0;j                     new_board[i][j]=board[i][j];


            make_move(new_board,row,col,player);//变动测试
            new_score=get_score(new_board,player);//得出变动后的分数
            if(score                 score=new_score;
        }
  return score;
}


void computer_move(char board[][SIZE],int moves[][SIZE],char player)//palyer=*
{
    int row=0;
    int col=0;
    int best_row=0;
    int best_col=0;
    int i=0;
    int j=0;
    int new_score=0;
    int score=100;
    char temp_board[SIZE][SIZE];
    int temp_moves[SIZE][SIZE];
    char opponent=player=='o'?'*':'o';
    for(row=0;row         for(col=0;col         {
            if(moves[row][col]==0)
                continue;
            for(i=0;i                 for(j=0;j                     temp_board[i][j]=board[i][j];//测试
            make_move(temp_board,row,col,player);
            valid_moves(temp_board,temp_moves,opponent);
            new_score=best_move(temp_board,temp_moves,opponent);//得分
            if(new_score             {
                score=new_score;
                best_row=row;
                best_col=col;
            }
        }
    make_move(board,best_row,best_col,player);
}//此函数以上为人机函数




void print_h(int h)
{
cout << "     " << (char)(h+65) ;
for (int k=0; k<8; k++)
{
switch (qi[h][k])
{   case 0: cout << "□"; break;
   case 2: cout << "●"; break;
case 1: cout << "◎"; break;
}
}
printf("\n");
}


void print()
{
cout << "      01234567" << endl;
for (int l=0; l<8; l++)
print_h(l);
}


void xiugai(int hang, int lie, int heng, int zong, int num)
{
for (int i=1; i<=num; i++)
{
hang+=heng; lie+=zong;
qi[hang][lie]=3-qi[hang][lie];
}
}


int panduan(int count, int shu, int se)
{
int out; // out=0:不继续; out=1:继续; out=2:不继续并返回成功;
    if (shu==0) out=0;//无子
else if (shu==(3-se)) out=1;
    else if (count==1) out=0;//说明跳过了上面一条,紧邻同色棋
     else out=2;//只剩下了同色的情况
return out;
}


bool chuli(int se, int i, int j, bool leixing)
{
bool ctrl=false;
int flag=1;
int hang=i; int lie=j;
int count=0;//各个方向的第N个棋子
while (hang>0 && flag==1) // 向上判断
{
hang--;
count++;
flag=panduan(count, qi[hang][lie], se);
}
if (flag==2) if (leixing) {   xiugai(i,j,-1,0,count-1); ctrl=true; }
            else ctrl=true;


flag=1;
count=0;
    hang=i; lie=j;
while (hang<7 && flag==1) // 向下判断
{
hang++;
count++;
flag=panduan(count, qi[hang][lie], se);
}
if (flag==2) if (leixing) {   xiugai(i,j,1,0,count-1); ctrl=true; }
                 else ctrl=true;
flag=1;
count=0;
    hang=i; lie=j;
while (lie>0 && flag==1) // 向左判断
{
lie--;
count++;
flag=panduan(count, qi[hang][lie], se);
}
if (flag==2) if (leixing) {   xiugai(i,j,0,-1,count-1); ctrl=true; }
                 else ctrl=true;
flag=1;
count=0;
    hang=i; lie=j;
while (lie<7 && flag==1) // 向右判断
{
lie++;
count++;
flag=panduan(count, qi[hang][lie], se);
}
if (flag==2) if (leixing) {   xiugai(i,j,0,1,count-1); ctrl=true; }
                 else ctrl=true;
flag=1;
count=0;
    hang=i; lie=j;
while (hang>0 && lie>0 && flag==1) // 向左上判断
{
hang--; lie--;
count++;
flag=panduan(count, qi[hang][lie], se);
}
if (flag==2) if (leixing) {   xiugai(i,j,-1,-1,count-1); ctrl=true; }
                 else ctrl=true;
flag=1;
count=0;
    hang=i; lie=j;
while (hang<7 && lie<7 && flag==1) // 向右下判断
{
hang++; lie++;
count++;
flag=panduan(count, qi[hang][lie], se);
}
if (flag==2) if (leixing) {   xiugai(i,j,1,1,count-1); ctrl=true; }
                 else ctrl=true;
flag=1;
count=0;
    hang=i; lie=j;
while (hang>0 && lie<7 && flag==1) // 向右上判断
{
hang--; lie++;
count++;
flag=panduan(count, qi[hang][lie], se);
}
if (flag==2) if (leixing) {   xiugai(i,j,-1,1,count-1); ctrl=true; }
                 else ctrl=true;
flag=1;
count=0;
    hang=i; lie=j;
while (hang<7 && lie>0 && flag==1) // 向左下判断
{
hang++; lie--;
count++;
flag=panduan(count, qi[hang][lie], se);
}
if (flag==2) if (leixing) {   xiugai(i,j,1,-1,count-1); ctrl=true; }
                 else ctrl=true;
if (ctrl && leixing) qi[i][j]=se;//leixing为真且满足条件该处落子
return ctrl;
}




int main()
{
int  b;
bool ctrl=false, ctrl_all=false, ctrl_1=false, ctrl_2=false;//ctrl-1为白
int j=0;
int n=1;//落子数
int se=2;
char h,l;
int lie, hang;
int count_hei=0; int count_bai=0;//计数


char board[SIZE][SIZE]={0};
    int moves[SIZE][SIZE]={0};//可移动位置数组
    int row=0;
    int col=0;
    int no_of_games=0;
    int no_of_moves=0;//落子个数
    int invalid_moves=0;
    int comp_score=0;
    int user_score=0;
    char y=0;
    char x=0;
    char again=0;
    int player=0;
    double start,finish;
    int i;
    system("color B0");
printf("选择人人对战按 1 ,选择人机对战按 0 \n");
scanf("%d",&b);


if(b)//人人函数
{
        start = clock();//取开始时间
        for ( i=0; i<8; i++)
            for (j=0; j<8; j++)
                qi[i][j]=0;
        qi[3][3]=1; qi[4][4]=1; qi[3][4]=2; qi[4][3]=2;//1是白棋,2是黑棋
        while (n<61)
        {
            se=3-se;//黑白转换
            for (i=0; i<8; i++)
            {
                for (j=0; j<8; j++)
                {
                    if (qi[i][j]==0)
                    {
                        ctrl_1=(ctrl_1 || chuli(1, i, j, false));//对可落白子的查找,真则可下
                        if (ctrl_1 && ctrl_2) break;
                        ctrl_2=(ctrl_2 || chuli(2, i, j, false));//对可落黑子的查找,真则可下
                        if (ctrl_1 && ctrl_2) break;
                    }
                }
                if (ctrl_1 && ctrl_2) break;//进行全盘判定如果存在可下点则跳出
            }
            if (!(ctrl_1 || ctrl_2)) break;//无可下点
            if ((!ctrl_1) && ctrl_2 && (se==1)) continue;//白棋pass,黑棋接着下
            if ((!ctrl_2) && ctrl_1 && (se==2)) continue;//黑棋pass,白棋接着下//不进行落子处理只进行判定
            count_hei=0; count_bai=0;
            for (i=0; i<8; i++)
                for (j=0; j<8; j++)
                {
                    if (qi[i][j]==1) count_hei++;//统计黑白棋个数
                    else if (qi[i][j]==2) count_bai++;
                }
            print();//初始棋盘生成
            cout << "     黑方 " << count_bai << " : " << count_hei << " 白方" << endl;
            if (se==1) cout << "     白方下子" << endl;
            else cout << "     黑方下子" << endl;
            while (!ctrl)
            {
                cout << "     ";
                cin >> h >> l;
                cout << endl;
                hang=h-65; lie=l-48;//把字符转换为数字
                if (qi[hang][lie]!=0) ctrl=false;
                else ctrl=chuli(se, hang, lie, true);//进行下棋,若成功进行完了cirl真
                if (!ctrl) cout << "     此处不能落子!" << endl;
            }
            ctrl=false; ctrl_1=false; ctrl_2=false;//重置
            n++;
        }
        count_hei=0; count_bai=0;
        for (i=0; i<8; i++)
            for (j=0; j<8; j++)
            {
                if (qi[i][j]==1) count_hei++;
                else if (qi[i][j]==2) count_bai++;
            }//最终计数
        print();
        cout << "     白方 " << count_hei << " : " << count_bai << " 黑方" << endl;
        if (count_hei>count_bai) cout << "     白方胜!" << endl;
        else if (count_hei         else cout << "     打平了!" << endl;
        finish = clock();//取结束时间
        printf( "     %.2f seconds\n",(finish - start) / CLOCKS_PER_SEC);//以秒为单位显示之
        cout << "     按任意键退出..." << endl;
        cin >> i;
    }//人人函数结束
else//人机函数开始
{
    start = clock();//取开始时间
    printf("\nREVERSI\n\n");
    printf("  你执白先行 - (o)\n  电脑为黑色 - (*).\n");
    printf("\n按回车键开始\n");
    scanf("%c",&again);


    do
 {
  player=++no_of_games%2;
  no_of_moves=4;


  for(row=0;row    for(col=0;col     board[row][col]=' ';


  board[SIZE/2-1][SIZE/2-1]=board[SIZE/2][SIZE/2]='o';
  board[SIZE/2-1][SIZE/2]=board[SIZE/2][SIZE/2-1]='*';


  do
  {
   display(board);
   if(player++%2)//玩家走恒成立
   {
    if(valid_moves(board,moves,'o'))//查找全部可以下的地方标为1
    {
     for(;;)
     {
      fflush(stdin);//清空输入缓冲区,不影响下一次输入
      printf("该你下了(行列): ");
      scanf("%d%c",&x,&y);
      y=tolower(y)-'a';//将字符变为小写字母并得到其坐标
      x--;
      if(x>=0&&y>=0&&x       {
       make_move(board,x,y,'o');//变动棋子
       no_of_moves++;//落子数
       break;
      }
      else
       printf("该处不可落子,请另寻他处!\n");
     }
    }
    else//玩家没有可落子的地方
     if(++invalid_moves<2)//玩家pass
     {
      fflush(stdin);
      printf("\nYou have to pass,press return");
      scanf("%c",&again);
     }
     else
      printf("\n没地方可走了,游戏结束\n");
   }
   else//机器走
   {
    if(valid_moves(board,moves,'*'))//查找
    {
     invalid_moves=0;//机器有地下就重置
     computer_move(board,moves,'*');
     no_of_moves++;
    }
    else//机器无地可下
    {
     if(++invalid_moves<2)//玩家无地可下invalid-moves已经是1
      printf("\nI have to pass, your go\n");
     else
      printf("\n没地方可走了,游戏结束\n");
    }
   }
  comp_score=user_score=0;
  for(row=0;row    for(col=0;col    {
    comp_score+=board[row][col]=='*';
    user_score+=board[row][col]=='o';
   }
  printf("     最终得分:\n");
  printf("          Computer   %d\n            User     %d",comp_score,user_score);
  }while(no_of_moves

  display(board);//


  comp_score=user_score=0;
  for(row=0;row    for(col=0;col    {
    comp_score+=board[row][col]=='*';
    user_score+=board[row][col]=='o';
   }
  printf("     最终得分:\n");
  printf("          Computer   %d\n            User     %d\n\n",comp_score,user_score);


  fflush(stdin);
  finish = clock();//取结束时间
  printf( "     %.2f seconds\n",(finish - start) / CLOCKS_PER_SEC);//以秒为单位显示
  printf("Do you want to play again (y/n): ");
  scanf("%c",&again);
 }while(tolower(again)=='y');


 printf("\nGoodbye\n");
}


return 0;

}


你可能感兴趣的:(黑白棋游戏程序)