game.c

来自「数字信号处理实验」· C语言 代码 · 共 506 行 · 第 1/2 页

C
506
字号
     {command=bioskey(0);
      if(command==VK_ENTER) return ENTER;
      else if(command==VK_DOWN)
        {drawmat(jin24S,24,300,350,RED);
         drawmat(ru24S,24,320,350,RED);
         drawmat(tui24S,24,300,380,WHITE);
         drawmat(chu24S,24,320,380,WHITE);
         break;
        }
      }
   while(1)   /*当“退出”突出显示时,用户按“Enter"和向上方向键有效*/
     {command=bioskey(0);
     if(command==VK_ENTER) return QUITE;
     else if(command==VK_UP) break;
     }
  }
}


void draw(int x,int y,int MorC)
/*根据MorC的值在第一、二维的坐标分别为x、y的位置下一子*/
{
int vx,vy;
int color;
chsman[x][y]=MorC;/*下子*/
if(MorC==P1) color=mancolor;
else  color=computercolor;
switch(x)
  {case 0:vy=170;break;
   case 1:vy=240;break;
   case 2:vy=310;
  }
switch(y)
  {case 0:vx=250;break;
   case 1:vx=320;break;
   case 2:vx=390;
  }
setcolor(color);
circle(vx,vy,25);
}
/*根据键盘输入的z的值确定下子的第一维(x)和第二维坐标*/
int convert(int *x,int *y,char z)
{
 switch(z)
 {case 0x31:*x=2;*y=0;break;
  case 0x32:*x=2;*y=1;break;
  case 0x33:*x=2;*y=2;break;
  case 0x34:*x=1;*y=0;break;
  case 0x35:*x=1;*y=1;break;
  case 0x36:*x=1;*y=2;break;
  case 0x37:*x=0;*y=0;break;
  case 0x38:*x=0;*y=1;break;
  case 0x39:*x=0;*y=2;
 }
 return 0;
}
int man(void)      /*人按1-9键下棋,小键盘上的1-9键分别对应于棋盘上的九个格*/
{
int row,col,test=1;
char k=0x30;
while(test==1||chsman[row][col]!=0)
 {
  while(k<0x31||k>0x39)
    k=bioskey(0);
  convert(&row,&col,k);
  test=0;
  k=0x30;
 }
draw(row,col,P1);
return 0;
}

void judge(void)
{
 int row, col;
 int i;
 /*分别用三个数组存储 棋盘上各行,各列,或者两条线上的数组元素的值的和(以下称之为权值)*/
 int rskAndAtkLevlRow[3] = {0}, rskAndAtkLevlCol[3] = {0}, rskAndAtkLevlSlsh[2] = {0};
 if(stepFlg == 0){
    /*计算机下的第一子特别处理,优先下a[1][1]位置*/
  stepFlg = 1;
  if(chsman[1][1] == P1){
   draw(0,0,P2);
   return;
  } 
  else{
   draw(1,1,P2);
   return;
  }
 }
 stepFlg++;
 /*计算各行,各列以及两斜线的权值*/
 for(row = 0; row < 3; row++){
     for(col = 0; col < 3; col++){
         rskAndAtkLevlRow[row] += chsman[row][col];
     }
 }
 for(col = 0; col < 3; col++){
     for(row = 0; row < 3; row++){
         rskAndAtkLevlCol[col] += chsman[row][col];
     }
 }
 rskAndAtkLevlSlsh[0] = chsman[0][0] + chsman[1][1] + chsman[2][2];
 rskAndAtkLevlSlsh[1] = chsman[0][2] + chsman[1][1] + chsman[2][0];

 /*若权值为-2(计算机下了两了,另一位置为空),计算机攻击*/
 /*攻击某一行*/
 for(row = 0; row < 3; row++){
  if(rskAndAtkLevlRow[row] == -2){
   chkAndPutDwnRow(row)
  }
 }
 /*攻击某一列*/
 for(col = 0; col< 3; col++){
     if(rskAndAtkLevlCol[col] == -2){
   chkAndPutDwnCol(col)
     }
 }
 /*攻击斜率为-1的斜线*/
 if(rskAndAtkLevlSlsh[0] == -2){
     for(row = 0, col = 0; row < 3; row++, col++){
         if(chsman[row][col]==0)
            {draw(row,col,P2);return;}
     }
 }
 /*攻击斜率为1的斜线*/
 if(rskAndAtkLevlSlsh[1] == -2){
     for(row = 0, col = 2; row < 3; row++, col--)
           if(chsman[row][col]==0) {draw(row,col,P2);return;}
 }
 /*若权值为2(人下了两子,另一位置为空),计算机防守*/
 /*在某一行上防守*/
 for(row = 0; row < 3; row++){
     if(rskAndAtkLevlRow[row] == 2)
       chkAndPutDwnRow(row)
 }
 /*在某一列上防守*/
 for(col = 0; col< 3; col++){
     if(rskAndAtkLevlCol[col] == 2)
         chkAndPutDwnCol(col)
 }
 /*在斜率为-1的斜线上防守*/
 if(rskAndAtkLevlSlsh[0] == 2){
     for(row = 0, col = 0; row < 3; row++, col++)
           if(chsman[row][col]==0) {draw(row,col,P2);return;}
 }
 /*在斜率为1的斜线上防守*/
 if(rskAndAtkLevlSlsh[1] == 2){
     for(row = 0, col = 2; row < 3; row++, col--)
           if(chsman[row][col]==0) {draw(row,col,P2);return;}
 }
 /*若上述条件都不符,计算机在棋盘四角上下一子*/
 for(row = 0; row < 3; row++){
     for(col = 0; col < 3; col++){
         if(chsman[row][col] == 0 && ((row == 0 && col == 0) || (row == 0 && col == 2) ||
    (row == 2 && col == 0) || (row == 2 && col == 2)))
        {draw(row,col,P2);return;}
     }
 }
 /*若上述条件都不符,计算机在棋盘与数字键2、4、6、8的位置上下一子*/
 for(row = 0; row < 3; row++){
     for(col = 0; col < 3; col++){
         if(chsman[row][col] == 0 && ((row == 0 && col == 1) || (row == 1 && col == 0) ||
             (row == 1 && col == 2) || (row == 2 && col == 1)))
        {draw(row,col,P2);return;}
     }
 }
}
void chessboard()
/*进入游戏后画出棋盘*/
  {int i,j;
   cleardevice();
   setcolor(BACKGROUND);
   for(j=0;j<=getmaxy();j++)
        line(0,j,getmaxx(),j);   /*用循环语句画背景防止屏幕闪烁*/
   setcolor(RED);
   line(215, 205, 425, 205);
   line(215, 275, 425, 275);
   line(285, 135, 285, 345);
   line(355, 135, 355, 345);
   drawmat(ji24S,24,145,110,computercolor);    /*在棋盘边写"计算机"与"人",先下一方用黑色字,另一方白色字*/
   drawmat(suan24S,24,165,110,computercolor);
   drawmat(Ji24S,24,185,110,computercolor);
   drawmat(ren24S,24,460,110,mancolor);
  }
/*判断游戏是否结束,若结束则输出结果并返回1,否则返回零*/
int chkresult(void)
{int i;
 for(i = 0; i < 3; i++)  
     if(chsman[i][0] + chsman[i][1] + chsman[i][2] == -3 ||  /*计算机赢*/
          chsman[0][i] + chsman[1][i] + chsman[2][i] == -3 ||
            chsman[0][0] + chsman[1][1] + chsman[2][2] == -3 ||
              chsman[0][2] + chsman[1][1] + chsman[2][0] == -3)
       {drawmat(ying24S,24,165,150,RED);
        drawmat(shu24S,24,460,150,WHITE);
        return 1;
       }
 for(i = 0; i < 3; i++) 
     if(chsman[i][0] + chsman[i][1] + chsman[i][2] == 3 ||  /*人赢*/
               chsman[0][i] + chsman[1][i] + chsman[2][i] == 3 ||
                 chsman[0][0] + chsman[1][1] + chsman[2][2] == 3 ||
                  chsman[0][2] + chsman[1][1] + chsman[2][0] == 3)
       {drawmat(ying24S,24,460,150,RED);
        drawmat(shu24S,24,165,150,WHITE);
        return 1;
       }
 if(stepFlg==5)/*计算机已下五子(计算机先下)或四子(人先下), 和棋*/
    {drawmat(he24S,24,293,110,RED);
     drawmat(qi24S,24,324,110,RED);
     return 1;
    } 
 return 0;
}
void compete() /*进入游戏,并对本函数对下棋的一些参数初始化*/
 {int i,j;
  int result;
  stepFlg = 0;
  for(i=0;i<3;i++)     /*初始化棋盘状态*/
    for(j=0;j<3;j++)
      chsman[i][j]=0;
  randomize();
  firstone=random(2);  /*随机让人或计算机先下第一子*/
  if(firstone==MAN) {mancolor=BLACK;computercolor=WHITE;}  /*先下者用黑子*/
  else {mancolor=WHITE;computercolor=BLACK;}
  chessboard();       /*画棋盘*/
  while(1)
    {
    if(firstone==MAN)    /*先后下子直至结束*/
       {man();
       if(chkresult()==1) {getch();return;}
       judge();
       if(chkresult()==1) {getch();return;}
       }
    else
      {judge();
       if(chkresult()==1) {getch();return;}
       man();
       if(chkresult()==1) {getch();return;}
      }
    }
 }
int main(void)
{ int k=ENTER;
  initgr(); /* BGI初始化 */
  while(k==ENTER)
  {k=pictureone();
   if(k==QUITE) break;
   else compete();
  }
  closegraph();
  return 0;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?