五子棋AI智能算法设计和测试方法
先前发了几篇五子棋游戏程序设计的博文,设计了游戏程序,也设计了AI智能奕棋的算法,运行程序检测算法的可行性,完成人机模式游戏功能的设置。这还不够,还要提高算法的实战水平,即算力和应用水平。
对于人机对战的电脑智能应子算法,参阅很多五子棋书籍棋谱和五子棋竞赛的对抗棋谱。我感到白棋的后手防御算法很难取胜,棋界有黑棋高手先手必胜一说。算法么想了很多,既然是人工智能下棋就得按人的思路来算计。棋书阐述有许多思路和棋局解说。如活四冲四,嵌五,活三嵌四,活二嵌二。这些是高级棋手的总结。我就按此思路用加权计权方法来表现此类各种情况。
我对算法的思路是:黑棋的进攻点就是白棋的防守点,反之,白棋的进攻点就是黑棋的防守点。我采用一次遍历棋盘各点位的方法,凡有黑子和白子就判断其四周的空白点,即可下子位,评估棋势加权计分。棋势就是单子、活二嵌二、活三嵌三嵌四、活四冲四嵌五。各个棋势的交点就叠加计分,高分点就是双方博弈的必争点。算法的要点是:独子成二是起点,连二到连三是重点,关键的要点是三连子到四连五连。这这三点就分出权重的棋势。活三02220两边的点位是,先手是绝杀点,后手是防守逢三必堵。眠三122200棋势,空位下子成冲四,这是抢先手来改势扩势来进攻。若抓到冲四加活三叠加进攻点,权分叠加计权,就能绝杀对方。我的算法思路就这样。算法想白棋后手取胜,就在白棋的棋势上加小分,这样利于白棋在同等情况下能争得先手,反战进攻取胜。想法很简单,写算法也不难,而对于棋势的加权分的估量较难。
图例:
人机模式例:人执黑,AI 执白,无禁手则黑棋可胜,有禁手就AI胜。
五子棋博弈要算杀,算杀就是计算必杀之局。必杀局有双活三,双冲四,冲四加活三,嵌五加活三,嵌五加冲四,这些必杀局就是必胜法宝。此算法的要点就是如何加权必杀局棋势的加权分。文后附源码中的testAIq( ),算法至要可见一斑,自己体会一下。
算杀的最高境界是做杀,预判算出必杀点提前几子做出必杀局。此谓奕道高手中的高手,乃高高手也。此种算法也就是编程界的高手,是谓大咖也。我望之有些高仰,自感境界还没到。叠加计权计分有趋向于此类。还要努力,锲而不舍,持之以恒。
另外在设计上加了算法的测试方法。用来检测和改进算法。
测试算法的方法:
一是:程序运行时在黑白落子周边的空位(即可下子位)显示加权计算的分值,查看加权计分情况。最高分点位画出黄色标记点,即AI选取的下子位。
在双人模式时可以直观的看到AI加权计算的分值,以及选取下子位的过程。
在人机模式时由人下黑子检测白棋的防守和进攻情况 。依据此优化和改进算法。
二是:设置自动演示功能autotest(),不需手动模拟对奕过程,连续点击演示按钮逐步显示黑白双方由机器选位下子过程。这就是对战演示功能。
增加26个开局定式对战演示。用以观察加权计分的设置情况,以此来测试和改进算法。也可以每步根据AI计权黄点黑白双方落子位来下子,这样可慢慢地观察加权计分情况。当然在演示功能时可介入手动操作下子,这是方法的灵活应用。
五子棋程序设置双人对奕,人机模式,对战演示三种模式。设置悔棋,记录功能,有禁手设置。另有复盘功能设置。
AI智能奕棋的算法testAIq( ),主要是检测算法,测试算法的可行性。程序设置的对战演示就是为了测试算法,此为研究五子棋算法提供一些参考。
此算法加权偏重于白棋,主要是研究如何对付”黑先必胜”。研究白棋抢先手,拦堵黑棋,反转取胜。
测试了好几个局的例子,白棋的攻防还是可以的。然而如
(例11 例12 例13例15 例16等),
黑棋还是蛮厉害的,如白棋挡不住,就还是黑棋胜。
例4花月局,例7金星局,例8松月局
白棋防守封堵都很漂亮,抢先手反攻取胜,可供参考研究。
例24斜月局,黑棋进攻力度不够,黑21手F8和23手J12失误而失先手,白棋反败为胜。
我测试了26定式局和人机对战的好多局,本文仅例出了一部分。感兴趣的朋友可自己来玩下。此游戏程序可成为喜欢五子棋游戏的练手程序。下面源码可在安卓手机上编译为桌面游戏。
下面是五子棋游戏程序设计的源码:
//****************************************
//* 五子棋 Gobang AI v.3.0.1 (测试版)
//* 人机对战 双人对奕 对战演示
//* 编制人:张纯叔 [email protected]
//* 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,ss9 ;
int dx,dy; //draw X, Y
FileInput filebox; //file Input box加底图
int size[2]; //load picture size
string fname; //filename
int i,j,t ; //t = times
int a,b ; //tab for print
int pn[250]; // pn 0=" " , 1=black , 2=white
int n; // 225 棋子编码号pn(250)容错
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, kn ; //sn AI计权位号 1 to 225
int dwn[120]; //记录,下子60回合120子为和棋
int col,row ;
int gn ; //game round number
int fudat[200]; //复盘数据
int fusum; //复盘记录总数
int sd; //复盘
int jqn[225]; //计权数
int jqf,jqfn ; //计权分,优选点位码
int js[225]; //禁手设置
int jsset ; //0=on 有禁手,1=off 无禁手
double smode ; // 开局模式 26式
int num ; // 开局式号
//**********
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]="选择开局定式 ( 26种定式 )";
nMenu[0]=200;
sMenu[1]="选择游戏模式 ( 双人 , 人机 )";
nMenu[1]=201;
sMenu[2]="悔棋";
nMenu[2]=202;
sMenu[3]="复盘";
nMenu[3]=203;
sMenu[4]="禁手设置 ( on )";
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.3.0.1 ");
//*************************
cs.SetProc (context, mycanvasProc); //触控设置
mode=0 ;
s7="游戏模式:双人对奕";
wn=0 ; //测试演示
gn=0; //round number
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,95,505);
cs.SetColor(255,0,250,0);
cs.DrawText (ss3,90,500);
cs.SetFillMode (0);//0不填色,1填色
cs.SetColor(255,250,250,0);
cs.DrawText (ss3,91,501);
cs.SetFillMode (1);//0不填色,1填色
cs.SetTextSize (36);
cs.SetColor(255,150,50,250);
cs.DrawText ("(测试版)",255,555);
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;
dx=px/40;
dy=py/40;
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.SetTextStyle (0);
cs.SetFillMode (1);//0不填色,1填色
cs.SetColor (255,240,240,240); //clear n
cs.DrawRect (520,760,605,800);
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
autotest (){
//用于检测AI智能下子算法 testAIq ()
//黑白棋用同一个算法下子很难区分算法的优劣,
//要设计二种算法分别以黑棋VS白棋才能显示出
//算法的优劣。下面代码只可检测算法的可行性。
s7="游戏模式:对战演示";
if (isDo==0||dn>75) {
ss9="( 演示 ) "; print ss9;
cs.DrawText (ss9,655,(dn+2)*16);
isDo=0 ; return ; } //结束标志,测试75子
if (mode==1) return ; //双人模式可演示
if (dn==0) { //设定首子黑先天元位
n=113; wn=0 ; black_do () ; }
//注:对战演示模式可按选定的开局定式演示
wn=wn+1 ;
testAIq () ; //智能计权取得下子点位
if (wn>1) wn=0 ; //轮流下子
if (wn==1) white_do () ; //白棋下子
if (wn==0) black_do () ; //黑棋下子
detect () ; //判胜负
}//autotest ()
//AI智能下子算法求解方案:
//(一) 四连情况,黑棋下子,黑冲四嵌五,白必应子,若白无活四 022220 冲四 122220 022221 和嵌五 22022 22202 20222 则必应,有则先着取胜
//* (二) 三连情况,黑棋下子,黑成活三嵌四,若白无活三 02220 嵌四 2022 2202 则必应, 有则先着下子成活四
//(三) 二连情况,黑棋下子,
//有活二01100嵌三01010,010010基本都是这样, 二连应子:抢先手原则,白棋先找自己的活二嵌三 ,先下子成活三嵌四
//(四) 开局应首子,定标黑子 pn113,白应首子, 大多棋谱是 应上(直指) pn98,上右(斜指) pn99,暂定此应起首三子:按棋谱开局法
//*黑白双方博弈,加权计分,黑攻方进攻点就是白守方防守点。叠加加权计分,乃此算法要点。计分累加标记此点,取最高分作为进攻点和防守点。
//下面的 testAIq () 是测试算法。
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+14]==0) jqn[k+14]= jqn[k+14]+20 ;
if (pn[k-16]==0) jqn[k-16]= jqn[k-16]+20 ;
if (pn[k+16]==0) jqn[k+16]= jqn[k+16]+20 ;
}//pn
//二连 002200 为成活三冲四进攻点
if (j>1&&j<13){
if (pn[k]==2&&pn[k+1]==2){ //左右
if (pn[k-1]==0) jqn[k-1]= jqn[k-1]+200 ;
if (pn[k-1]==0&&pn[k-2]==0) { jqn[k-2]= jqn[k-2]+310 ; jqn[k-1]= jqn[k-1]+310 ; }
if (pn[k+2]==0) jqn[k+2]= jqn[k+2]+200 ;
if (pn[k+2]==0&&pn[k+3]==0) { jqn[k+3]= jqn[k+3]+310 ; jqn[k+2]= jqn[k+2]+310 ; }
} }
if (i>1&&i<13){
if (pn[k]==2&&pn[k+15]==2){ //上下
if (pn[k-15]==0) jqn[k-15]= jqn[k-15]+200 ;
if (pn[k-15]==0&&pn[k-30]==0) { jqn[k-30]= jqn[k-30]+310 ; jqn[k-15]= jqn[k-15]+310 ; }
if (pn[k+30]==0) jqn[k+30]= jqn[k+30]+200 ;
if (pn[k+30]==0&&pn[k+45]==0) { jqn[k+45]= jqn[k+45]+310 ; jqn[k+30]= jqn[k+30]+310 ; }
} }
if (i>1&&i<13&&j>3&&j<15){
if (pn[k]==2&&pn[k+14]==2){ //左对角
if (pn[k-14]==0) jqn[k-14]= jqn[k-14]+200 ;
if (pn[k-14]==0&&pn[k-28]==0) { jqn[k-28]= jqn[k-28]+310 ; jqn[k-14]= jqn[k-14]+310 ; }
if (pn[k+28]==0) jqn[k+28]= jqn[k+28]+200 ;
if (pn[k+28]==0&&pn[k+42]==0) { jqn[k+42]= jqn[k+42]+310 ; jqn[k+28]= jqn[k+28]+310 ; }
} }
if (i>1&&i<13&&j>1&&j<13){
if (pn[k]==2&&pn[k+16]==2){ //右对角
if (pn[k-16]==0) jqn[k-16]= jqn[k-16]+200 ;
if (pn[k-16]==0&&pn[k-32]==0) { jqn[k-32]= jqn[k-32]+310 ; jqn[k-16]= jqn[k-16]+310 ; }
if (pn[k+32]==0) jqn[k+32]= jqn[k+32]+200 ;
if (pn[k+32]==0&&pn[k+48]==0) { jqn[k+48]= jqn[k+48]+310 ; jqn[k+32]= jqn[k+32]+310 ; }
} }
//二连 020020
if (j>1&&j<13){
if (pn[k]==2&&pn[k+3]==2){ //左右
if (pn[k-1]==0&&pn[k+1]==0) jqn[k+1]= jqn[k+1]+510 ;
if (pn[k+4]==0&&pn[k+2]==0) jqn[k+2]= jqn[k+2]+510 ; } }
if (i>1&&i<13){
if (pn[k]==2&&pn[k+45]==2){ //上下
if (pn[k-15]==0&&pn[k+15]==0) jqn[k+15]= jqn[k+15]+510 ;
if (pn[k+60]==0&&pn[k+30]==0) jqn[k+30]= jqn[k+30]+510 ; } }
if (i>1&&i<13&&j>3&&j<15){
if (pn[k]==2&&pn[k+42]==2){ //左对角
if (pn[k-14]==0&&pn[k+14]==0) jqn[k+14]= jqn[k+14]+510 ;
if (pn[k+56]==0&&pn[k+28]==0) jqn[k+28]= jqn[k+28]+510 ; } }
if (i>1&&i<13&&j>1&&j<13){
if (pn[k]==2&&pn[k+48]==2){ //右对角
if (pn[k-16]==0&&pn[k+16]==0) jqn[k+16]= jqn[k +16]+510 ;
if (pn[k+64]==0&&pn[k+32]==0) jqn[k+32]= jqn[k+32]+510 ; } }
//嵌三 02020 为成活三冲四进攻点
if (j>1&&j<13){
if (pn[k]==2&&pn[k+1]==0&&pn[k+2]==2){ //左右
jqn[k+1]= jqn[k+1]+510 ;
if (pn[k-1]==0) jqn[k-1]= jqn[k-1]+310 ;
if (pn[k+3]==0) jqn[k+3]= jqn[k+3]+310 ; } }
if (i>1&&i<13){
if (pn[k]==2&&pn[k+15]==0&&pn[k+30]==2){ //上下
jqn[k+15]= jqn[k+15]+510 ;
if (pn[k-15]==0) jqn[k-15]= jqn[k-15]+310 ;
if (pn[k+45]==0) jqn[k+45]= jqn[k+45]+310 ; } }
if (i>1&&i<13&&j>3&&j<15){
if (pn[k]==2&&pn[k+14]==0&&pn[k+28]==2){//左对角
jqn[k+14]= jqn[k+14]+510 ;
if (pn[k-14]==0) jqn[k-14]= jqn[k-14]+310 ;
if (pn[k+42]==0) jqn[k+42]= jqn[k+42]+310 ; } }
if (i>1&&i<13&&j>1&&j<13){
if (pn[k]==2&&pn[k+16]==0&&pn[k+32]==2){//右对角
jqn[k+16]= jqn[k+16]+510 ;
if (pn[k-16]==0) jqn[k-16]= jqn[k-16]+310 ;
if (pn[k+48]==0) jqn[k+48]= jqn[k+48]+310 ; } }
//三连,眠三抢冲四 12220 02221 逢三必堵
if (j>1&&j<13){
if (pn[k]==2&&pn[k+1]==2&&pn[k+2]==2){ //左右
//三连成嵌五 +550 叠加分进攻点
if (pn[k-1]==0) jqn[k-1]= jqn[k-1]+310 ;
if (pn[k-1]==0&&pn[k-2]==0) jqn[k-1]= jqn[k-1]+410 ; //必杀点加权分
if (pn[k-1]==0&&pn[k-2]==0) jqn[k-2]= jqn[k-2]+550 ;
if (pn[k+3]==0) jqn[k+3]= jqn[k+3]+310 ;
if (pn[k+3]==0&&pn[k+4]==0) jqn[k+3]= jqn[k+3]+410 ;
if (pn[k+3]==0&&pn[k+4]==0) jqn[k+4]= jqn[k+4]+550 ; } }
if (i>1&&i<13){
if (pn[k]==2&&pn[k+15]==2&&pn[k+30]==2){ //上下
//三连成嵌五 +550 叠加分进攻点
if (pn[k-15]==0) jqn[k-15]= jqn[k-15]+310 ;
if (pn[k-15]==0&&pn[k-30]==0) jqn[k-15]= jqn[k-15]+410 ;
if (pn[k-15]==0&&pn[k-30]==0) jqn[k-30]= jqn[k-30]+550 ;
if (pn[k+45]==0) jqn[k+45]= jqn[k+45]+310 ;
if (pn[k+45]==0&&pn[k+60]==0) jqn[k+45]= jqn[k+45]+410 ;
if (pn[k+45]==0&&pn[k+60]==0) jqn[k+60]= jqn[k+60]+550 ; } }
if (i>1&&i<13&&j>3&&j<15){
if (pn[k]==2&&pn[k+14]==2&&pn[k+28]==2){//左对角
//三连成嵌五 +550 叠加分进攻点
if (pn[k-14]==0) jqn[k-14]= jqn[k-14]+310 ;
if (pn[k-14]==0&&pn[k-28]==0) jqn[k-14]= jqn[k-14]+410 ;
if (pn[k-14]==0&&pn[k-28]==0) jqn[k-28]= jqn[k-28]+550 ;
if (pn[k+42]==0) jqn[k+42]= jqn[k+42]+310 ;
if (pn[k+42]==0&&pn[k+56]==0) jqn[k+42]= jqn[k+42]+410 ;
if (pn[k+42]==0&&pn[k+56]==0) jqn[k+56]= jqn[k+56]+550 ;
} }
if (i>1&&i<13&&j>1&&j<13){
if (pn[k]==2&&pn[k+16]==2&&pn[k+32]==2){//右对角
//三连成嵌五 +550 叠加分进攻点
if (pn[k-16]==0) jqn[k-16]= jqn[k-16]+310 ;
if (pn[k-16]==0&&pn[k-32]==0) jqn[k-16]= jqn[k-16]+410 ;
if (pn[k-16]==0&&pn[k-32]==0) jqn[k-32]= jqn[k-32]+550 ;
if (pn[k+48]==0) jqn[k+48]= jqn[k+48]+310 ;
if (pn[k+48]==0&&pn[k+64]==0) jqn[k+48]= jqn[k+48]+410 ;
if (pn[k+48]==0&&pn[k+64]==0) jqn[k+64]= jqn[k+64]+550 ; } }
//三连,活三变活四,必杀 0022200 与上叠加
if(pn[k2]==0&&pn[k1]==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]+1350 ;
jqn[k+3]= jqn[k+3]+1350 ; }
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]+1350 ;
jqn[k+45]= jqn[k+45]+1350 ; }
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]+1350 ;
jqn[k+42]= jqn[k+42]+1350 ; }
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]+1350 ;
jqn[k+48]= jqn[k+48]+1350 ; }
//*********
//白子算杀,做杀,找活三嵌四交点 +250
//白棋进攻态势,与二连三连计分叠加抢先手
//嵌四类 做冲四 2022 2202 布杀点 +350
// 120220 122020 020221 022021
if (j>1&&j<13){
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]+350 ; } }
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]+350 ; } }
} //j<12
if (i>1&&i<13){
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]+350 ; } }
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]+350 ; } }
}
if(j>3&&i>1&&i<13){ //行2--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]+350 ; } }
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]+350 ; } }
} //j>4, i<12
if (j>1&&j<13&&i<13){ //列2--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]+350 ; } }
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]+350 ; } }
} //i<12&&j<12
//嵌四 020220 022020 必杀点+350 j<12 防越界
if (j>1&&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]+1350 ; }
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]+1350 ; } }
if (i>1&&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]+1350 ; }
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]+1350 ; } }
if (j>3&&j<15&&i>1&&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]+1350 ; }
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]+1350 ; } }
if (j>1&&j<12&&i>1&&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]+1350 ; }
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]+1350 ; } }
//活四冲四成五连 022220 122220 022221
//此是必杀点 +1990 j<12 防越界
//必杀点黑子 +1200, 白子 +1990 先胜
if (j>1&&j<12){
if (pn[k]==2&&pn[k+1]==2&&pn[k+2]==2&&pn[k
+3]==2){ //左右
if (pn[k-1]==0) jqn[k-1]= jqn[k-1]+1990 ;
if (pn[k+4]==0) jqn[k+4]= jqn[k+4]+1990 ; } }
if (i>1&&i<12){
if (pn[k]==2&&pn[k+15]==2&&pn[k+30]==2&&pn[k+45]==2){ //上下
if (pn[k-15]==0) jqn[k-15]= jqn[k-15]+1990 ;
if (pn[k+60]==0) jqn[k+60]= jqn[k+60]+1990 ; } }
if (j>3&&i>1&&i<12){
if(pn[k]==2&&pn[k+14]==2&&pn[k+28]==2&&pn[k +42]==2){//左对角
if (pn[k-14]==0) jqn[k-14]= jqn[k-14]+1990 ;
if (pn[k+56]==0) jqn[k+56]= jqn[k+56]+1990 ; } }
if (j>1&&j<12&&i>1&&i<12){
if (pn[k]==2&&pn[k+16]==2&&pn[k+32]==2&&pn[k+48]==2){//右对角
if (pn[k-16]==0) jqn[k-16]= jqn[k-16]+1990 ;
if (pn[k+64]==0) jqn[k+64]= jqn[k+64]+1990 ; } }
//嵌五,此是必杀点 20222 22022 22202
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]+1990 ; }
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]+1990 ; }
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]+1990 ; } } //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]+1990 ; }
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]+1990 ; }
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]+1990 ; } } //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]+1990 ; }
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]+1990 ; }
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]+1990 ; } }
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]+1990 ; }
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]+1990 ; }
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]+1990 ; } }
//****************************
//以下是黑棋估权计分
//黑棋进攻点亦即白棋防守点,白下子亦取高分位
//独子 左右上下 二对角 八方
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]+30 ; //直指
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]+30 ; //斜指
if (pn[k-16]==0) jqn[k-16]= jqn[k-16]+20 ;
}//pn
//二连 001100 为成活三冲四进攻点
if (j>1&&j<13){
if (pn[k]==1&&pn[k+1]==1){ //左右
if (pn[k-1]==0) jqn[k-1]= jqn[k-1]+100 ;
if (pn[k-1]==0&&pn[k-2]==0) { jqn[k-2]= jqn[k-2]+200 ; jqn[k-1]= jqn[k-1]+300 ; }
if (pn[k+2]==0) jqn[k+2]= jqn[k+2]+100 ;
if (pn[k+2]==0&&pn[k+3]==0) { jqn[k+3]= jqn[k+3]+200 ; jqn[k+2]= jqn[k+2]+300 ; }
} }
if (i>1&&i<13){
if (pn[k]==1&&pn[k+15]==1){ //上下
if (pn[k-15]==0) jqn[k-15]= jqn[k-15]+100 ;
if (pn[k-15]==0&&pn[k-30]==0) { jqn[k-30]= jqn[k-30]+200 ; jqn[k-15]= jqn[k-15]+300 ; }
if (pn[k+30]==0) jqn[k+30]= jqn[k+30]+100 ;
if (pn[k+30]==0&&pn[k+45]==0) { jqn[k+45]= jqn[k+45]+200 ; jqn[k+30]= jqn[k+30]+300 ; }
} }
if (i>1&&i<13&&j>3&&j<15){
if (pn[k]==1&&pn[k+14]==1){ //左对角
if (pn[k-14]==0) jqn[k-14]= jqn[k-14]+100 ;
if (pn[k-14]==0&&pn[k-28]==0) { jqn[k-28]= jqn[k-28]+200 ; jqn[k-14]= jqn[k-14]+300 ; }
if (pn[k+28]==0) jqn[k+28]= jqn[k+28]+100 ;
if (pn[k+28]==0&&pn[k+42]==0) { jqn[k+42]= jqn[k+42]+200 ; jqn[k+28]= jqn[k+28]+300 ; }
} }
if (i>1&&i<13&&j>1&&j<13){
if (pn[k]==1&&pn[k+16]==1){ //右对角
if (pn[k-16]==0) jqn[k-16]= jqn[k-16]+100 ;
if (pn[k-16]==0&&pn[k-32]==0) { jqn[k-32]= jqn[k-32]+200 ; jqn[k-16]= jqn[k-16]+300 ; }
if (pn[k+32]==0) jqn[k+32]= jqn[k+32]+100 ;
if (pn[k+32]==0&&pn[k+48]==0) { jqn[k+48]= jqn[k+48]+200 ; jqn[k+32]= jqn[k+32]+300 ; }
} }
//连二 010010
if (j>1&&j<13){
if (pn[k]==1&&pn[k+3]==1){ //左右
if (pn[k-1]==0&&pn[k+1]==0) jqn[k+1]= jqn[k+1]+200 ;
if (pn[k+4]==0&&pn[k+2]==0) jqn[k+2]= jqn[k+2]+200 ; } }
if (i>1&&i<13){
if (pn[k]==1&&pn[k+45]==1){ //上下
if (pn[k-15]==0&&pn[k+15]==0) jqn[k+15]= jqn[k+15]+200 ;
if (pn[k+60]==0&&pn[k+30]==0) jqn[k+30]= jqn[k+30]+200 ; } }
if (i>1&&i<13&&j>3&&j<15){
if (pn[k]==1&&pn[k+42]==1){ //左对角
if (pn[k-14]==0&&pn[k+14]==0) jqn[k+14]= jqn[k+14]+200 ;
if (pn[k+56]==0&&pn[k+28]==0) jqn[k+28]= jqn[k+28]+200 ; } }
if (i>1&&i<13&&j>1&&j<13){
if (pn[k]==1&&pn[k+48]==1){ //右对角
if (pn[k-16]==0&&pn[k+16]==0) jqn[k+16]= jqn[k+16]+200 ;
if (pn[k+64]==0&&pn[k+32]==0) jqn[k+32]= jqn[k+32]+200 ; } }
//嵌三 01010 可成双活三
if (j>1&&j<13){
if (pn[k]==1&&pn[k+1]==0&&pn[k+2]==1){ //左右
jqn[k+1]= jqn[k+1]+500 ;
if (pn[k-1]==0) jqn[k-1]= jqn[k-1]+300 ;
if (pn[k+3]==0) jqn[k+3]= jqn[k+3]+300 ; } }
if (i>1&&i<13){
if (pn[k]==1&&pn[k+15]==0&&pn[k+30]==1){ //上下
jqn[k+15]= jqn[k+15]+500 ;
if (pn[k-15]==0) jqn[k-15]= jqn[k-15]+300 ;
if (pn[k+30]==0) jqn[k+30]= jqn[k+30]+300 ; } }
if (i>1&&i<13&&j>3&&j<15){
if (pn[k]==1&&pn[k+14]==0&&pn[k+28]==1){//左对角
jqn[k+14]= jqn[k+14]+500 ;
if (pn[k-14]==0) jqn[k-14]= jqn[k-14]+300 ;
if (pn[k+28]==0) jqn[k+28]= jqn[k+28]+300 ; } }
if (i>1&&i<13&&j>1&&j<13){
if (pn[k]==1&&pn[k+16]==0&&pn[k+32]==1){//右对角
jqn[k+16]= jqn[k+16]+500 ;
if (pn[k-16]==0) jqn[k-16]= jqn[k-16]+300 ;
if (pn[k+32]==0) jqn[k+32]= jqn[k+32]+300 ; } }
//三连,眠三21110 01112 抢冲四
if (j>1&&j<13){
if (pn[k]==1&&pn[k+1]==1&&pn[k+2]==1){ //左右
//三连成嵌五 +550 叠加分进攻点
if (pn[k-1]==0) jqn[k-1]= jqn[k-1]+300 ;
if (pn[k-1]==0&&pn[k-2]==0) jqn[k-1]= jqn[k-1]+400 ; //必杀点加权分
if (pn[k-1]==0&&pn[k-2]==0) jqn[k-2]= jqn[k-2]+550 ;
if (pn[k+3]==0) jqn[k+3]= jqn[k+3]+300 ;
if (pn[k+3]==0&&pn[k+4]==0) jqn[k+3]= jqn[k+3]+400 ;
if (pn[k+3]==0&&pn[k+4]==0) jqn[k+4]= jqn[k+4]+550 ; } }
if (i>1&&i<13){
if (pn[k]==1&&pn[k+15]==1&&pn[k+30]==1){ //上下
//三连成嵌五 +550 叠加分进攻点
if (pn[k-15]==0) jqn[k-15]= jqn[k-15]+300 ;
if (pn[k-15]==0&&pn[k-30]==0) jqn[k-15]= jqn[k-15]+400 ;
if (pn[k-15]==0&&pn[k-30]==0) jqn[k-30]= jqn[k-30]+550 ;
// if (pn[k-15]==2&&pn[k+45]==0) jqn[k+45]= jqn[k+45]-200 ; //眠三可不堵,???
if (pn[k+45]==0) jqn[k+45]= jqn[k+45]+300 ;
if (pn[k+45]==0&&pn[k+60]==0) jqn[k+45]= jqn[k+45]+400 ;
if (pn[k+45]==0&&pn[k+60]==0) jqn[k+60]= jqn[k+60]+550 ;
} }
if (i>1&&i<13&&j>3&&j<15){
if (pn[k]==1&&pn[k+14]==1&&pn[k+28]==1){//斜左
//三连成嵌五 +550 叠加分进攻点
if (pn[k-14]==0) jqn[k-14]= jqn[k-14]+300 ;
if (pn[k-14]==0&&pn[k-28]==0) jqn[k-14]= jqn[k-14]+400 ;
if (pn[k-14]==0&&pn[k-28]==0) jqn[k-28]= jqn[k-28]+550 ;
if (pn[k+42]==0) jqn[k+42]= jqn[k+42]+300 ;
if (pn[k+42]==0&&pn[k+56]==0) jqn[k+42]= jqn[k+42]+400 ;
if (pn[k+42]==0&&pn[k+56]==0) jqn[k+56]= jqn[k+56]+550 ; } }
if (i>1&&i<13&&j>1&&j<13){
if (pn[k]==1&&pn[k+16]==1&&pn[k+32]==1){//右斜
//三连成嵌五 +550 叠加分进攻点
if (pn[k-16]==0) jqn[k-16]= jqn[k-16]+300 ;
if (pn[k-16]==0&&pn[k-32]==0) jqn[k-16]= jqn[k-16]+400 ;
if (pn[k-16]==0&&pn[k-32]==0) jqn[k-32]= jqn[k-32]+550 ;
if (pn[k+48]==0) jqn[k+48]= jqn[k+48]+300 ;
if (pn[k+48]==0&&pn[k+64]==0) jqn[k+48]= jqn[k+48]+400 ;
if (pn[k+48]==0&&pn[k+64]==0) jqn[k+64]= jqn[k+64]+550 ; } }
//三连,活三变活四 01110 白方逢三必堵
if(pn[k-2]==0&&pn[k-1]==0&&pn[k]==1&&pn[k+1]==1&&pn[k+2]==1&&pn[k+3]==0&&pn[k+4]==0){ //左右
jqn[k-1]= jqn[k-1]+800 ;
jqn[k+3]= jqn[k+3]+800 ; }
if(pn[k-30]==0&&pn[k-15]==0&&pn[k]==1&&pn[k+15]==1&&pn[k+30]==1&&pn[k+45]==0&&pn[k+60]==0){ //上下
jqn[k-15]= jqn[k-15]+800 ;
jqn[k+45]= jqn[k+45]+800 ; }
if(pn[k-28]==0&&pn[k-14]==0&&pn[k]==1&&pn[k+14]==1&&pn[k+28]==1&&pn[k+42]==0&&pn[k+56]==0){//左对角
jqn[k-14]= jqn[k-14]+800 ;
jqn[k+42]= jqn[k+42]+800 ; }
if(pn[k-32]==0&&pn[k-16]==0&&pn[k]==1&&pn[k+16]==1&&pn[k+32]==1&&pn[k+48]==0&&pn[k+64]==0){//右对角
jqn[k-16]= jqn[k-16]+800 ;
jqn[k+48]= jqn[k+48]+800 ; }
//黑方的必杀点就是白方的防守要点
//嵌四 010110 011010 必杀点 +350
if (j>1&&j<12){
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]+350 ; }
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]+350 ; } }
if (i>1&&i<12){
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]+350 ; }
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]+350 ; } }
if (i>1&&i<12&&j>3&&j<15){
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]+350 ; }
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]+350 ; } }
if (i>1&&i<12&&j>1&&j<12){
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]+350 ; }
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]+350 ; } }
//活四冲四 此是必杀点 211110 011112 +1200
//黑有此白必堵,此是必杀点 如白无连五则必应
if (j>1&&j<12){ // j<12 防越界
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]+1200 ;
if (pn[k+4]==0) jqn[k+4]= jqn[k+4]+1200 ; } }
if (i>1&&i<12){
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]+1200 ;
if (pn[k+60]==0) jqn[k+60]= jqn[k+60]+1200 ; } }
if (i>1&&i<12&&j>3&&j<15){
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]+1200 ;
if (pn[k+56]==0) jqn[k+56]= jqn[k+56]+1200 ; } }
if (i>1&&i<12&&j>1&&j<12){
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]+1200 ;
if (pn[k+64]==0) jqn[k+64]= jqn[k+64]+1200 ; } }
//嵌五 10111 11011 11101 +1200
//此是必杀点 如白无连五则必应
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]+1200 ; }
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]+1200 ; }
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]+1200 ; }
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]+1200 ; }
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]+1200 ; }
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]+1200 ; }
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]+1200 ; }
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]+1200 ; }
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]+1200 ; }
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]+1200 ; }
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]+1200 ; }
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]+1200 ; }
} } //test i , j pn(225) 棋盘点位
//******************************
//测试:显示加权计分情况,最高分白下子
if (isDo==0) return ;
cs.SetTextSize (14);
cs.SetTextStyle (0);
cs.SetColor (255,0,0,240) ;
for (i=1;i<=225;i++){ //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) ; //标记分值
} }
//计算最高分
jqf=0 ;
for (i=1;i<=225;i++){
k= jqn[i] ;
if ( k>jqf) { jqf=k ; jqfn=i ; }
} //计算最高分
sn=jqfn ; //计权最高分点位转坐标
// print " sn= ",jqfn ," jqf= ",jqf ; //test
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) ; //test 查看
n=sn ; //下子点号sn转换为n, draw board
px=dx ; py=dy ; //board ()标记下子点
//**** AI 走子 **********************
}//testAIq ()
swapabc (){ //传入col , 输出 ss = "ABC"
//pn(225) 转显示 H8 ...G9...
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 (); //AI 算法测试 ****
//scan restricted move and draw mark
if (jsset==0) restrict_move () ; //禁手设置标记
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 () ; }
testAIq (); //AI 算法测试 ****
//scan restricted move and draw mark
if (jsset==0) restrict_move () ; //禁手设置标记
}//white_do ()
board (){ //绘制棋板,更新棋板
if (isDo==0) return ; //结束标志
fname="/storage/emulated/0/go02.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.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,255,255,255); //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,255,255,255);
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,60,40,20);
cs.SetTextStyle (1);
cs.SetTextSize (14);
string abc$ ;
abc$="sABCDEFGHIJKLMNO" ;
a=0 ; b=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) ;
if (i==9) b=2 ; //"I" + tab 调整
if (i>10) b=-1 ; //"K...O" + tab
cs.DrawText (ss,i*40-4+b,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="编制人:张纯叔 ( [email protected] ) " ;
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,255,255,255); //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,90,90,90); //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(95,255,0,0);
cs.DrawRect (390,670,600,740);
cs.SetColor(255,240,240,240);
cs.DrawText (s6,410,720);
cs.SetTextSize (36); //print s7=模式
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);
if(jsset==0){ //禁手设置 on ****
cs.SetColor(255,250,80,120);
cs.DrawText ("有禁手",600,720);
cs.SetColor (255,180,0,180) ;
cs.DrawCircle (690,710,9) ; }//draw mark
if(jsset==1){
cs.SetColor(255,250,80,120);
cs.DrawText ("无禁手",600,720);
cs.SetColor (255,250,250,0) ;
cs.DrawCircle (690,710,9) ; } //mark
cs.SetTextSize (30); // show开局名$ s8
cs.SetColor(255,220,0,200);
cs.DrawText (s8, 382,890);
//draw pieces number 画出下子序号*****
for (i=1;i<=dn;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,220);
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]>100){ //禁手,判白棋胜
print "禁手 pn=", n ;
cs.SetColor(255,255,0,0);
cs.SetTextSize (16);
cs.DrawText ("( 禁手 )",655,(dn+2)*16 );
cs.SetTextSize (40);
cs.DrawText ("( 禁手 )",460,530 );
ss9="白棋胜 !";
goto heqi; }
return;
//********
//** show win flag 判胜负
showwin:
if (dn>120) { //判和棋
ss9="( 和 棋 )"; goto heqi; }
cs.SetTextStyle (0);
cs.SetTextSize (16);
cs.SetColor(255,255,0,0);
if (pn[k]==1) {
ss9="黑棋胜 !"; print ss9;
cs.DrawText (ss9,655,(dn+2)*16); }
if (pn[k]==2) {
ss9="白棋胜 !"; print ss9;
cs.DrawText (ss9,655,(dn+2)*16); }
isDo=0; //结束标志
heqi: //和棋 drawngame
cs.SetTextSize (60);
cs.SetTextStyle (1);
cs.SetFillMode (1);//0不填色,1填色
cs.SetColor(255,0,90,0);
cs.DrawText (ss9,214,544);
cs.SetColor(255,255,0,0);
cs.DrawText (ss9,210,540);
cs.SetFillMode (0);//0不填色,1填色
cs.SetColor(255,250,250,0);
cs.DrawText (ss9,210,540);
print ss9 ; //record
cs.Update ();
isDo=0; //结束标志
}//detect ()
gamestart (){ //开始游戏
setDisplay (1);
isDo=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)禁手
s6="⚫棋选子"; //init
px=320 ; py=320 ; //标记
dn=0; wn=0 ; n=0 ; //计数清零
gn=gn+1; //game round + 1
clearOutput(); //清除记录
s8=" " ; //演示局名
jsset=1 ; //无禁手
board (); //绘出棋板
}//gamestart ()
restrict_set (){ //加禁手设置
jsset=0 ; //设置黑棋禁手 set on
board () ;
}//restrict_set()
restrict_move (){ //禁手设置
//黑棋禁手,加权计算查找
for (i=1;i<=225;i++) { js[i]=0 ; } //init scan
//三三禁手,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){
js[k+1]= js[k+1]+100 ;
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]==1&&pn[k+4]==1) { //101(0)101四四
js[k+1]= js[k+1]+200 ; } }//左右
if (pn[k-15]==0&&pn[k+15]==0&&pn[k+30]==1&&pn[k+45]==0){
js[k+15]= js[k+15]+100 ;
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]==1&&pn[k+60]==1) { //四四
js[k+15]= js[k+15]+200 ; } }//上下
if (pn[k-14]==0&&pn[k+14]==0&&pn[k+28]==1&&pn[k+42]==0){
js[k+14]= js[k+14]+200 ;
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]==1&&pn[k+42]==1) { //四四
js[k+14]= js[k+14]+200 ; } }//斜左
if (pn[k-16]==0&&pn[k+16]==0&&pn[k+32]==1&&pn[k+48]==0){
js[k+16]= js[k+16]+100 ;
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]==1&&pn[k+64]==1) { //四四
js[k+16]= js[k+16]+200 ; } }//右斜
} //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.DrawCircle (dx,dy,5) ; } //draw mark
} }
cs.Update () ;
// sleep(500) ;
}//restrict_move ()
set_smode ( ) { //选择开局定式
if (mode==1) return; //人机模式不设定式
gamestart () ;
smode=doubleInput("选择开局26定式(人机模式不设置定式)", "1. 寒星局 2. 溪月局 3. 疏星局 4. 花月局 ...... 23. 明星局 24. 斜月局 25. 名月局 26. 彗星局 \n 输入 [ 空 ] 或 ( 0 ) 则取消 " );
if (smode==0) return;
if (smode>26) smode=1 ; //防选空
num=(int)smode ; //double to int
n=113 ; wn=0 ;
black_do () ; //开局黑首子天元位
// 1. 寒星局 2. 溪月局 3. 疏星局
// 4. 花月局 5. 残月局 6. 雨月局
// 7. 金星局 8. 松月局 9. 丘月局
//10. 新月局 11. 瑞星局 12. 山月局
//13. 游星局 **> (1-13是直指式)
//14. 长星局 15. 峡月局 16. 恒星局
//17. 水月局 18. 流星局 19. 云月局
//20. 浦月局 21. 岚月局 22. 银月局
//23. 明星局 24. 斜月局 25. 名月局
//26. 彗星局 **>(14-26是斜指式)
if (num==1) { //直指
s8=" 1. 寒星局" ;
n=98 ; white_do () ;
n=83; black_do () ; }
if (num==2) { //直指
s8=" 2. 溪月局" ;
n=98 ; white_do () ;
n=84 ; black_do () ; }
if (num==3) { //直指
s8=" 3. 疏星局" ;
n=98 ; white_do () ;
n=85 ; black_do () ; }
if (num==4) { //直指
s8=" 4. 花月局" ;
n=98 ; white_do () ;
n=99 ; black_do () ; }
if (num==5) { //直指
s8=" 5. 残月局" ;
n=98 ; white_do () ;
n=100 ; black_do () ; }
if (num==6) { //直指
s8=" 6. 雨月局" ;
n=98 ; white_do () ;
n=114 ; black_do () ; }
if (num==7) { //直指
s8=" 7. 金星局" ;
n=98 ; white_do () ;
n=115; black_do () ; }
if (num==8) { //直指
s8=" 8. 松月局" ;
n=98 ; white_do () ;
n=128 ; black_do () ; }
if (num==9) { //直指
s8=" 9. 丘月局" ;
n=98 ; white_do () ;
n=129 ; black_do () ; }
if (num==10) { //直指
s8="10. 新月局" ;
n=98 ; white_do () ;
n=130; black_do () ; }
if (num==11) { //直指
s8="11. 瑞星局" ;
n=98 ; white_do () ;
n=143 ; black_do () ; }
if (num==12) { //直指
s8="12. 山月局" ;
n=98 ; white_do () ;
n=144 ; black_do () ; }
if (num==13) { //直指
s8="13. 游星局" ;
n=98 ; white_do () ;
n=145 ; black_do () ; }
//以上是直指开局13式,以下是斜指开局13式
if (num==14) { //斜指
s8="14. 长星局" ;
n=99 ; white_do () ;
n=85 ; black_do () ; }
if (num==15) { //斜指
s8="15. 峡月局" ;
n=99 ; white_do () ;
n=100 ; black_do () ; }
if (num==16) { //斜指
s8="16. 恒星局" ;
n=99 ; white_do () ;
n=115 ; black_do () ; }
if (num==17) { //斜指
s8="17. 水月局" ;
n=99 ; white_do () ;
n=130 ; black_do () ; }
if (num==18) { //斜指
s8="18. 流星局" ;
n=99 ; white_do () ;
n=145 ; black_do () ; }
if (num==19) { //斜指
s8="19. 云月局" ;
n=99 ; white_do () ;
n=114 ; black_do () ; }
if (num==20) { //斜指
s8="20. 浦月局" ;
n=99 ; white_do () ;
n=129 ; black_do () ; }
if (num==21) { //斜指
s8="21. 岚月局" ;
n=99 ; white_do () ;
n=144 ; black_do () ; }
if (num==22) { //斜指
s8="22. 银月局" ;
n=99 ; white_do () ;
n=128 ; black_do () ; }
if (num==23) { //斜指
s8="23. 明星局" ;
n=99 ; white_do () ;
n=143 ; black_do () ; }
if (num==24) { //斜指
s8="24. 斜月局" ;
n=99 ; white_do () ;
n=127 ; black_do () ; }
if (num==25) { //斜指
s8="25. 名月局" ;
n=99 ; white_do () ;
n=142 ; black_do () ; }
if (num==26) { //斜指
s8="26. 彗星局" ;
n=99 ; white_do () ;
n=141 ; black_do () ; }
}//set_mode ()
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 "黑棋胜 ! " ;
print ss9 ;
} //=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-5,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 ();
set_smode ( ) ;
}
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****