五子棋透明棋盘界面设计(C语言)
五子棋透明棋盘设计,漂亮的界面制作。程序设置双人对奕,人机模式,对战演示三种模式。设置悔棋,记录功能,有禁手设置。另有复盘功能设置。
本文主要介绍透明的玻璃板那样的五子棋棋盘的制作。作为界面设计,透明棋盘的制作很简单,用绘图软件做一幅图片游戏时重新载入图片就可刷新棋盘。而此例示范的是怎样在底图上绘出透明棋盘。方法也很简单,就是在绘制棋盘时画笔的颜色设置时alpha通道值调低些,SetColor(a,r,g,b),a是alpha,rgb是三原色它们的取值都在0-55之间,a=255不透明,a=100就可显示透明色了。
对于悔棋的设置,个人认为没必要,下棋讲究落子无悔,这是好的棋品。为了摆谱研究战术和AI智能博弈算法,在游戏程序中设置了复盘功能。程序没退出就能复现出上一次的盘面。另外还加了记录功能和显示下子序号,每盘棋都打印黑白双方下子记录,界面上也显示记录。有一点就是程序退出记录也就没了。解决的方法是把记录存为文本文件,需要时可作为复盘数据。也可以采用截屏方法保存棋局图片,以便以后复盘研究。
人机模式是设计AI智能奕棋的算法,主要是检测算法,测试算法的可行性。程序设置的对战演示就是为了测试算法,此为研究五子棋算法提供一些参考。
以下是源码,有较详细的注释。
//****************************************
//* 五子棋 Gobang AI V.2.5.6
//* 人机对战 双人对奕 对战演示
//* 编制人:张纯叔 micelu@126.com
//* myspringc v2.7 编译
//****************************************
Canvas cs; //画布
string sBarDes[10]; //按钮
int nBarId[10];
string sMenu[50]; //菜单
int nMenu[50];
float src[4]; //ClearDraw (cls) clear screen
string s1,s2,s3,s4,s5,s6,s7,s8 ; //显示
string s,ss,ss1,ss2,ss3,ss4;
int dx,dy; //draw X, Y
FileInput filebox; //file Input box加底图
int size[2]; //load picture size
string fname; //filename
int i,j,t,a; //t = times
int pn[225]; // pn 0=" " , 1=black , 2=white
int n; // 225 棋子编码号
int px,py; // piece x,y
int context; //canvasProc 触控
int obj;
int id;
int event;
int dn,dn1 ; //下子计数
int isDo; //游戏操作控制 1=可下子,0=不可下
int B,W,k; //detect win Black White
string cordp,cordp1; //record pn & G9
int cord; //record switch
int mode; //0=人人,1=人机
int wn;
int sn;
int dwn[120]; //记录,下子60回合120子为和棋
int col,row ;
int cn,kn; //show record num
int gn ; //game round number
int fudat[200]; //复盘数据
int fusum; //复盘记录总数
int sd; //复盘
int jqn[225]; //计权数
int jqf,jqfn ; //计权分,优选点位码
int js[225]; //禁手设置
int jsset ; //s8 show restrict mark
//**********
main(){
setDisplay(1);
cs.SetBackground(200,200,200);
cs.Active();
sBarDes[0]="开始游戏";
nBarId[0]=100;
sBarDes[1]="选择模式";
nBarId[1]=101;
sBarDes[2]="黑棋下子";
nBarId[2]=102;
sBarDes[3]="白棋下子";
nBarId[3]=103;
sBarDes[4]="退出程序";
nBarId[4]=104;
sBarDes[5]="记录v";
nBarId[5]=105;
setToolBarHeight(6);
setButtonTextSize(13);
setToolBarBackgroundColor(255,250,250,250);
setButtonColor(255,220,220,220);
setButtonTextColor(255,0,0,150);
setToolBar(100,myToolBarProc,sBarDes,nBarId,6);
sMenu[0]="开始游戏";
nMenu[0]=200;
sMenu[1]="选择模式 ( 双人 , 人机 )";
nMenu[1]=201;
sMenu[2]="悔棋";
nMenu[2]=202;
sMenu[3]="复盘";
nMenu[3]=203;
sMenu[4]="禁手设置 ( 有 , 无 )";
nMenu[4]=204;
sMenu[5]="查看记录";
nMenu[5]=205;
sMenu[6]="显示棋板";
nMenu[6]=206;
sMenu[7]="退出";
nMenu[7]=207;
setMenu(200,myMenuProc,sMenu,nMenu,8);
setTitle("五子棋 (AI智能版) V.2.5.6 ");
//*************************
cs.SetProc (context, mycanvasProc);
mode=0 ;
s7="游戏模式:双人对奕";
wn=0 ; //测试演示
gn=0; //round number
jsset= 0 ; s8="无禁手" ;
gamestart (); //游戏初始界面
//draw title ****
ss3="五子棋 (AI智能版)";
cs.SetTextSize (60);
cs.SetTextStyle (1);
cs.SetFillMode (1);//0不填色,1填色
cs.SetColor(255,160,60,40);
cs.DrawText (ss3,105,505);
cs.SetColor(255,0,250,0);
cs.DrawText (ss3,100,500);
cs.SetFillMode (0);//0不填色,1填色
cs.SetColor(255,250,250,0);
//cs.DrawText (ss3,100,500);
cs.DrawText (ss3,101,501);
cs.Update();
while (){}
}//main ()
mycanvasProc (int context,int obj,int id,int event,float x,float y){
if (isDo==0) return ; //结束标志
kn=kn+1; //延时, 减少闪屏
if ((kn-kn/2*2)==0){ kn=0; }else{ return; }
board (); //redraw board
//** get chess pieces position X , Y
if (x>40&&x<610&&y>40&&y<610){
px=(int)(x/40)*40; //棋盘区棋位取整数
py=(int)(y/40)*40;
s=intToString (px);
s1= "px = "+s;
s=intToString (py);
s2= "py = "+s;
dx=px/40; dy=py/40;
s=intToString (dx);
s3= "dx = "+s;
s=intToString (dy);
s4= "dy = "+s;
cs.SetFillMode (0);//0不填色,1填色
cs.SetColor (255,250,0,0); //chess flag选子标记
cs.DrawRect (px-20,py-20,px+20,py+20);
}
//复盘和悔棋按钮
if (x>40&&x<180&&y>900&&y<960){
replay () ; } //复盘
if (x>210&&x<350&&y>900&&y<960){
undo () ; } //悔棋
if (x>380&&x<520&&y>900&&y<960){
if (mode==0) autotest () ; } //算法测试
cs.SetFillMode (1);//0不填色,1填色
cs.SetColor (255,230,230,230); //clear n
cs.DrawRect (525,760,600,800);
// cs.SetColor(255,255,0,0);
// cs.SetTextSize (24);
//cs.DrawText (s1,50,700); //测试 dx , dy
//cs.DrawText (s2,50,740);
//cs.DrawText (s3,200,700);
//cs.DrawText (s4,200,740);
n=(dy-1)*15+dx; //提示选定棋子pn number
row=15-(n/15) ;
col=(n-(n/15*15)) ;
if (col==0){ col=15 ; row=row+1 ; }
swapabc () ; //col n to abc return ss
s=ss+" "+intToString (row) ;
s5="选定落子位 >> "+s;
if (x<40||x>610||y<40||y>610) s5=" "; //棋盘位越界
cs.SetColor(255,0,0,150);
cs.SetTextSize (30);
cs.DrawText (s5,328,790); //提示选定棋子
cs.Update ();
}//mycanvasProc
//AI智能下子算法求解方案:
//(一) 四连情况,黑棋下子,黑冲四嵌五,白必应子,若白无活四 022220 冲四 22220 02222 和嵌五 22022 22202 20222 则必应,有则先着取胜
//(二) 三连情况,黑棋下子,黑成活三嵌四,
// 若白无活三 02220 嵌四 2022 2202 则必应,
// 有则先着下子成活四
//(三) 二连情况,黑棋下子,
// 有活二 01100 嵌三 01010 基本都是这样,
// 二连应子:抢先手原则,白棋先找自己的活二嵌三
// 先下子成活三嵌四
//(四) 开局应首子,定标黑子 pn113,白应首子
// 大多棋 谱是 应上 pn98,上右 pn99,暂定此
// 白应起首三子:按棋谱法
//黑白双方博弈,加权计分,黑攻方进攻点就是白守方
//防守点。计分累加标记此点,乃此算法要点。
//将下面 testAIq ()算法分二部分,来测试一下
autotest (){
//用于检测AI智能下子算法 testAIq ()
//黑白棋用同一个算法下子很难区分算法的优劣,
//要设计二种算法分别以黑棋VS白棋才能显示出
//算法的优劣。下面代码只可检测算法的可行性。
s7="游戏模式:对战演示";
if (isDo==0||dn>120) return ; //结束标志,测试120子
if (mode==1) return ; //双人模式可演示
wn=wn+1 ;
if (dn==0) { //设定首子黑先天元位
n=113; black_do () ;
n=82 ; wn=0 ; //变换n 加以检测
white_do () ;
cs.Update () ; }
testAIq () ; //智能计权取得下子点位
if (wn>1) wn=0 ; //轮流下子
if (wn==1) white_do () ; //白棋下子
if (wn==0) black_do () ; //黑棋下子
detect () ; //判胜负
}//autotest ()
restrict_set (){ //禁手设置选择
jsset=jsset+1 ;
if (jsset>1) jsset=0 ;
if (jsset==0) s8="无禁手" ;
if (jsset==1) s8="有禁手" ;
board () ;
}//restrict_set()
restrict_move (){ //禁手设置
//黑棋禁手,加权计算查找
for (i=1;i<=225;i++) {
js[i]=0 ; } //scan init
//三三禁手,01010 此情况中间为可成三三的交点
//此点记100,若有两个三三,此点就计分200,
//即禁手点位,黑棋若下子即可判负
for (i=1;i<=15;i++){ //遍历scan 黑子
for (j=1;j<=15;j++){
k=(i-1)*15+j ; //pn(n) number
//三三禁手形 0 0 1 010 0, k前后 0位计权
//两边为空中间可成活三,有子是假活三
if (pn[k]==1){ // scan B (k)
if (pn[k-1]==0&&pn[k+1]==0&&pn[k+2]==1&&pn[k+3]==0){
if ( pn[k-2]==0) js[k-1]= js[k-1]+100 ;
if (pn[k+4]==0) js[k+3]= js[k+3]+100 ;
if ( pn[k-2]==0&&pn[k+4]==0) {
js[k+1]= js[k+1]+100 ; } }//左右
if (pn[k-15]==0&&pn[k+15]==0&&pn[k+30]==1&&pn[k+45]==0){
if ( pn[k-30]==0) js[k-15]= js[k-15]+100 ;
if (pn[k+60]==0) js[k+45]= js[k+45]+100 ;
if ( pn[k-30]==0&&pn[k+60]==0) {
js[k+15]= js[k+15]+100 ; } }//上下
if (pn[k-14]==0&&pn[k+14]==0&&pn[k+28]==1&&pn[k+42]==0){
if ( pn[k-28]==0) js[k-14]= js[k-14]+100 ;
if (pn[k+56]==0) js[k+42]= js[k+42]+100 ;
if ( pn[k-28]==0&&pn[k+42]==0) {
js[k+14]= js[k+14]+100 ; } }//斜左
if (pn[k-16]==0&&pn[k+16]==0&&pn[k+32]==1&&pn[k+48]==0){
if ( pn[k-32]==0) js[k-16]= js[k-16]+100 ;
if (pn[k+64]==0) js[k+48]= js[k+48]+100 ;
if ( pn[k-32]==0&&pn[k+64]==0) {
js[k+16]= js[k+16]+100 ; } }//右斜
} //00 1 0100
//禁手形 00 1 100 , k前后 0位计权
if (pn[k]==1){ //scan B (k)
if (pn[k-1]==0&&pn[k+1]==1&&pn[k+2]==0){
if (pn[k-2]==0) js[k-2]= js[k-2]+100 ;
if (pn[k-2]==0) js[k-1]= js[k-1]+100 ; //**
js[k+2]= js[k+2]+100 ;
if (pn[k+3]==0) js[k+3]= js[k+3]+100 ; } //左右
if (pn[k-15]==0&&pn[k+15]==1&&pn[k+30]==0){
if (pn[k-30]==0) js[k-30]= js[k-30]+100 ;
if (pn[k-30]==0) js[k-15]= js[k-15]+100 ;
js[k+30]= js[k+30]+100 ;
if (pn[k+45]==0) js[k+45]= js[k+45]+100 ; } //上下
if (pn[k-14]==0&&pn[k+14]==1&&pn[k+28]==0){
if (pn[k-28]==0) js[k-28]= js[k-28]+100 ;
if (pn[k-28]==0) js[k-14]= js[k-14]+100 ;
if (j<12) js[k+28]= js[k+28]+100 ;
if (pn[k+42]==0) js[k+42]= js[k+42]+100 ; } //斜左
if (pn[k-16]==0&&pn[k+16]==1&&pn[k+32]==0){
if (pn[k-32]==0) js[k-32]= js[k-32]+100 ;
if (pn[k-32]==0) js[k-16]= js[k-16]+100 ;
js[k+32]= js[k+32]+100 ;
if (pn[k+48]==0) js[k+48]= js[k+48]+100 ; } //右斜
} //00 1 100
//禁手形 0 1 0010 , 中间 0位计权
if (pn[k]==1){ //scan B (k)
if (pn[k-1]==0&&pn[k+1]==0&&pn[k+2]==0&&pn[k+3]==1&&pn[k+4]==0){
js[k+1]= js[k+1]+100 ;
js[k+2]= js[k+2]+100 ; } //左右
if (pn[k-15]==0&&pn[k+15]==0&&pn[k+30]==0&&pn[k+45]==1&&pn[k+60]==0){
js[k+15]= js[k+15]+100 ;
js[k+30]= js[k+30]+100 ; } //上下
if (pn[k-14]==0&&pn[k+14]==0&&pn[k+28]==0&&pn[k+42]==1&&pn[k+56]==0){
js[k+14]= js[k+14]+100 ;
js[k+28]= js[k+28]+100 ; } //斜左
if (pn[k-16]==0&&pn[k+16]==0&&pn[k+32]==0&&pn[k+48]==1&&pn[k+64]==0){
js[k+16]= js[k+16]+100 ;
js[k+32]= js[k+32]+100 ; } //右斜
} //010010
//四四禁手算法同三三禁手
//四四禁手形 0 1 110 , 前后 0 位计权
if (pn[k]==1){ //scan B (k)
if (pn[k+1]==1&&pn[k+2]==1){
if (pn[k-2]==0&&pn[k-1]==0) js[k-1]= js[k-1]+100 ;
if (pn[k+3]==0&&pn[k+4]==0)js[k+3]= js[k+3]+100 ;
} //左右
if (pn[k+15]==1&&pn[k+30]==1){
if(pn[k-30]==0&&pn[k-15]==0) js[k-15]=js[k-15]+100 ;
if (pn[k+45]==0&&pn[k+60]==0)js[k+45]= js[k+45]+100 ;
} //上下
if (pn[k-14]==0&&pn[k+14]==1&&pn[k+28]==1&&pn[k+42]==0){
if (pn[k-28]==0) js[k-14]= js[k-14]+100 ;
if (pn[k+56]==0)js[k+42]= js[k+42]+100 ;
if (pn[k+56]==0)js[k+56]= js[k+56]+100 ; } //斜左
if (pn[k-16]==0&&pn[k+16]==1&&pn[k+32]==1&&pn[k+48]==0){
if (pn[k-32]==0) js[k-16]= js[k-16]+100 ;
if (pn[k+64]==0)js[k+48]= js[k+48]+100 ;
if (pn[k+64]==0)js[k+64]= js[k+64]+100 ; } //右斜
} //01110
//四四禁手形 0 1 1010 , 0 1 0110 前后 0 位计权
if (pn[k]==1){ //scan B (k)
if (pn[k-1]==0&&pn[k+1]==0&&pn[k+3]==1&&pn[k+4]==0){
if (pn[k+1]==0&&pn[k+2]==1)js[k+1]= js[k+1]+100 ;
if (pn[k+1]==1&&pn[k+2]==0)js[k+2]= js[k+2]+100 ;
} //左右
if (pn[k-15]==0&&pn[k+15]==0&&pn[k+45]==1&&pn[k+60]==0){
if (pn[k+15]==0&&pn[k+30]==1)js[k+15]= js[k+15]+100 ;
if (pn[k+15]==1&&pn[k+30]==0)js[k+30]= js[k+30]+100 ;
} //上下
if (pn[k-14]==0&&pn[k+14]==0&&pn[k+42]==1&&pn[k+56]==0){
if (pn[k+14]==0&&pn[k+28]==1)js[k+14]= js[k+14]+100 ;
if (pn[k+14]==1&&pn[k+28]==0)js[k+28]= js[k+28]+100 ;
} //斜左
if (pn[k-16]==0&&pn[k+16]==0&&pn[k+48]==1&&pn[k+64]==0){
if (pn[k+16]==0&&pn[k+32]==1)js[k+16]= js[k+16]+100 ;
if (pn[k+16]==1&&pn[k+32]==0)js[k+32]= js[k+32]+100 ;
} //右斜
} //0 1 1010 0 1 0110
//禁手的基本设置就这样,其他有些特殊的情况暂不
//设置,AI完整智能版需全设置。上述设置是个示例。
//长连禁手设置:在判胜负函数 detect () 时
// 黑棋超过五连即判黑负,白棋胜。
} }//scan i , j
//**********
cs.SetTextSize (16);
cs.SetTextStyle (0);
for (i=1;i<=225;i++){ //test restrict_move
if (js[i] !=0) { //Mark it
s=intToString ( js[i]) ;
dx=(i-(i/15*15))*40;
dy=(i/15)*40+40;
if (dx==0){ dx=15*40; dy=dy-40; }
cs.SetColor (255,250,250,0) ;
cs.DrawCircle (dx,dy,3) ; //draw mark
if (js[i]>100){
cs.SetColor (255,180,0,180) ;
// cs.DrawText (s,dx-15,dy) ; //put js(i)
cs.DrawCircle (dx,dy,5) ; //draw mark
}
} }
cs.Update () ;
}//restrict_move ()
testAIq (){
//人机对战AI选子,加权计算
for (i=1;i<=225;i++) {
jqn[i]=0 ; } //scan init
//遍历加权
for (i=1;i<=15;i++){ //遍历scan B & W 子
for (j=1;j<=15;j++){
k=(i-1)*15+j ; //pn(n) number
//独子 左右上下 二对角 八方
if (pn[k]==2){
if (pn[k-1]==0) jqn[k-1]= jqn[k-1]+20 ;
if (pn[k+1]==0) jqn[k+1]= jqn[k+1]+20 ;
if (pn[k-15]==0) jqn[k-15]= jqn[k-15]+20 ;
if (pn[k+15]==0) jqn[k+15]= jqn[k+15]+20 ;
if (pn[k+14]==0) jqn[k+14]= jqn[k+14]+20 ;
if (pn[k+16]==0) jqn[k+16]= jqn[k+16]+20 ;
if (pn[k-14]==0) jqn[k-14]= jqn[k-14]+20 ;
if (pn[k-16]==0) jqn[k-16]= jqn[k-16]+20 ;
}//pn
//连二
if (pn[k]==2&&pn[k+1]==2){ //左右
if (pn[k-1]==0) jqn[k-1]= jqn[k-1]+520 ;
if (pn[k+2]==0) jqn[k+2]= jqn[k+2]+520 ; }
if (pn[k]==2&&pn[k+15]==2){ //上下
if (pn[k-15]==0) jqn[k-15]= jqn[k-15]+520 ;
if (pn[k+30]==0) jqn[k+30]= jqn[k+30]+520 ; }
if (pn[k]==2&&pn[k+14]==2){ //左对角
if (pn[k-14]==0) jqn[k-14]= jqn[k-14]+520 ;
if (pn[k+28]==0) jqn[k+28]= jqn[k+28]+520 ; }
if (pn[k]==2&&pn[k+16]==2){ //右对角
if (pn[k-16]==0) jqn[k-16]= jqn[k-16]+520 ;
if (pn[k+32]==0) jqn[k+32]= jqn[k+32]+520 ; }
//嵌三 02020 +1020 为活三冲四进攻点
if (pn[k]==2&&pn[k+1]==0&&pn[k+2]==2){ //左右
jqn[k+1]= jqn[k+1]+520 ;
if (pn[k-1]==0) jqn[k-1]= jqn[k-1]+1020 ;
if (pn[k+3]==0) jqn[k+3]= jqn[k+3]+1020 ; }
if (pn[k]==2&&pn[k+15]==0&&pn[k+30]==2){ //上下
jqn[k+15]= jqn[k+15]+520 ;
if (pn[k-15]==0) jqn[k-15]= jqn[k-15]+1020 ;
if (pn[k+45]==0) jqn[k+45]= jqn[k+45]+1020 ; }
if (pn[k]==2&&pn[k-14]==0&&pn[k-28]==2){//左对角
jqn[k-14]= jqn[k-14]+520 ;
if (pn[k+14]==0) jqn[k+14]= jqn[k+14]+1020 ;
if (pn[k-42]==0) jqn[k-42]= jqn[k-42]+1020 ; }
if (pn[k]==2&&pn[k+16]==0&&pn[k+32]==2){//右对角
jqn[k+16]= jqn[k+16]+520 ;
if (pn[k-16]==0) jqn[k-16]= jqn[k-16]+1020 ;
if (pn[k+48]==0) jqn[k+48]= jqn[k+48]+1020 ; }
//三连,眠三抢冲四 12220 02221
if (pn[k]==2&&pn[k+1]==2&&pn[k+2]==2){ //左右
if (pn[k-1]==0) jqn[k-1]= jqn[k-1]+2320 ;
if (pn[k+3]==0) jqn[k+3]= jqn[k+3]+2320 ; }
if (pn[k]==2&&pn[k+15]==2&&pn[k+30]==2){ //上下
if (pn[k-15]==0) jqn[k-15]= jqn[k-15]+2320 ;
if (pn[k+45]==0) jqn[k+45]= jqn[k+45]+2320 ; }
if (pn[k]==2&&pn[k-14]==2&&pn[k-28]==2){//左对角
if (pn[k+14]==0) jqn[k+14]= jqn[k+14]+2320 ;
if (pn[k-42]==0) jqn[k-42]= jqn[k-42]+2320 ; }
if (pn[k]==2&&pn[k+16]==2&&pn[k+32]==2){//右对角
if (pn[k-16]==0) jqn[k-16]= jqn[k-16]+2320 ;
if (pn[k+48]==0) jqn[k+48]= jqn[k+48]+2320 ; }
//三连,活三变活四,必杀 0022200 +2000
if ( pn[k-2]==0&&pn[k-1]==0&&pn[k]==2&&pn[k+1]==2&&pn[k+2]==2&&pn[k+3]==0&&pn[k+4]==0){ //左右
jqn[k-1]= jqn[k-1]+3500 ;
jqn[k+3]= jqn[k+3]+3500 ; }
if (pn[k-30]==0&&pn[k-15]==0&&pn[k]==2&&pn[k+15]==2&&pn[k+30]==2&&pn[k+45]==0&&pn[k+60]==0){ //上下
jqn[k-15]= jqn[k-15]+3500 ;
jqn[k+45]= jqn[k+45]+3500 ; }
if(pn[k-28]==0&&pn[k-14]==0&&pn[k]==2&&pn[k+14]==2&&pn[k+28]==2&&pn[k+42]==0&&pn[k+56]==0){//左对角
jqn[k-14]= jqn[k-14]+3500 ;
jqn[k+42]= jqn[k+42]+3500 ; }
if (pn[k-32]==0&&pn[k-16]==0&&pn[k]==2&&pn[k+16]==2&&pn[k+32]==2&&pn[k+48]==0&&pn[k+64]==0){//右对角
jqn[k-16]= jqn[k-16]+3500 ;
jqn[k+48]= jqn[k+48]+3500 ; }
//*********
//白子算杀,做杀,找活三嵌四交点 +2500
//嵌四类 做冲四 2022 2202 布杀点 +1800
// 120220 122020 020221 022021
if (j<12){
if (pn[k]==2&&pn[k+1]==0&&pn[k+2]==2&&pn[k+3]==2){ //左右
if (pn[k-1]==0||pn[k+4]==0){ jqn[k+1]= jqn[k+1]+1800 ; } }
if (pn[k]==2&&pn[k+1]==2&&pn[k+2]==0&&pn[k+3]==2){ //左右
if (pn[k-1]==0||pn[k+4]==0){ jqn[k+2]= jqn[k+2]+1800 ; } }
} //j<12
if (i<12){
if (pn[k]==2&&pn[k+15]==0&&pn[k+30]==2&&pn[k+45]==2){ //上下
if (pn[k-15]==0||pn[k+60]==0){ jqn[k+15]= jqn[k+15]+1800 ; } }
if (pn[k]==2&&pn[k+15]==2&&pn[k+30]==0&&pn[k+45]==2){ //上下
if (pn[k-15]==0||pn[k+60]==0){ jqn[k+30]= jqn[k+30]+1800 ; } }
} //i<12
if(j>4&&i<12){
if (pn[k]==2&&pn[k+14]==0&&pn[k+28]==2&&pn[k+42]==2){ //斜左
if (pn[k-14]==0||pn[k+56]==0){ jqn[k+14]= jqn[k+14]+1800 ; } }
if (pn[k]==2&&pn[k+14]==2&&pn[k+28]==0&&pn[k+42]==2){ //斜左
if (pn[k-14]==0||pn[k+56]==0){jqn[k+28]= jqn[k+28]+1800 ; } }
} //j>4, i<12
if (j<12&&i<12){
if (pn[k]==2&&pn[k+16]==0&&pn[k+32]==2&&pn[k+48]==2){ //右斜
if (pn[k-16]==0||pn[k+64]==0){ jqn[k+16]= jqn[k+16]+1800 ; } }
if (pn[k]==2&&pn[k+16]==2&&pn[k+32]==0&&pn[k+48]==2){ //右斜
if (pn[k-16]==0||pn[k+64]==0){ jqn[k+32]= jqn[k+32]+1800 ; } }
} //i<12&&j<12
//嵌四 020220 022020 必杀点+3500 j<12 防越界
if (j<12){
if ( pn[k-1]==0&&pn[k]==2&&pn[k+1]==0&&pn[k+2]==2&&pn[k+3]==2&&pn[k+4]==0){ //左右
jqn[k+1]= jqn[k+1]+3500 ; }
if ( pn[k-1]==0&&pn[k]==2&&pn[k+1]==2&&pn[k+2]==0&&pn[k+3]==2&&pn[k+4]==0){ //左右
jqn[k+2]= jqn[k+2]+3500 ; } }
if (i<12){
if ( pn[k-15]==0&&pn[k]==2&&pn[k+15]==0&&pn[k+30]==2&&pn[k+45]==2&&pn[k+60]==0){ //上下
jqn[k+15]= jqn[k+15]+3500 ; }
if ( pn[k-15]==0&&pn[k]==2&&pn[k+15]==2&&pn[k+30]==0&&pn[k+45]==2&&pn[k+60]==0){ //上下
jqn[k+30]= jqn[k+30]+3500 ; } }
if (j>4&&i<12){
if ( pn[k-14]==0&&pn[k]==2&&pn[k+14]==0&&pn[k+28]==2&&pn[k+42]==2&&pn[k+56]==0){ //斜左
jqn[k+14]= jqn[k+14]+3500 ; }
if ( pn[k-14]==0&&pn[k]==2&&pn[k+14]==2&&pn[k+28]==0&&pn[k+42]==2&&pn[k+56]==0){ //斜左
jqn[k+28]= jqn[k+28]+3500 ; } }
if (j<12&&i<12){
if ( pn[k-16]==0&&pn[k]==2&&pn[k+16]==0&&pn[k+32]==2&&pn[k+48]==2&&pn[k+64]==0){ //右斜
jqn[k+16]= jqn[k+16]+3500 ; }
if ( pn[k-16]==0&&pn[k]==2&&pn[k+16]==2&&pn[k+32]==0&&pn[k+48]==2&&pn[k+64]==0){ //右斜
jqn[k+32]= jqn[k+32]+3500 ; } }
//活四冲四 022220 122220 022221
//此是必杀点 +9000 j<12 防越界
if (pn[k]==2&&pn[k+1]==2&&pn[k+2]==2&&pn[k+3]==2){ //左右
if (j>1&&pn[k-1]==0) jqn[k-1]= jqn[k-1]+9000 ;
if (j<12&&pn[k+4]==0) jqn[k+4]= jqn[k+4]+9000 ; }
if (pn[k]==2&&pn[k+15]==2&&pn[k+30]==2&&pn[k+45]==2){ //上下
if (i>1&&pn[k-15]==0) jqn[k-15]= jqn[k-15]+9000 ;
if (i<12&&pn[k+60]==0) jqn[k+60]= jqn[k+60]+9000 ; }
if(pn[k]==2&&pn[k+14]==2&&pn[k+28]==2&&pn[k+42]==2){//左对角
if (i>4&&j<14&&pn[k-14]==0) jqn[k-14]= jqn[k-14]+9000 ;
if (i<12&&j>4&&pn[k+56]==0) jqn[k+56]= jqn[k+56]+9000 ; }
if (pn[k]==2&&pn[k+16]==2&&pn[k+32]==2&&pn[k+48]==2){//右对角
if (j>1&&i<12&&pn[k-16]==0) jqn[k-16]= jqn[k-16]+9000 ;
if (j<12&&i<12&&pn[k+64]==0) jqn[k+64]= jqn[k+64]+9000 ; }
//嵌五,此是必杀点 20222 22022 22202 +9000
if (j<12){ // j<12 防越界
if ( pn[k]==2&&pn[k+1]==0&&pn[k+2]==2&&pn[k+3]==2&&pn[k+4]==2){ //左右 20222
jqn[k+1]= jqn[k+1]+9000 ; }
if ( pn[k]==2&&pn[k+1]==2&&pn[k+2]==0&&pn[k+3]==2&&pn[k+4]==2){ //左右 22022
jqn[k+2]= jqn[k+2]+9000 ; }
if ( pn[k]==2&&pn[k+1]==2&&pn[k+2]==2&&pn[k+3]==0&&pn[k+4]==2){ //左右 22202
jqn[k+3]= jqn[k+3]+9000 ; } } //j<12
if (i<12){
if ( pn[k]==2&&pn[k+15]==0&&pn[k+30]==2&&pn[k+45]==2&&pn[k+60]==2){ //上下 20222
jqn[k+15]= jqn[k+15]+9000 ; }
if ( pn[k]==2&&pn[k+15]==2&&pn[k+30]==0&&pn[k+45]==2&&pn[k+60]==2){ //上下 22022
jqn[k+30]= jqn[k+30]+9000 ; }
if ( pn[k]==2&&pn[k+15]==2&&pn[k+30]==2&&pn[k+45]==0&&pn[k+60]==2){ //上下 22202
jqn[k+45]= jqn[k+45]+9000 ; } } //i<12
if (j>4&&i<12){
if ( pn[k]==2&&pn[k+14]==0&&pn[k+28]==2&&pn[k+42]==2&&pn[k+56]==2){ //斜左 20222
jqn[k+14]= jqn[k+14]+9000 ; }
if ( pn[k]==2&&pn[k+14]==2&&pn[k+28]==0&&pn[k+42]==2&&pn[k+56]==2){ //斜左 22022
jqn[k+28]= jqn[k+28]+9000 ; }
if ( pn[k]==2&&pn[k+14]==2&&pn[k+28]==2&&pn[k+42]==0&&pn[k+56]==2){ //斜左 22202
jqn[k+42]= jqn[k+42]+9000 ; } }
if (j<12&&i<12){
if ( pn[k]==2&&pn[k+16]==0&&pn[k+32]==2&&pn[k+48]==2&&pn[k+64]==2){ //右斜 20222
jqn[k+16]= jqn[k+16]+9000 ; }
if ( pn[k]==2&&pn[k+16]==2&&pn[k+32]==0&&pn[k+48]==2&&pn[k+64]==2){ //右斜 22022
jqn[k+32]= jqn[k+32]+9000 ; }
if ( pn[k]==2&&pn[k+16]==2&&pn[k+32]==2&&pn[k+48]==0&&pn[k+64]==2){ //右斜 22202
jqn[k+48]= jqn[k+48]+9000 ; } }
//****************************
//以下是黑棋估权计分
//独子 左右上下 二对角 八方
if (pn[k]==1){
if (pn[k-1]==0) jqn[k-1]= jqn[k-1]+20 ;
if (pn[k+1]==0) jqn[k+1]= jqn[k+1]+20 ;
if (pn[k-15]==0) jqn[k-15]= jqn[k-15]+20 ;
if (pn[k+15]==0) jqn[k+15]= jqn[k+15]+20 ;
if (pn[k+14]==0) jqn[k+14]= jqn[k+14]+20 ;
if (pn[k+16]==0) jqn[k+16]= jqn[k+16]+20 ;
if (pn[k-14]==0) jqn[k-14]= jqn[k-14]+20 ;
if (pn[k-16]==0) jqn[k-16]= jqn[k-16]+20 ;
}//pn
//连二
if (pn[k]==1&&pn[k+1]==1){ //左右
if (pn[k-1]==0) jqn[k-1]= jqn[k-1]+500 ;
if (pn[k+2]==0) jqn[k+2]= jqn[k+2]+500 ; }
if (pn[k]==1&&pn[k+15]==1){ //上下
if (pn[k-15]==0) jqn[k-15]= jqn[k-15]+500 ;
if (pn[k+30]==0) jqn[k+30]= jqn[k+30]+500 ; }
if (pn[k]==1&&pn[k+14]==1){ //左对角
if (pn[k-14]==0) jqn[k-14]= jqn[k-14]+500 ;
if (pn[k+28]==0) jqn[k+28]= jqn[k+28]+500 ; }
if (pn[k]==1&&pn[k+16]==1){ //右对角
if (pn[k-16]==0) jqn[k-16]= jqn[k-16]+500 ;
if (pn[k+32]==0) jqn[k+32]= jqn[k+32]+500 ; }
//嵌三 02020
if (pn[k]==1&&pn[k+1]==0&&pn[k+2]==1){ //左右
jqn[k+1]= jqn[k+1]+500 ; }
if (pn[k]==1&&pn[k+15]==0&&pn[k+30]==1){ //上下
jqn[k+15]= jqn[k+15]+500 ; }
if (pn[k]==1&&pn[k+14]==0&&pn[k+28]==1){//左对角
jqn[k+14]= jqn[k+14]+500 ; }
if (pn[k]==1&&pn[k+16]==0&&pn[k+32]==1){//右对角
jqn[k+16]= jqn[k+16]+500 ; }
//三连,眠三12220 02221 逢三必堵
if (pn[k]==1&&pn[k+1]==1&&pn[k+2]==1){ //左右
if (pn[k-1]==0) jqn[k-1]= jqn[k-1]+3000 ;
if (pn[k+3]==0) jqn[k+3]= jqn[k+3]+3000 ; }
if (pn[k]==1&&pn[k+15]==1&&pn[k+30]==1){ //上下
if (pn[k-15]==0) jqn[k-15]= jqn[k-15]+3000 ;
if (pn[k+45]==0) jqn[k+45]= jqn[k+45]+3000 ; }
if (pn[k]==1&&pn[k-14]==1&&pn[k-28]==1){//左对角
if (pn[k+14]==0) jqn[k+14]= jqn[k+14]+3000 ;
if (pn[k-42]==0) jqn[k-42]= jqn[k-42]+3000 ;
if (pn[k+2]==0) jqn[k+2]= jqn[k+2]+3050 ;
if (pn[k-30]==0) jqn[k-30]= jqn[k-30]+3050 ;
} //破梅花阵
if (pn[k]==1&&pn[k+16]==1&&pn[k+32]==1){//右对角
if (pn[k-16]==0) jqn[k-16]= jqn[k-16]+3000 ;
if (pn[k+48]==0) jqn[k+48]= jqn[k+48]+3000 ;
if (pn[k+2]==0) jqn[k+2]= jqn[k+2]+3050 ;
if (pn[k+30]==0) jqn[k+30]= jqn[k+30]+3050 ;
} //破梅花阵
//三连,活三 01110 逢三必堵
if ( pn[k-1]==0&&pn[k]==1&&pn[k+1]==1&&pn[k+2]==1&&pn[k+3]==0){ //左右
if (pn[k-1]==0) jqn[k-1]= jqn[k-1]+3300 ;
if (pn[k+3]==0) jqn[k+3]= jqn[k+3]+3300 ; }
if (pn[k-15]==0&&pn[k]==1&&pn[k+15]==1&&pn[k+30]==1&&pn[k+45]==0){ //上下
if (pn[k-15]==0) jqn[k-15]= jqn[k-15]+3300 ;
if (pn[k+45]==0) jqn[k+45]= jqn[k+45]+3300 ; }
if (pn[k-14]==0&&pn[k]==1&&pn[k+14]==1&&pn[k+28]==1&&pn[k+42]==0){//左对角
if (pn[k-14]==0) jqn[k-14]= jqn[k-14]+3300 ;
if (pn[k+42]==0) jqn[k+42]= jqn[k+42]+3300 ; }
if (pn[k-16]==0&&pn[k]==1&&pn[k+16]==1&&pn[k+32]==1&&pn[k+48]==0){//右对角
if (pn[k-16]==0) jqn[k-16]= jqn[k-16]+3300 ;
if (pn[k+48]==0) jqn[k+48]= jqn[k+48]+3300 ; }
//嵌四 010110 011010 必杀点 +3500
if ( pn[k-1]==0&&pn[k]==1&&pn[k+1]==0&&pn[k+2]==1&&pn[k+3]==1&&pn[k+4]==0){ //左右
jqn[k+1]= jqn[k+1]+3500 ; }
if ( pn[k-1]==0&&pn[k]==1&&pn[k+1]==1&&pn[k+2]==0&&pn[k+3]==1&&pn[k+4]==0){ //左右
jqn[k+2]= jqn[k+2]+3500 ; }
if ( pn[k-15]==0&&pn[k]==1&&pn[k+15]==0&&pn[k+30]==1&&pn[k+45]==1&&pn[k+60]==0){ //上下
jqn[k+15]= jqn[k+15]+3500 ; }
if ( pn[k-15]==0&&pn[k]==1&&pn[k+15]==1&&pn[k+30]==0&&pn[k+45]==1&&pn[k+60]==0){ //上下
jqn[k+30]= jqn[k+30]+3500 ; }
if ( pn[k-14]==0&&pn[k]==1&&pn[k+14]==0&&pn[k+28]==1&&pn[k+42]==1&&pn[k+56]==0){ //斜左
jqn[k+14]= jqn[k+14]+3500 ; }
if ( pn[k-14]==0&&pn[k]==1&&pn[k+14]==1&&pn[k+28]==0&&pn[k+42]==1&&pn[k+56]==0){ //斜左
jqn[k+28]= jqn[k+28]+3500 ; }
if ( pn[k-16]==0&&pn[k]==1&&pn[k+16]==0&&pn[k+32]==1&&pn[k+48]==1&&pn[k+64]==0){ //右斜
jqn[k+16]= jqn[k+16]+3500 ; }
if ( pn[k-16]==0&&pn[k]==1&&pn[k+16]==1&&pn[k+32]==0&&pn[k+48]==1&&pn[k+64]==0){ //右斜
jqn[k+32]= jqn[k+32]+3500 ; }
//活四冲四 此是必杀点 211110 011112 +6000
//黑有此白必堵,此是必杀点 如白无连五则必应
if ( pn[k]==1&&pn[k+1]==1&&pn[k+2]==1&&pn[k+3]==1){ //左右
if (pn[k-1]==0) jqn[k-1]= jqn[k-1]+7000 ;
if (pn[k+4]==0) jqn[k+4]= jqn[k+4]+7000 ; }
if (pn[k]==1&&pn[k+15]==1&&pn[k+30]==1&&pn[k+45]==1){ //上下
if (pn[k-15]==0) jqn[k-15]= jqn[k-15]+7000 ;
if (pn[k+60]==0) jqn[k+60]= jqn[k+60]+7000 ; }
if(pn[k]==1&&pn[k-14]==1&&pn[k-28]==1&&pn[k-42]==1){//左对角
if (pn[k+14]==0) jqn[k+14]= jqn[k+14]+7000 ;
if (pn[k-56]==0) jqn[k-56]= jqn[k-56]+7000 ; }
if (pn[k]==1&&pn[k+16]==1&&pn[k+32]==1&&pn[k+48]==1){//右对角
if (pn[k-16]==0) jqn[k-16]= jqn[k-16]+7000 ;
if (pn[k+64]==0) jqn[k+64]= jqn[k+64]+7000 ; }
//嵌五 10111 11011 11101 +6000
//此是必杀点 如白无连五则必应
if ( pn[k]==1&&pn[k+1]==0&&pn[k+2]==1&&pn[k+3]==1&&pn[k+4]==1){ //左右 10111
jqn[k+1]= jqn[k+1]+7000 ; }
if ( pn[k]==1&&pn[k+1]==1&&pn[k+2]==0&&pn[k+3]==1&&pn[k+4]==1){ //左右 11011
jqn[k+2]= jqn[k+2]+7000 ; }
if ( pn[k]==1&&pn[k+1]==1&&pn[k+2]==1&&pn[k+3]==0&&pn[k+4]==1){ //左右 11101
jqn[k+3]= jqn[k+3]+7000 ; }
if ( pn[k]==1&&pn[k+15]==0&&pn[k+30]==1&&pn[k+45]==1&&pn[k+60]==1){ //上下 10111
jqn[k+15]= jqn[k+15]+7000 ; }
if ( pn[k]==1&&pn[k+15]==1&&pn[k+30]==0&&pn[k+45]==1&&pn[k+60]==1){ //上下 11011
jqn[k+30]= jqn[k+30]+7000 ; }
if ( pn[k]==1&&pn[k+15]==1&&pn[k+30]==1&&pn[k+45]==0&&pn[k+60]==1){ //上下 11101
jqn[k+45]= jqn[k+45]+7000 ; }
if ( pn[k]==1&&pn[k+14]==0&&pn[k+28]==1&&pn[k+42]==1&&pn[k+56]==1){ //斜左 10111
jqn[k+14]= jqn[k+14]+7000 ; }
if ( pn[k]==1&&pn[k+14]==1&&pn[k+28]==0&&pn[k+42]==1&&pn[k+56]==1){ //斜左 11011
jqn[k+28]= jqn[k+28]+7000 ; }
if ( pn[k]==1&&pn[k+14]==1&&pn[k+28]==1&&pn[k+42]==0&&pn[k+56]==1){ //斜左 11101
jqn[k+42]= jqn[k+42]+7000 ; }
if ( pn[k]==1&&pn[k+16]==0&&pn[k+32]==1&&pn[k+48]==1&&pn[k+64]==1){ //右斜 10111
jqn[k+16]= jqn[k+16]+7000 ; }
if ( pn[k]==1&&pn[k+16]==1&&pn[k+32]==0&&pn[k+48]==1&&pn[k+64]==1){ //右斜 11011
jqn[k+32]= jqn[k+32]+7000 ; }
if ( pn[k]==1&&pn[k+16]==1&&pn[k+32]==1&&pn[k+48]==0&&pn[k+64]==1){ //右斜 11101
jqn[k+48]= jqn[k+48]+7000 ; }
} } //test i , j pn(225) 棋盘点位
//******************************
//测试:显示加权计分情况,最高分白下子
if (isDo==0) return ;
cs.SetTextSize (16);
cs.SetTextStyle (0);
cs.SetColor (255,0,150,0) ;
for (i=1;i<=225;i++){ //test scan
if (jqn[i] !=0) {
//print i," qn= ",jqn[i] ; //测试
s=intToString ( jqn[i]) ;
dx=(i-(i/15*15))*40;
dy=(i/15)*40+40;
if (dx==0){ dx=15*40; dy=dy-40; }
cs.DrawText (s,dx,dy) ; //draw jqn(i)
} }
//计算最高分
jqf=0 ;
for (i=1;i<=225;i++){
k= jqn[i] ;
if ( k>jqf) { jqf=k ; jqfn=i ; }
} //计算最高分
sn=jqfn ; //计权最高分点位转坐标
if (dn==1) {
if (gn==1) sn=98 ;
if (gn==2) sn=97 ;
if (gn==3) sn=99 ; }
// print " sn= ",jqfn ," jqf= ",jqf ;
dx=(sn-(sn/15*15))*40;
dy=(sn/15)*40+40;
if (dx==0) {dx=15*40; dy=dy-40; }
cs.SetColor (255,250,250,0);
cs.DrawCircle (dx,dy,5); //标记下子点
cs.Update () ;
// sleep (500) ;
n=sn ; //下子点号sn转换为n, draw board
px=dx ; py=dy ; //board ()标记下子点
//**** AI 走子 **********************
}//testAIq ()
swapabc (){ //传入col , 输出 ss = "ABC"
string abc$ ;
abc$="sABCDEFGHIJKLMNO" ;
ss=subString (abc$,col,1) ;
}//swapabc ()
black_do (){ //黑棋下子
pn[n]=1;
s6="白棋选子";
row=15-(n/15) ;
col=(n-(n/15*15)) ;
if (col==0){ col=15 ; row=row+1 ; }
swapabc () ; //return ss
cordp=" B "+intToString (n); //走子记录
cordp1=" B "+ss+intToString (row) ;
if (cordp != ss2) { //不重复记录
dn=dn+1; //print dn;
print dn," ",cordp," " , ss,row ; //打印记录
ss2=cordp;
dwn[dn]=n ; //print play number
fudat[dn]=n; fusum=dn; //复盘数据
board ();
}
testAIq (); //test AI 计权白子点位下子 **
if (mode==1) { //人机模式下子
white_do () ; } // AI Do 白下子
}//black_do ()
white_do (){ //白棋下子
if (isDo==0) return ;
pn[n]=2;
s6="黑棋选子";
row=15-(n/15) ;
col=(n-(n/15*15)) ;
if (col==0){ col=15 ; row=row+1 ; }
swapabc () ; //return ss
cordp=" W "+intToString (n); //走子记录
cordp1="W "+ss+intToString (row) ;
if (cordp != ss2) {
dn=dn+1;
print dn," ",cordp," " , ss,row ; //打印记录
ss2=cordp;
dwn[dn]=n ; //print play number
fudat[dn]=n; fusum=dn; //复盘数据
board () ;
}
if (jsset==1) restrict_move () ; //禁手设置
//scan restricted move and draw mark
}//white_do ()
board (){
if (isDo==0) return ; //结束标志
fname="/storage/emulated/0/go01.jpg";
cs.DrawBitmap(fname,0,0); //加底图
//** draw board grids 棋盘方格
cs.SetFillMode (1);//0不填色,1填色
cs.SetColor (155,0,0,0); //底板底线
cs.DrawRect(634,13,638,633);
cs.DrawRect(13,632,638,636);
cs.SetColor (85,220,150,50); //pad棋板
cs.DrawRect (8,8,636,632);
cs.SetColor (85,250,180,100); //pad棋板
// cs.DrawRect (20,20,620,620);
cs.SetFillMode (0);//0不填色,1填色
for (i=1;i<15;i++){ //draw grids棋盘格
for (j=1;j<15;j++){
cs.SetColor (255,150,150,150); //grid 格线
cs.DrawRect(i*40-1,j*40-1,i*40+39,j*40+39);
cs.SetColor (255,250,250,250); //grid
cs.DrawRect(i*40,j*40,i*40+40,j*40+40);
} } //格线
cs.SetColor (255,0,0,0); // rectangle line
cs.DrawRect (8,8,634,632);
cs.DrawRect (21,21,620,620);
cs.DrawRect (20,20,620,620);
//draw flag points
cs.SetFillMode (1);//0不填色,1填色
cs.SetColor (255,140,140,140);
cs.DrawCircle(160,160,5); //星
cs.DrawCircle(480,160,5);
cs.DrawCircle(160,480,5);
cs.DrawCircle(480,480,5);
cs.DrawCircle(320,320,5); //中元
cs.SetColor (255,240,240,240);
cs.DrawCircle(161,161,5); //星
cs.DrawCircle(481,161,5);
cs.DrawCircle(161,481,5);
cs.DrawCircle(481,481,5);
cs.DrawCircle(321,321,5); //中元
// 绘出棋盘坐标编码 1-15 , A-O
cs.SetColor (255,100,40,20);
cs.SetTextStyle (1);
cs.SetTextSize (14);
string abc$ ;
abc$="sABCDEFGHIJKLMNO" ;
a=0 ; //set print tab
for (i=1;i<=15;i++){
ss1=intToString (i) ;
if (i>9) a=4 ; //tab for print number
cs.DrawText (ss1,25-a,645-i*40) ;
ss=subString (abc$,i,1) ;
cs.DrawText (ss,i*40-4,615) ; }
//draw button 绘制按钮
cs.SetColor (125,50,150,150);
cs.DrawRect (40,900,181,961);
cs.DrawRect (210,900,351,961);
cs.DrawRect (380,900,521,961);
for (i=1;i<60;i++){ //按钮渐变色
cs.SetColor (125,250-i*4,250-i*3,250-i*3);
cs.DrawLine (41,900+i,180,900+i);
cs.DrawLine (211,900+i,350,900+i);
cs.DrawLine (381,900+i,520,900+i);
}
cs.SetColor(255,255,250,0);
cs.SetTextStyle (1);
cs.SetTextSize (32);
cs.DrawText ("复 盘",72,940);
cs.DrawText ("悔 棋",242,940);
cs.DrawText ("演 示",412,940);
//print title
cs.SetTextSize (80);
cs.SetTextStyle (1);
cs.SetColor (150,50,50,50);
cs.DrawText ("五子棋",50,793);
cs.DrawText ("Gobang",50,873);
cs.SetColor (155,240,160,110);
cs.DrawText ("五子棋",52,790);
cs.DrawText ("Gobang",52,870);
s="编制人:张纯叔 ( micelu@126.com ) " ;
cs.SetTextSize (24);
cs.DrawText (s, 40, 990);
for (i=1;i<=225;i++){
//draw chess pieces 画出已下黑白子
dx=(i-(i/15*15))*40;
dy=(i/15)*40+40;
if (dx==0){ dx=15*40; dy=dy-40; }
if ( pn[i]==2){ //white
cs.SetColor (255,140,80,40); //piecesW
cs.DrawCircle(dx+2,dy+2,17);
cs.SetColor (255,220,220,220); //pieceW
cs.DrawCircle(dx,dy,17);
cs.SetColor (255,250,250,250); //pieceW
cs.DrawCircle(dx-6,dy-6,2); }
if (pn[i]==1){ //black
cs.SetColor (255,220,100,40); //piecesB
cs.DrawCircle(dx+1,dy+1,17);
cs.SetColor (255,0,0,0); //pieceB
cs.DrawCircle(dx,dy,17);
cs.SetColor (255,200,200,200); //pieceB
cs.DrawCircle(dx-6,dy-6,2); }
} //draw chess pieces
cs.SetColor (255,240,0,0); //刚落子标记
cs.DrawCircle(px,py,5);
//提示选子
cs.SetTextSize (42);
cs.SetColor(55,255,0,0);
cs.DrawRect (390,670,600,740);
cs.SetColor(255,255,60,180);
cs.DrawText (s6,415,720); //pn(n) num
cs.SetTextSize (36);
if (mode==0) cs.SetColor(255,255,60,180);
if (mode==1) cs.SetColor(255,100,200,0);
cs.DrawText (s7,20,680); //模式
cs.SetTextSize (26);
cs.SetColor(255,250,80,120);
cs.DrawText (s8,600,720); //restrict禁手
//draw pieces number 画出下子序号*****
for (i=1;i<=dn;i++){
// cn=i ;
s=intToString(i) ;
kn=dwn[i] ;
dx=(kn-(kn/15*15))*40;
dy=(kn/15)*40+40;
if (dx==0){ dx=15*40; dy=dy-40; }
cs.SetTextSize (16);
cs.SetColor (255,0,160,0);
cs.DrawText (s,dx-5,dy+5);
//界面显示记录
n=fudat[i] ;
row=15-(n/15) ;
col=(n-(n/15*15)) ;
if (col==0){ col=15 ; row=row+1 ; }
swapabc () ; //return ss
if ((i-i/2*2)==0) {s="W " ; }else{s=" B " ; }
ss1=s+ss+intToString (row) ;
cs.SetTextStyle (0);
cs.SetTextSize (18);
cs.SetColor(255,0,0,150);
if(ss1==" B O16") ss1="悔棋" ;
cs.DrawText (ss1,655,i*16); //record _G8
}
cs.Update ();
detect (); //检测胜负
}//board ()
detect (){ //检测胜负
//detect Black chess 判胜 ******
for (i=1;i<16;i++){ // B 黑子
for (j=1;j<12;j++){
k=(i-1)*15+j ; //pn(B) number
if (pn[k]==1){
if ( pn[k+1]==1&&pn[k+2]==1&&pn[k+3]==1&&pn[k+4]==1){
if (pn[k+5]==1) pn[k]=2 ; //超五连,禁手白胜
goto showwin ; } //右
} } }
for (i=1;i<12;i++){ // B 黑子
for (j=1;j<16;j++){
k=(i-1)*15+j ; //pn(B) number
if (pn[k]==1){
if ( pn[k+15]==1&&pn[k+30]==1&&pn[k+45]==1&&pn[k+60]==1){
if (pn[k+75]==1) pn[k]=2 ; //超五连,禁手白胜
goto showwin ; } //下
} } }
for (i=1;i<12;i++){ // B 黑子
for (j=1;j<12;j++){
k=(i-1)*15+j ; //pn(B) number
if (pn[k]==1){
if ( pn[k+16]==1&&pn[k+32]==1&&pn[k+48]==1&&pn[k+64]==1){
if (pn[k+80]==1) pn[k]=2 ; //超五连,禁手白胜
goto showwin ; } //右斜
} } }
for (i=1;i<12;i++){ // B 黑子
for (j=5;j<16;j++){
k=(i-1)*15+j ; //pn(B) number
if (pn[k]==1){
if ( pn[k+14]==1&&pn[k+28]==1&&pn[k+42]==1&&pn[k+56]==1){
if (pn[k+70]==1) pn[k]=2 ; //超五连,禁手白胜
goto showwin ; } //斜左
} } }
//********************************
//detect White chess 判胜 ******
for (i=1;i<16;i++){ // W 白子
for (j=1;j<12;j++){
k=(i-1)*15+j ; //pn(W) number
if (pn[k]==2){
if ( pn[k+1]==2&&pn[k+2]==2&&pn[k+3]==2&&pn[k+4]==2){ goto showwin ; } //右
} } }
for (i=1;i<12;i++){ // W 白子
for (j=1;j<16;j++){
k=(i-1)*15+j ; //pn(W) number
if (pn[k]==2){
if ( pn[k+15]==2&&pn[k+30]==2&&pn[k+45]==2&&pn[k+60]==2){ goto showwin ; } //下
} } }
for (i=1;i<12;i++){ // W 白子
for (j=1;j<12;j++){
k=(i-1)*15+j ; //pn(W) number
if (pn[k]==2){
if ( pn[k+16]==2&&pn[k+32]==2&&pn[k+48]==2&&pn[k+64]==2){ goto showwin ; } //右斜
} } }
for (i=1;i<12;i++){ // W 白子
for (j=5;j<16;j++){
k=(i-1)*15+j ; //pn(W) number
if (pn[k]==2){
if ( pn[k+14]==2&&pn[k+28]==2&&pn[k+42]==2&&pn[k+56]==2){ goto showwin ; } //斜左
} } }
//*****************************
if (pn[n]==1&&js[n]==200){ //禁手,判白棋胜
ss="白棋胜 !"; goto heqi; }
if (dn>120) {
ss="( 和 棋 )"; goto heqi; }
return;
//** show win flag 判胜负
showwin:
cs.SetTextStyle (0);
cs.SetTextSize (16);
cs.SetColor(255,255,0,0);
if (pn[k]==1) {
ss="黑棋胜 !"; print ss;
cs.DrawText (ss,655,(dn+2)*16); }
if (pn[k]==2) {
ss="白棋胜 !"; print ss;
cs.DrawText (ss,655,(dn+2)*16); }
isDo=0; //结束标志
heqi: //和棋 drawngame
cs.SetTextSize (60);
cs.SetTextStyle (1);
cs.SetFillMode (1);//0不填色,1填色
cs.SetColor(255,180,90,40);
cs.DrawText (ss,214,544);
cs.SetColor(255,255,0,0);
cs.DrawText (ss,210,540);
cs.SetFillMode (0);//0不填色,1填色
cs.SetColor(255,250,250,0);
cs.DrawText (ss,210,540);
print ss ;
cs.Update ();
isDo=0; //结束标志
}//detect ()
gamestart (){ //开始游戏
setDisplay (1);
cord=1 ; //记录开关
for (i=1;i<=225;i++){ pn[i]=0; } //init pn (n)下子位
for (i=0;i<=120;i++){ dwn[i]=0; } //init dwn (n)复盘
for (i=1;i<=225;i++){ js[i]=0 ; } //init js (n)禁手
isDo=1; //游戏操作控制
s6="黑棋选子"; //init
px=320 ; py=320 ; //标记
dn=0; wn=0 ; n=0 ; //计数清零
gn=gn+1; //game round + 1
clearOutput(); //清除记录
fname="/storage/emulated/0/go02.jpg";
cs.DrawBitmap(fname,0,0); //加底图
board (); //绘出棋板
}//gamestart ()
undo(){ //悔棋设置
if (isDo==1) {
pn[n]=0; fudat[dn]=0;
print "悔 "+intToString (n);
cs.SetTextStyle (0);
cs.SetTextSize (16);
cs.SetColor(255,250,0,0);
cs.DrawText ("悔",655,dn*16);
dn=dn-1 ; //序号减 1
if (dn<1) dn=0 ;
cs.Update ();
board (); }
}//undo ()
replay (){ //复盘
gamestart ( );
setDisplay (1);
print "fusum= " ,fusum;
for (i=1;i<=fusum;i++){
//draw chess pieces 画出复盘黑子白子
kn=fudat[i] ; //取得数据
sd=i-i/2*2 ; //mod 0=白棋, 1=黑棋
dx=(kn-(kn/15*15))*40;
dy=(kn/15)*40+40;
if (dx==0){ dx=15*40; dy=dy-40; }
if ( sd==0){ //white
ss=intToString (kn);
cordp=" W "+ss;
row=15-(kn/15) ;
col=(kn-(kn/15*15)) ;
swapabc () ;
print i," ",cordp," " , ss,row ; //打印记录
ss4="W "+ss+intToString (row) ;
cs.SetColor (255,140,80,40); //piecesW
cs.DrawCircle(dx+2,dy+2,17);
cs.SetColor (255,220,220,220); //pieceW
cs.DrawCircle(dx,dy,17);
cs.SetColor (255,250,250,250); //pieceW
cs.DrawCircle(dx-6,dy-6,2); }
if ( sd==1){ //black
ss=intToString (kn);
cordp=" B "+ss;
row=15-(kn/15) ;
col=(kn-(kn/15*15)) ;
swapabc () ;
print i," ",cordp," " , ss,row ; //打印记录
ss4=" B "+ss+intToString (row) ;
cs.SetColor (255,220,100,40); //piecesB
cs.DrawCircle(dx+1,dy+1,17);
cs.SetColor (255,0,0,0); //pieceB
cs.DrawCircle(dx,dy,17);
cs.SetColor (255,200,200,200); //pieceB
cs.DrawCircle(dx-6,dy-6,2); }
if (i==fusum){
cs.SetColor (255,0,250,0); //标志最末胜子点
cs.DrawCircle(dx,dy,5);
cs.SetTextStyle (1);
cs.SetTextSize (60);
cs.SetFillMode (1);//0不填色,1填色
cs.SetColor (255,160,70,40);
cs.DrawText ("复 盘",253, 553) ;
cs.SetColor (255,250,250,0);
cs.DrawText ("复 盘",250, 550) ;
cs.SetFillMode (0);//0不填色,1填色
cs.SetColor (255,50,250,0);
cs.DrawText ("复 盘",250, 550) ;
if ( sd==0) print "白棋胜 ! " ;
if ( sd==1) print "黑棋胜 ! " ;
} //=fusum
cs.SetFillMode (1);//0不填色,1填色
cs.SetTextStyle (0);
cs.SetTextSize (16);
s=intToString (i); //标记序号
cs.SetColor (255,250,0,0);
cs.DrawText (s,dx-2,dy+5);
//界面显示记录
cs.SetTextSize (18);
cs.SetColor(255,150,0,0);
cs.DrawText (ss4,655,i*16); //界面显示记录
cs.Update ();
sleep (1000);
} //draw replay chess pieces
isDo=0 ; //结束标志
}//replay ()
myToolBarProc(int nBtn,int nContext)
{
if(nBtn==100){//开始游戏
gamestart ();
}
if(nBtn==101){//选择模式
mode=mode+1; //0=人人, 1= 人机
if (mode>1) mode=0 ;
if (mode==0) s7="游戏模式:双人对弈 ";
if (mode==1) s7="游戏模式:人机模式 ";
gamestart ();
}
if(nBtn==102){//黑棋下子
if ( pn[n]==0) black_do() ;
}
if(nBtn==103){//白棋下子,双人对弈模式
if (mode==0&&pn[n]==0) white_do () ;
}
if(nBtn==104){//退出程序
clearOutput();
cs.ClearDraw (0,src);
setDisplay (0);
exit (0);
}
if(nBtn==105){//查看记录
cord=cord+1;
if (cord>1) cord=0 ;
if (cord==0) setDisplay (0); //查看记录
if (cord==1) setDisplay (1); //显示棋板
}
}//myToolBar ()
myMenuProc(int nMen,int nContext)
{
if(nMen==200){ //开始游戏
gamestart (); }
if(nMen==201){ //选择模式
mode=mode+1; //0=人人, 1= 人机
if (mode>1) mode=0 ;
if (mode==0) s7="游戏模式:双人对弈 ";
if (mode==1) s7="游戏模式:人机模式 ";
gamestart ();
}
if(nMen==202){ //悔棋
undo ();
}
if (nMen==203){ //复盘
replay ();
}
if (nMen==204){ //禁手设置
restrict_set () ;
}
if(nMen==205){ //查看记录
setDisplay (0);
}
if(nMen==206){ //显示棋板
setDisplay (1);
}
if (nMen==207){ //Exit
clearOutput();
cs.ClearDraw (0,src);
setDisplay (0);
exit (0);
}
}//myMenu()
loadpic (){ //用于装载预设棋盘底图
//use filebox open files and load a picture
filebox.SetTitle("装载图片(*.bmp;*.jpg;*.png)");
filebox.SetFilter(".bmp;.jpg;.png");
filebox.Show();
if(filebox.GetCount()==1){
fname=filebox.GetFileName(0);
if(getPicSize(fname,size)<0){ return; }
cs.ClearDraw (0,src);
cs.DrawBitmap(fname,0,0);
cs.Update (); }
}//loadpic ()
//**** End ********
相关文章:

五子棋透明棋盘界面设计(C语言)
五子棋透明棋盘设计,漂亮的界面制作。程序设置双人对奕,人机模式,对战演示三种模式。设置悔棋,记录功能,有禁手设置。另有复盘功能设置。 本文主要介绍透明的玻璃板那样的五子棋棋盘的制作。作为界面设计,…...

Redis第六讲 Redis之List底层数据结构实现
List数据结构 List是一个有序(按加入的时序排序)的数据结构,Redis采用quicklist(双端链表) 和 ziplist 作为List的底层实现。可以通过设置每个ziplist的最大容量,quicklist的数据压缩范围,提升数据存取效率 list-max-ziplist-size -2 // 单个ziplist节点最大能存储 8kb ,…...

电子学会2023年3月青少年软件编程python等级考试试卷(四级)真题,含答案解析
目录 一、单选题(共25题,共50分) 二、判断题(共10题,共20分) 三、编程题(共3题,共30分)...

【MATLAB】一篇文章带你了解beatxbx工具箱使用
目录 一篇文章带你了解beatxbx工具箱使用 一篇文章带你了解beatxbx工具箱使用 clc;clear; tic; % step1 初始化 % 个体数量 NIND = 35; % 最大遗传代数 MAXGEN = 180; % 变量的维数 NVAR = 2; % 变量的二进制位数 % 上下界 bounds=[-10 10-10 10]; precision=0.0001; %运算精度…...

【LinuxC Sqlite数据库小项目】基于Sqlite的打卡系统------适合初学者练手的小项目
最近小哥老是想浪,不想好好学习,这不行啊,得想点办法,多少做点努力,于是就自己给自己写了个打卡程序; 该程序基于Sqlite数据库,实现一个简单的打卡功能,该函数具有自动初始化的功能…...

在掌握C#基础上再学习C语言
C#和C语言虽然名字相似,但它们在很多方面都有很大的区别。 首先,C#是一种面向对象的语言,而C语言是过程化的语言。这意味着C#具有更丰富的语言特性,如类、接口、继承和多态性等,而C语言则更侧重于直接对计算机硬件进行…...

HTML5 <body> 标签
HTML <body> 标签 实例 一个简单的 HTML 文档,包含尽可能少的必需的标签: <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>文档标题</title> </head><body> 文档内容…...

(链表)反转链表
文章目录前言:问题描述:解题思路:代码实现:总结:前言: 此篇是针对链表的经典练习。 问题描述: 给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1…...

deb文件如何安装到iphone方法分享
Cydia或同类APT管理软件在线安装 Cydia或同类APT管理软件在线安装,这个是最佳的安装方式,因为通常无需考虑依赖关系,但缺点是对网络的要求比较高;命令行中以dpkg-iXXX.deb的形式安装,好处是可以以通配符一次性安装多个deb,而且也可以直接看到脚本的运行状况和安装成功/失…...

mongodb和mysql双写数据一致性问题
文章目录 我们是如何用MongoDB的如何保证双写一致性?先写数据库,再写MongoDB先写MongoDB,再写数据库用户修改操作如何保存数据如何清理新增的垃圾数据定时删除随机删除我们是如何用MongoDB的 MongoDB是一个高可用、分布式的文档数据库,用于大容量数据存储。文档存储一般用…...

Databend 开源周报第 88 期
Databend 是一款现代云数仓。专为弹性和高效设计,为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务:https://app.databend.com 。 Whats On In Databend 探索 Databend 本周新进展,遇到更贴近你心意的 Databend 。 Support Eager…...

Vue3学习笔记(9.4)
Vue3自定义指令 除了默认设置的核心指令(v-model和v-show),Vue也允许注册自定义指令。 下面我们注册一个全局指令v-focus,该指令的功能是在页面加载时,元素获得焦点: <!--* Author: RealRoad10834252…...

导入 Excel 文件时,抛出 413 (Request Entity Too Large) 错误
Excel文件大小:8MB 异常信息:413 (Request Entity Too Large) 环境:IIS10PHP7.2.33 依次检查如下几项: 一、php.ini Maximum amount of memory a script may consume (128MB) 限制代码消耗的最大内存,默认128…...

Verilog学习笔记1——关键词、运算符、数据类型、function/task、initial/always、generate
文章目录前言一、关键词二、运算符三、数据类型1、基本类型:reg、wire、integer、parameter四、条件语句五、循环语句1、for2、generate六、function和task七、initial和always1、initial和always相同点和区别2、always和assign语句区别前言 2023.4.4 2023.4.7 补充…...

探索LeetCode【0005】最长回文子串(未搞懂,未练习)
目录0、题目1、第一个官方答案1.1 动态规划(未懂)1.2 中心扩展(已懂)1.3 Manacher(未懂)2、第二个参考答案2.1 暴力求法(已懂)2.2 反转法(未懂)2.3 动态规划&…...

使用 Docker run 命令简化容器化
使用 Docker run 命令简化容器化 Docker run 是在 Docker 容器中运行应用程序的基本命令。在开始使用 Docker 之前,了解一些重要的命令非常重要。 在本博客中,我们将解释 Docker run 命令的基本语法,并探索其一些最常见的选项,以…...

腾讯TNN神经网络推理框架手动实现多设备单算子卷积推理
文章目录前言1. 简介2. 快速开始2.1 onnx转tnn2.2 编译目标平台的 TNN 引擎2.3 使用编译好的 TNN 引擎进行推理3. 手动实现单算子卷积推理(浮点)4. 代码解析4.1 构建模型(单卷积层)4.2 构建解释器4.3 初始化tnn5. 模型量化5.1 编译量化工具5.2 量化scale的计算5.3 量化流程6. i…...

基础解惑:Linux 下文件描述符标志和文件状态标志区别
简述 文件描述符标志,是体现进程的文件描述符的状态,fork进程时,文件描述符被复制;目前只有一种文件描述符:FD_CLOEXEC文件状态标志,是体现进程打开文件的一些标志,fork时不会复制file 结构&am…...

学弟:如何在3个月内学会自动化测试?
有小学弟问:如何在3个月内学会自动化测试? 老实说如果你现在上班,之前主要在做功能测试,或者编程基础比较弱的话,三个月够呛。 如果你是脱产学习,每天能保持6~8小时学习时间的话,可…...

C-NCAP 2025主动安全ADAS测试研究
中汽中心汽车测评管理中心(简称“中汽测评”)是负责运营C-NCAP、CCRT等测评项目的管理机构。中汽测评以引领汽车行业进步、支撑汽车强国建设为使命,通过独立、公正、专业、开放的测试评价,服务消费者,当好选车购车参谋…...

【Apifox】测试工具自动编写接口文档
在开发过程中,我们总是避免不了进行接口的测试, 而相比手动敲测试代码,使用测试工具进行测试更为便捷,高效 今天发现了一个非常好用的接口测试工具Apifox 相比于Postman,他还拥有一个非常nb的功能, 在接…...

解决brew安装opencv报错问题
目录1.报错12. 解决方案3. 报错24. 解决方案4.1 原因分析4.2 手动下载portable-ruby-2.6.8_1.el_capitan.bottle.tar.gz4.3 拷贝portable-ruby-2.6.8_1.el_capitan.bottle.tar.gz到指定目录1.报错1 mac本用brew报如下错误: xialiangzhideMacBook-Pro:~ xialz$ bre…...

Linux软件安装---Tomcat安装
安装Tomcat 操作步骤: 使用xftp上传工具将tomcat的 二进制发布包上传到Linux解压安装包,命令为tar -zxvf apache-tomcat*** -C /usr/local进入Tomcat的bin的启动目录,命令为sh startup.sh或者./startup.sh 验证Tomcat启动是否成功࿰…...

提示工程师是什么工作?
提示工程师是什么工作? 因为ChatGPT的爆火,大家都把眼光锁定在这个号称“ChatGPT新兴职业” 的“提示工程师”上。“提示工程师”是什么工作?为什么说未来所有职业 都需要提示工程的能力? 先解释一下“提示”,它最早…...

WXSS-WXML-WXS语法
目录: 1 WXSS编写程序样式 2 Mustache语法绑定 3 WXML的条件渲染 4 WXML的列表渲染 5 WXS语法基本使用 6 WXS语法案例练习 小程序的自适应单位rpx。在设计稿为iPhone6的时候1px2rpx wxml必须是闭合标签,或者单标签加/,否则会报错&#…...

POSIX正则表达式
维基百科 POSIX基本表达式 https://en.wikibooks.org/wiki/Regular_Expressions/POSIX_Basic_Regular_Expressions POSIX扩展正则表达式 https://en.wikibooks.org/wiki/Regular_Expressions/POSIX-Extended_Regular_Expressions 正则表达式 https://en.wikipedia.org/wiki/R…...

数据分析工具集合:Tableau入门及其他工具简介
目录 一、Tableau简介 1、下载链接 2、使用技巧 二、其他常用数据分析工具 1、Microsoft Excel简介 1.1、下载链接 1.2、使用技巧 2、Python简介 2.1、下载链接 2.2、常用库的安装方式和使用技巧 2.2.1、Pandas 2.2.2、NumPy 2.2.3、Matplotlib 3、R语言简介 3.…...

响应式布局的五种方法
响应式布局的五种方法1.百分比布局2.rem布局3. 媒体查询 media screen4. flex布局5.vw 和 vh响应式布局是同一页面在不同的屏幕上有不同的布局,即只需要一套代码使页面适应不同的屏幕。 1.百分比布局 1.有父元素就相对于父元素 2.没有父元素就相对于视口的大小 举一…...

Javase学习文档------数组
Java 数组是 Java 编程中非常基础和重要的一个知识点。 以下是 Java 数组的主要学习内容: 数组的几个特点 数组在声明时必须指定长度,且长度不可变:数组的长度在声明时就需要确定,一旦确定就不能修改。因此,在使用数组…...

百度高德地图JS-API学习手记:地图基本设置与省市区数据加载
无论是百度还是高德地图开发,还是高德地图开发。官方的给的案例启示很多,copy再修改下,就完成了 概述-地图 JS API | 高德地图API 地图 JS API | 百度地图API SDK 这个大致看一下,我想。有点GIS基础都能完成地图开发。 个人认…...