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 + -
显示快捷键?