fivechee.c

来自「redboy for gba 是BPNS为GBA编写的一个小软件。软件的邹形是B」· C语言 代码 · 共 1,116 行 · 第 1/2 页

C
1,116
字号
#include <CsAgb.h>
#include <Qgraph.h>
#include <graph.h>
#include <rb_stdio.h>
#define chee_hard rb_xp
#define chee_sp rb_yp
#define chee_error rb_bg
#define max_sp 20
extern u8 rb_xp;
extern u8 rb_yp;
extern u8 rb_bg;
extern u32 rnd(u32);
typedef struct
{
   u32 weight;
   u8 type;
} p_type;

typedef struct
{
   u8 xp;
   u8 yp;
   u32 weight;
} chee_loc;

void chee_box(u8 xp,u8 yp,u8 mod)
{
   Q_box(48+xp*8,30+yp*8,54+xp*8,36+yp*8,mod?(mod==1?RGB(20,10,5):(mod==2?RGB(30,30,30):RGB(20,30,0))):18000);
   return;
}

u8 chee_blink(u8 xp,u8 yp,u8 mod)
{
   u8 i=0;
   u32 wait;
   while (TRUE)
   {
      CS_ReadKey();
      wait=15000;
      while (wait)
      {
         wait--;
         if (CS_IsKeyHold(KEY_UP)||CS_IsKeyHold(KEY_DOWN)||CS_IsKeyHold(KEY_LEFT)||CS_IsKeyHold(KEY_RIGHT))
         {
            chee_box(xp,yp,mod);
            return 0;
         }
         if (CS_IsKeyHold(KEY_B))
         {
            chee_box(xp,yp,mod);
            return 1;
         }
      }
      chee_box(xp,yp,(i%2)?0:mod);
      i++;
      if(i>100) i=0;
   }
}
void box_num(u8 xp,u8 yp,u8 num,u8 mod)
{
   u8 number[11][15]={{1,1,1,1,0,1,1,0,1,1,0,1,1,1,1},{0,0,1,0,0,1,0,0,1,0,0,1,0,0,1},
   {1,1,1,0,0,1,1,1,1,1,0,0,1,1,1},{1,1,1,0,0,1,1,1,1,0,0,1,1,1,1},{1,0,1,1,0,1,1,1,1,0,0,1,0,0,1},
   {1,1,1,1,0,0,1,1,1,0,0,1,1,1,1},{1,1,1,1,0,0,1,1,1,1,0,1,1,1,1},{1,1,1,0,0,1,0,0,1,0,0,1,0,0,1},
   {1,1,1,1,0,1,1,1,1,1,0,1,1,1,1},{1,1,1,1,0,1,1,1,1,0,0,1,1,1,1},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
   u8 i,j;
   for (i=0;i<3;i++)
   for (j=0;j<5;j++)
   chee_box(xp+i,yp+j,(number[num][3*j+i]?mod:0));
   return;
}

void chee_sethard()
{
   if (chee_hard>5 || chee_hard<1) chee_hard=1;
   while(TRUE)
   {
      box_num(6,5,chee_hard,1);
      readkey();
      if (CS_IsKeyDown(KEY_DOWN)) chee_hard++;
      else if (CS_IsKeyDown(KEY_UP)) chee_hard--;
      else if (CS_IsKeyDown(KEY_A))
      {
         box_num(6,5,10,1);
         return;
      }
      if (chee_hard<1) chee_hard=5;
      else if (chee_hard>5) chee_hard=1;
   }
}

void chee_clear(u8 *plate,u8 *plate_ve)
{
   u8 i,j;
   for (i=0;i<15;i++)
   for (j=0;j<15;j++)
   {
      *(plate+15*i+j)=0;
      *(plate_ve+15*i+j)=0;
      chee_box(i,j,0);
   }
   return;
}
void chee_wins(u8 man,u8 com)
{
   box_num(2,1,man/10,2);
   box_num(6,1,man%10,2);
   box_num(5,8,com/10,1);
   box_num(9,8,com%10,1);
   while (TRUE)
   {
      CS_ReadKey();
      if (CS_IsKeyDown(KEY_A)) return;
   }
}
void show_win(chee_loc loc,u8 who,u8 *plate)
{
   u8 xp=loc.xp,yp=loc.yp,der=0;
   u8 i,j,ljoin,rjoin;
   int xsp=xp,ysp=yp;
   int xd[4]={1,0,1,-1},yd[4]={0,1,1,1};
   for (i=0;i<4;i++) //获得成五子
   {
      rjoin=0;
      xsp=xp;
      ysp=yp;
      for (j=0;j<4;j++)
      {
         xsp=xsp+xd[i];
         ysp=ysp+yd[i];
         if (xsp<0 || ysp<0 || xsp>14 || ysp>14) break;
         if (*(plate+15*xsp+ysp)!=who) break;
         rjoin++;
      }
      ljoin=0;
      xsp=xp;
      ysp=yp;
      for (j=0;j<4;j++)
      {
         xsp=xsp-xd[i];
         ysp=ysp-yd[i];
         if (xsp<0 || ysp<0 || xsp>14 || ysp>14) break;
         if (*(plate+15*xsp+ysp)!=who) break;
         ljoin++;
      }
      if (rjoin+ljoin>=4) {der=i;break;}
   }
   while(TRUE)
   {
      j=!j;
      xsp=xp-xd[der]*ljoin;
      ysp=yp-yd[der]*ljoin;
      for (i=0;i<5;i++)//反显成五子
      {
         chee_box(xsp,ysp,(j?who:3));
         xsp=xsp+xd[der];
         ysp=ysp+yd[der];
      }
      for (i=0;i<50;i++)
      {
         CS_ReadKey();
         if (CS_IsKeyDown(KEY_A)) return;
      }
   }
}

u8 chees_inline(u8 xp,u8 yp,u8 *plate, u8 who, u8 dre)
{
   u8 i,count=0;
   int xsp=xp,ysp=yp;
   int xd[4]={1,0,1,-1},yd[4]={0,1,1,1};
   for (i=0;i<3;i++)
   {
      xsp=xsp+xd[dre];
      ysp=ysp+yd[dre];
      if (xsp<0 || xsp>14 ||ysp<0 || ysp>14) break;
      if (*(plate+xsp*15+ysp)==(who==1?2:1)) break;
      if (*(plate+xsp*15+ysp)==who) count++;
   }
   xsp=xp;
   ysp=yp;
   for (i=0;i<3;i++)
   {
      xsp=xsp-xd[dre];
      ysp=ysp-yd[dre];
      if (xsp<0 || xsp>14 ||ysp<0 || ysp>14) break;
      if (*(plate+xsp*15+ysp)==(who==1?2:1)) break;
      if (*(plate+xsp*15+ysp)==who) count++;
   }
   return count;
}

u8 check_chee(u8 *plate,u8 first)
{
   u8 i,j;
   u8 com=0,man=0;
   for (i=0;i<15;i++)
   for (j=0;j<15;j++)
   {
      if (*(plate+15*i+j)==1) com++;
      else if(*(plate+15*i+j)==2) man++;
   }
   if (com-man==first) return 0;
   return 1;
}

p_type get_weight(u8 xp,u8 yp,u8 who,u8 *plate)
{
   p_type result={0,5};
   u32 weight=0;
   u8 type;
   int i,j;
   int xd[4]={1,0,1,-1},yd[4]={0,1,1,1};
   u8 ljoin[4],rjoin[4];
   u8 ldev[4],rdev[4];
   u8 lsets[4],rsets[4];
   u8 lstop[4],rstop[4];
   u8 lstart[4],rstart[4],start;
   u8 typ[4]={0,0,0,0};
   int xsp,ysp;
   u8 nostop;
   u8 lblock,rblock,block,oneblock,noblock;
   u8 join,dev,sets;
   u16 nowp;
   u32 score[5]={0,5,20,80,320};
   u32 goals[8]={1,10,100,1000,10000,100000,1000000,10000000};
   u8 c_type[8]={0,0,0,0,0,0,0,0};
   for (i=0;i<4;i++)
   {
      xsp=xp;
      ysp=yp;
      nostop=1;
      lstop[i]=0;
      rstop[i]=0;
      lstart[i]=0;
      rstart[i]=0;
      ljoin[i]=0;
      rjoin[i]=0;
      ldev[i]=0;
      rdev[i]=0;
      lsets[i]=0;
      rsets[i]=0;
      start=1;
      for (j=0;j<4;j++)
      {
         xsp=xsp+xd[i];
         ysp=ysp+yd[i];
         if (xsp<0 || ysp<0 || xsp>14 || ysp>14) break;
         nowp=15*xsp+ysp;
         if (*(plate+nowp)==(3-who)) break;
         if (*(plate+nowp)!=who) nostop=0;
         if (*(plate+nowp)==who)
         {
            rsets[i]++;
            rstop[i]=j+1;
            if (start) {rstart[i]=j+1;start=0;}
            if (nostop) rjoin[i]++;
         }
         rdev[i]++;
      }
      xsp=xp;
      ysp=yp;
      nostop=1;
      start=1;
      for (j=0;j<4;j++)
      {
         xsp=xsp-xd[i];
         ysp=ysp-yd[i];
         if (xsp<0 || ysp<0 || xsp>14 || ysp>14) break;
         nowp=15*xsp+ysp;
         if (*(plate+nowp)==(3-who)) break;
         if (*(plate+nowp)!=who) nostop=0;
         if (*(plate+nowp)==who)
         {
            lsets[i]++;
            lstop[i]=j+1;
            if (start) {lstart[i]=j+1;start=0;}
            if (nostop) ljoin[i]++;
         }
         ldev[i]++;
      }
   }
   for (i=0;i<4;i++)//单向分析
   {
      join=ljoin[i]+rjoin[i];
      dev=ldev[i]+rdev[i];
      lblock=(ljoin[i]==ldev[i]);
      rblock=(rjoin[i]==rdev[i]);
      block=(lblock||rblock);
      oneblock=(lblock!=rblock);
      noblock=!block;
      sets=lsets[i]+rsets[i];
      weight=weight+(dev>3?score[lsets[i]]+score[rsets[i]]:0)+dev;
      if (join>=4)//连四
      {
         result.weight=3*goals[7];
         result.type=0;
         return result;
      }
      else if (join>=3 && noblock) typ[i]=6;//活三
      else if (ldev[i]>=3 && rdev[i]>=3 && join==2 && (lstop[i]==lsets[i]+1) && (rstop[i]==rsets[i]+1) && lsets[i]>=2 && rsets[i]>=2) typ[i]=6;
      else if (join==3 && oneblock) typ[i]=5;//冲三
      else if ((ldev[i]==4 && lsets[i]==3)||(rdev[i]==4 && lsets[i]==3)) typ[i]=4;//离三
      else if ((ldev[i]>=3 && lsets[i]==2 && rjoin[i]>=1 && lstop[i]==3)||(rdev[i]>=3 && rsets[i]==2 && ljoin[i]>=1 && rstop[i]==3)) typ[i]=4;
      else if ((ljoin[i]==2 && rsets[i]>=1 && rstart[i]==1)||(rjoin[i]==2 && lsets[i]>=1 && lstart[i]==1)) typ[i]=4;
      else if (join==2 && noblock) typ[i]=3;//活二
      else if (noblock && ((lsets[i]==2 && lstop[i]==3 && ldev[i]>3)||(rsets[i]==2 && rstop[i]==3 && rdev[i]>3))) typ[i]=2;//离二
      else if (noblock && ((rjoin[i]==1 && lsets[i]>=1 && lstart[i]==2 && ldev[i]>2)||(ljoin[i]==1 && rsets[i]>=1 && rstart[i]==2 && rdev[i]>2))) typ[i]=2;
      else if (join==1 && dev>=4) typ[i]=1;//单一
      else typ[i]=0;
      weight=weight+goals[typ[i]];
      c_type[typ[i]]++;
   }
   if (c_type[6] || c_type[5]+c_type[4]>1 || ((c_type[5]||c_type[4]) && (c_type[3] || c_type[2])))
   {
      weight=weight+3*goals[6];
      type=1;
   }//必死态
   else if (c_type[5]+c_type[4]+c_type[3]+c_type[2]>1)
   {
      weight=weight+goals[6];
      type=2;
   }//两步致死态
   else if (c_type[5] || c_type[4])
   {
      weight=weight+5*goals[5];
      type=3;
   }//可控态
   else if (c_type[3]||c_type[2])
   {
      weight=weight+goals[4];
      type=4;
   }
   else type=5;
   result.weight=weight;
   result.type=type;
   return result;
}
void chee_push(u8 xp,u8 yp,p_type com[15][15],p_type man[15][15],p_type stack[max_sp][2][8][4],u8 *plate)//尝试放棋后保存当前状态保存
{
   int x,y;
   int i,j;
   int xd[8]={0,1,1,1,0,-1,-1,-1};
   int yd[8]={-1,-1,0,1,1,1,0,-1};
   if (chee_sp>=max_sp) {chee_error=1;return;}//堆栈溢出
   for (i=0;i<8;i++)//八个方向受影响
   {
      x=xp;
      y=yp;
      for (j=0;j<4;j++)//每个方向有四个点受影响
      {
         x+=xd[i];
         y+=yd[i];
         if (x<0 || x>14 || y<0 || y>14) continue;//点在棋盘之外
         if (plate[x*15+y]) continue;//该点已经有棋子
         stack[chee_sp][0][i][j]=com[x][y];
         stack[chee_sp][1][i][j]=man[x][y];//保存当前状态
         com[x][y]=get_weight(x,y,1,plate);
         man[x][y]=get_weight(x,y,2,plate);//计算该点新状态
      }
   }
   chee_sp++;//堆栈指针向前
}
void chee_pop(u8 xp,u8 yp,p_type com[15][15],p_type man[15][15],p_type stack[max_sp][2][8][4],u8 *plate)//撤消尝试
{
   int x,y;
   int i,j;
   int xd[8]={0,1,1,1,0,-1,-1,-1};
   int yd[8]={-1,-1,0,1,1,1,0,-1};
   if (chee_sp<1) {chee_error=1;return;}//堆栈溢出
   chee_sp--;//堆栈指针后退
   for (i=0;i<8;i++)//八个方向受影响
   {
      x=xp;
      y=yp;
      for (j=0;j<4;j++)//每个方向有四个点受影响
      {
         x+=xd[i];
         y+=yd[i];
         if (x<0 || x>14 || y<0 || y>14) continue;//点在棋盘之外
         if (plate[x*15+y]) continue;//该点已经有棋子
         com[x][y]=stack[chee_sp][0][i][j];
         man[x][y]=stack[chee_sp][1][i][j];//恢复该点状态
      }
   }
}
chee_loc fix_set(u8 xp,u8 yp,u8 *plate,p_type com[15][15])//查询受限设置点
{
   int x,y;
   int i,j;
   int xd[8]={0,1,1,1,0,-1,-1,-1};
   int yd[8]={-1,-1,0,1,1,1,0,-1};
   chee_loc result={xp,yp};
   for (i=0;i<8;i++)//八个方向受影响
   {
      x=xp;
      y=yp;
      for (j=0;j<4;j++)//每个方向有四个点受影响
      {
         x+=xd[i];
         y+=yd[i];
         if (plate[x*15+y]) continue;//该点已经有棋子
         if (x<0 || x>14 || y<0 || y>14) continue;//点在棋盘之外
         if (com[x][y].type==0) {result.xp=x;result.yp=y;return result;}
      }
   }
}

void chee_sort(chee_loc *p)//考查点排序
{
   int i,j;
   chee_loc temp;
   for (i=1;i<p[0].xp;i++)
   for (j=i+1;j<=p[0].xp;j++)
   {
      if (p[j].weight>p[i].weight)
      {
         temp=p[i];
         p[i]=p[j];
         p[j]=temp;
      }
   }
}

chee_loc comset(u8 *plate,u8 *man,u8 step,p_type coms[15][15],p_type mans[15][15],p_type stack[max_sp][2][8][4])//电脑下棋(高级)
{
   chee_loc set={20,20},result;//运算结果
   p_type nowtype,hsan,entype;
   chee_loc temp;
   int i,j,k;
   //u8 tp;
   int m,n,p;
   u32 cnow=0,mnow=0,now=0,hsnow=0;//当前权重
   u32 cmax=0,mmax=0,max=0,hsmax=0;//最大权值
   u8 cxp=20,cyp=20,mxp=20,myp=20,xp=20,yp=20,xsp,ysp,txp,typ;
   u8 ctype,mtype;
   u8 safe_xp=250,safe_yp=250;//已知安全点
   u8 maxsteps=chee_hard+1;//推算最大步数
   u16 nowp;
   u8 next=step+1;
   //u8 safe=1;
   chee_loc comp[5][10];//考察点
   chee_loc manp[5][10];
   for (m=0;m<5;m++)//初始化
   {
      comp[m][0].xp=0;
      manp[m][0].xp=0;
   }
   for (i=0;i<15;i++)//棋盘分析
   for (j=0;j<15;j++)
   {
      nowp=15*i+j;
      if (*(plate+nowp)) continue;
      nowtype=coms[i][j];//该点我方权值
      entype=mans[i][j];//敌方权值
      if (nowtype.type==0) //敌手致命
      {
         set.xp=200+i;
         set.yp=j;
         return set;
      }
      cnow=nowtype.weight;
      m=comp[nowtype.type][0].xp;
      if (nowtype.type!=5 && m<9)
      {
         comp[nowtype.type][0].xp++;
         m++;
         comp[nowtype.type][m].xp=i;
         comp[nowtype.type][m].yp=j;
         comp[nowtype.type][m].weight=cnow+cnow+entype.weight;
      }
      if (cnow>cmax)
      {
         cxp=i;
         cyp=j;
         cmax=cnow;
      }
      else if (cnow==cmax && rnd(2))
      {
         cxp=i;
         cyp=j;
      }
      mnow=entype.weight;
      m=manp[entype.type][0].xp;
      if (entype.type!=5 && m<9)
      {
         manp[entype.type][0].xp++;
         m++;
         manp[entype.type][m].xp=i;
         manp[entype.type][m].yp=j;
         manp[entype.type][m].weight=mnow+cnow;
      }
      if (mnow>mmax)
      {
         mxp=i;
         myp=j;
         mmax=mnow;
      }
      else if(mnow==mmax && rnd(2))
      {
         mxp=i;
         myp=j;
      }
      now=cnow+cnow+mnow;
      if (now>max)
      {
         max=now;
         txp=xp;
         typ=yp;
         xp=i;
         yp=j;
      }
      else if(now==max && rnd(2))
      {
         txp=xp;
         typ=yp;
         xp=i;
         yp=j;
      }
   }//获得最大点
   if (step>maxsteps)
   {
      set.xp=xp;
      set.yp=yp;
      return set;
   }//到达最大步数
   for (i=1;i<5;i++)//考查点排序
   {
      chee_sort(&comp[i][0]);
      chee_sort(&manp[i][0]);
   }
   if (manp[0][0].xp) //敌方必杀点(防)
   {
      xsp=manp[0][1].xp;
      ysp=manp[0][1].yp;
      nowp=15*xsp+ysp;
      if (step==0 || manp[0][0].xp>1)
      {
         set.xp=xsp;
         set.yp=200+ysp;
         return set;
      }
      *(plate+nowp)=1;//堵住该子
      *(man+nowp)=2;
      chee_push(xsp,ysp,coms,mans,stack,plate);//保存当前状态
      result=comset(man,plate,next,mans,coms,stack);//模拟敌方下子
      *(man+nowp)=0;
      *(plate+nowp)=0;//恢复棋盘
      chee_pop(xsp,ysp,coms,mans,stack,plate);//恢复数据
      set.xp=xsp;
      if (result.xp>=200) set.yp=ysp+200;//防守失败
      else set.yp=ysp;//可以防
      return set;
   }

   if (comp[1][0].xp)//我方活三(攻)
   {
      set.xp=comp[1][1].xp+200;
      set.yp=comp[1][1].yp;

⌨️ 快捷键说明

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