import win.ui;
/*DSG{{*/
mainForm = win.form(text="五子棋";right=736;bottom=588;bgcolor=32960;max=false)
mainForm.add(
back={cls="button";text="悔 棋";left=244;top=552;right=330;bottom=578;border=1;disabled=1;z=4};
ckbw={cls="checkbox";text="白子先走";left=24;top=556;right=128;bottom=576;bgcolor=32960;z=6};
map={cls="plus";left=95;top=9;right=631;bottom=543;bgcolor=33023;clipBk=false;edge=1;notify=1;z=1};
pb={cls="plus";left=646;top=171;right=714;bottom=239;edge=1;z=8};
pw={cls="plus";left=13;top=161;right=81;bottom=229;edge=1;z=7};
qzmap={cls="plus";left=96;top=12;right=632;bottom=546;clipBk=false;edge=1;notify=1;transparent=1;z=2};
spb={cls="static";left=653;top=263;right=717;bottom=300;transparent=1;z=10};
spw={cls="static";left=13;top=264;right=77;bottom=299;transparent=1;z=9};
start={cls="button";text="开 始";left=134;top=551;right=216;bottom=578;border=1;z=3};
sts={cls="static";text="状态栏";left=342;top=553;right=668;bottom=574;align="center";border=1;font=LOGFONT(weight=700);transparent=1;z=5}
)
/*}}*/
import math;
var dflag=false;//画图标志位
var map={};//初始图表
/* #slm=#hids+#wids */
var slm={};//已落子图表id
var hids={};//黑子id
var wids={};//白子id
var crs=26;//线 行列数 可放棋子为 25*25
var hw=true;//交换棋子着色,黑子先走
var step=20;//步长
mainForm.qzmap.top=mainForm.map.top;
mainForm.qzmap.left=mainForm.map.left;
mainForm.qzmap.width=mainForm.map.width;
mainForm.qzmap.height=mainForm.map.height;
var argb={//0xAARRGGBB
red=0xFFFF0000;
green=0xFF00FF00;
blue=0xFF0000FF;
yellow=0xFFFFFF00;
black=0xFF000000;
white=0xFFFFFFFF;
};//定义几个常用 色
tadd=function(t,id,f=false){//f 默认过滤重复值
if(type(t)=="table"){
if(f){table.push(t,id);}
else{if(!table.find(t,id)){table.push(t,id);}}
}
}
deltoo=function(tb,z=true){//删除table重复值,默认只保留非0值
var rtn={};
if(type(tb)=="table"){
for(i=1;#tb;1){
if(!table.find(rtn,tb[i])){
if(z){if(tb[i]!=0) table.push(rtn,tb[i]);}
else{table.push(rtn,tb[i]);}
}
}
}
return(rtn);
}
testid=function(cid){//测试当前是否已经落子
/*
4 9 2
3 5 7
8 1 6
*/
var rtn=0;//可落子
if(table.find(slm,cid)){//当前是否已有落子
if(table.find(hids,cid)){rtn=1;}//已有黑子
if(table.find(wids,cid)){rtn=2;}//已有白子
}
return(rtn);
}
testout=function(cid){//测试是否出边了
var rtn=0;
if(cid<25){rtn=1;}//第一行
if(cid>(crs-2)*25){rtn=2;}//最后一行
if(cid%25==0){rtn=4;}//最后一列
if(cid%25==1){rtn=3;}//第一列
return(rtn);
}
testfive=function(cid,wb=1){//测试四周连续棋子数量 任何一组大于4即为胜
//import console;
var tid;
var fv={h=1,s=1,p=1,n=1};
var rtn=0;
//console.log(cid);
//横
//console.log("--fv.h---");
for(i=1;5;1){tid=cid+i;if(testid(tid)==wb){fv.h++;if(testout(tid)==4){i=6;}} else {i=6;}}//右边
//console.log(fv.h);
for(i=1;5;1){tid=cid-i;if(testid(tid)==wb){fv.h++;if(testout(tid)=3){i=6;}} else {i=6;}}//左边
//console.log(fv.h);
//竖
//console.log("--fv.s---");
for(i=1;5;1){tid=cid-i*25;if(testid(tid)==wb){fv.s++;if(testout(tid)=1){i=6;}} else {i=6;}}//上边
//console.log(fv.s);
for(i=1;5;1){tid=cid+i*25;if(testid(tid)==wb){fv.s++;if(testout(tid)=2){i=6;}} else {i=6;}}//下边
//console.log(fv.s);
//console.log("--fv.p---")
//撇
for(i=1;5;1){tid=cid-i-i*25;if(testid(tid)==wb){fv.p++;if(testout(tid)==3 or testout(tid)==1){i=6;}} else {i=6;}}//左上
//console.log(fv.p);
for(i=1;5;1){tid=cid+i+i*25;if(testid(tid)==wb){fv.p++;if(testout(tid)==2 or testout(tid)==4){i=6;}} else {i=6;}}//右下
//console.log(fv.p);
//console.log("--fv.n---")
//捺
for(i=1;5;1){tid=cid+i-i*25;if(testid(tid)==wb){fv.n++;if(testout(tid)==4 or testout(tid)==1){i=6;}} else {i=6;}}//右上
//console.log(fv.n);
for(i=1;5;1){tid=cid-i+i*25;if(testid(tid)==wb){fv.n++;if(testout(tid)==3 or testout(tid)==4){i=6;}} else {i=6;}}//左下
//console.log(fv.n);
//console.log("-----")
//判断有没有连续5子
if(fv.h>4 || fv.s>4 || fv.p>4 || fv.n>4){rtn=5;}
return(rtn)
}
doudong=function(wf){//窗口抖动
var ox=wf.left;
var oy=wf.top;
var oh=wf.height;
var ow=wf.width;
for(i=1;2;1){
for(j=1;4;1){
wf.left=ox-j;
wf.top=oy-i;
wf.height=oh+i;
wf.width=ow+j;
sleep(100);
}
wf.left=ox;
wf.top=oy;
wf.height=oh;
wf.width=ow;
}
redraw(wf.map);
}
initmap=function(ca=20){
map={};
slm={};
hids={};
wids={};
mid=1;
step=20;
for(i=1;crs*step-step;step){// row*step-step+1
for(j=1;crs*step-step;step){// col*step-step+1
tadd(map,{j+ca,i+ca,j+step+ca/2,i+step+ca/2,mid});//x,y,w,h,id
mid++;
}
}
} //初始化地图
showmap=function(mp){//显示所有棋位框,测试时用,实际用不上
for(i=1;#map;1){
drawrect(mp,map[i]);
}
}
redraw=function(mp){//刷新棋子
for(i=1;#hids;1){//黑子
drawcircle(mp,map[hids[i]],,argb.black);
}
for(i=1;#wids;1){//白子
drawcircle(mp,map[wids[i]],,argb.white);
}
}//重画棋子
drawcircle=function(mp,cid,r=8,color=0xFF000000,qz=true){//默认半径为8
var x=cid[1]+5;
var y=cid[2]+5;
var brush = gdip.solidBrush(color);
var graphics=gdip.graphics(mp);
graphics.smoothingMode = 4/*_GdipSmoothingModeAntiAlias*/ ; //为了圆形画的平滑自然,加上抗锯齿功能
graphics.fillEllipse( brush, x-r,y-r,r*2,r*2);//画圆形、或椭圆
if(qz){//眼睛和嘴,哈哈哈。。。
if(color!=argb.white){brush=gdip.solidBrush(argb.white);}
else{brush=gdip.solidBrush(argb.black);}
graphics.fillEllipse(brush,x-r/4,y+r/3,r/2,r/5);
graphics.fillEllipse(brush,x-r/2,y-r/3,r/3,r/6);
graphics.fillEllipse(brush,x+r/3,y-r/3,r/3,r/6);
}
brush.delete();
}
drawup=function(mp,md,cl=0xFF0000FF){//左 上 影
drawrect(mp,{md[1]-2,md[2]-2,md[3],md[4]},cl);
}
drawdown=function(mp,md,cl=0xFF000000){// 右 下 影
drawrect(mp,{md[1],md[2],md[3]+2,md[4]+2},cl);
}
drawrect=function(mp,xx,rgbs=0xFAFF0000,flag=true){//画矩形,xx为数组={x,y,w,h} ,mp为窗体或控件,fl:true空心或false实心
import gdip;
var graphics = gdip.graphics(mp)
var penrect = gdip.pen( rgbs, 1, 2/*_GdipUnitPixel*/ );//笔
graphics.drawRectangle( penrect, xx[1],xx[2],xx[3]-xx[1],xx[4]-xx[2]);
if(flag){
var brush = gdip.solidBrush(rgbs);
graphics.fillRectangle( brush, xx[1]+1,xx[2]+1,xx[3]-xx[1]-1,xx[4]-xx[2]-1);
brush.delete();
}
penrect.delete();
} //画矩形
drawout=function(mp,cid,color=0xFF222222){//棋位提示框,有点闪,所以没开启
var graphics=gdip.graphics(mp);
var pen = gdip.pen( color,1,2/*_GdipUnitPixel*/ );
//创建一个文字路径
pen.dashCap = _GdipLineCap;
path = gdip.path();
path.addRectangle(map[cid][1]-3,map[cid][2]-3,step-4,step-4);
graphics.drawPath( pen, path);
pen.delete();
path.delete();
}
drawtext=function(mp,xx,tt,ss,rgbs=0xFF000000,align=1,valign=1){//xx文字区域{x,y,dx,dy},tt文字,ss大小
import gdip;
var graphics = gdip.graphics(mp)//图形对象graphics(可以看作是画板)
graphics.smoothingMode = 4/*_GdipSmoothingModeAntiAlias*/ ; //加上抗锯齿功能
var pentxt = gdip.pen( rgbs, 1,2/*_GdipUnitPixel*/ );//创建画笔,画笔pen只能画一个轮廓(画线描边)
var brushtxt = gdip.solidBrush(rgbs);//创建刷子,画刷可以对一个东西进行填充(刷子)
family = gdip.family( "Verdana" ); ////创建FontFamily字体
strformat = gdip.stringformat ( );//创建stringFormat
strformat.align =align;//1/*_StringAlignmentCenter*/; //设置样式 水平居中
strformat.lineAlign =valign;// 1/*_StringAlignmentCenter*/ ; //设置样式 垂直居中
rclayout = ..gdip.RECTF(xx[1],xx[2],xx[3]-xx[1]-1,xx[4]-xx[2]-1);//设置文字区域
path = gdip.path(); //创建一个文字路径
path.startFigure();
path.addstring( tt, family, 1/*_GdipFontStyleBold*/, ss, rclayout, strformat);
graphics.fillPath( brushtxt, path)//fillPath填充路径
//graphics.drawPath( pen, path)//drawPath描边
//删除所有GDI+对象
brushtxt.delete();
pentxt.delete() ;
strformat.delete();
family.delete();
path.delete();
} //写字
testxy=function(mx,my){//取当前位 map id
var cid=0;
for(i=1;#map;1){
if(mx>=map[i][1]&&mx<=map[i][3]&&my>=map[i][2]&&my<=map[i][4]){
cid=tonumber(map[i][5]);
}
}
return(cid);
} //测试 ID
reback=function(){//悔棋
if(#slm>0){
var cid=slm[#slm];
table.removeByValue(slm,cid);
table.removeByValue(wids,cid);
table.removeByValue(hids,cid);
hw=!hw;
return(cid);
}
return(0);
}
winner=function(mp,txt=""){//胜利 提示
dflag=false;
drawrect(mp,{70,90,440,170},argb.blue);
drawtext(mp,{80,110,440,150},txt+" 胜了!",45,argb.yellow);
}
gameover=function(fm,mp){//和棋 提示
doudong(fm);
drawrect(mp,{70,80,430,170},argb.blue);
drawtext(mp,{70,110,430,130},"和棋了!",45,argb.yellow);
dflag=false;
}
initline=function(graphics,ps=2,pm=2){//画背景线和标位点
var gh=graphics;//gdip.graphics(mp);
var pen=gdip.pen( argb.black,ps/* 2*/, pm /* 2=_GdipUnitPixel*/ );
var brush=gdip.solidBrush(argb.black);
var icrs=crs*step+1;
gh.drawRectangle(pen,4,4,icrs+3,icrs+3);
for(i=1;icrs;step){
gh.drawLine(pen,i+5,5,i+5,icrs+5);
gh.drawLine(pen,5,i+5,icrs+5,i+5);
}
gh.smoothingMode = 4/*_GdipSmoothingModeAntiAlias*/ ; //为了圆形画的平滑自然,加上抗锯齿功能
gh.fillEllipse(brush, step*6+1,step*6+1,10,10);
gh.fillEllipse(brush, step*20+1,step*6+1,10,10);
gh.fillEllipse(brush, step*6+1,step*20+1,10,10);
gh.fillEllipse(brush, step*13+1,step*13+1,10,10);
gh.fillEllipse(brush, step*20+1,step*20+1,10,10);
pen.delete();
brush.delete();
}//画背景线
hwgo=function(){//当前 棋色
if(hw){
mainForm.spb.text="黑子 走";
mainForm.spw.text="";
drawcircle(mainForm.pw,{29,29},32,0xffc08000,false);//窗体背景色转 argb
drawcircle(mainForm.pb,{28,28},30,argb.black,false);
} else {
mainForm.spw.text="白子 走";
mainForm.spb.text="";
drawcircle(mainForm.pb,{29,29},32,0xffc08000,false);//窗体背景色转 argb
drawcircle(mainForm.pw,{28,28},30,argb.white,false);
}
}
mainForm.onActivate = function(state,hwndOther,minimized){
if(state && dflag){//防止画布变成空白
mainForm.qzmap.redraw();
redraw(mainForm.qzmap);
}
}//窗口恢复显示
mainForm.map.onMouseMove = function(wParam,lParam){//当鼠标移动时
var x,y = win.getMessagePos(lParam);
var mid=testxy(x,y);
if(dflag && mid!=0){
hwgo();
mainForm.sts.text="棋位: "++mid++" ";
/*
mainForm.map.redraw();
redraw(mainForm.qzmap);
if(testid(mid)==0){
drawout(mainForm.qzmap,mid);
}
*/
}
}
mainForm.map.onMouseDown = function(wParam,lParam){//当鼠标左键按下时
var x,y = win.getMessagePos(lParam);
if( wParam & 0x1/*_MK_LBUTTON*/ ){
var mid =testxy(x,y);
var ff=0;
if(mid!=0 && dflag){
if(testid(mid)==0){//是否可落子
tadd(slm,mid);
if(hw){
tadd(hids,mid);
redraw(mainForm.qzmap);
ff=testfive(mid);
if(ff>4){winner(mainForm.qzmap,"黑子");dflag=false;}
}
else{
tadd(wids,mid);
redraw(mainForm.qzmap);
ff=testfive(mid,2);
if(ff>4){winner(mainForm.qzmap,"白子");dflag=false;}
}
hw=!hw;//交换
if(#slm>0){mainForm.back.disabled=false;}
if(#slm==#map && dflag){gameover();dflag=false;}//和棋了。
}
}
}
}//鼠标左键点击
mainForm.map.onDrawContent = function(graphics,rc,txtColor,rcContent,foreColor){
if(dflag){
initline(graphics);
}
}//前景刷新
mainForm.start.oncommand = function(id,event){// 开始
dflag=true;//允许画画
hw=true;//黑子先走。
if(mainForm.ckbw.checked){hw=false;}
hwgo();
initmap();
mainForm.map.redraw();//画线
}
/**
mainForm.map.wndproc = function(hwnd,message,wParam,lParam){
var x,y = win.getMessagePos(lParam);
if(wParam & 0x2/*_MK_RBUTTON*/){//右键单击
var mid=testxy(x,y);
//redraw(mainForm.qzmap);
}
//无返回值则继续调用默认回调函数
}//标记
**/
mainForm.back.oncommand = function(id,event){//悔棋
var mid;
if(dflag and #slm>0){
mid=reback();
mainForm.map.redraw();
redraw(mainForm.qzmap);
}
if(#slm<1){mainForm.back.disabled=true;}
}
mainForm.ckbw.oncommand = function(id,event){//白子先走
if(#slm==0 and mainForm.ckbw.checked){
hw=false;
}
if(!mainForm.ckbw.checked && #slm==0){hw=true;}
hwgo();
}
initmap();
mainForm.show();
dflag=true;//窗体完全载入并显示后,设置为true,然后重画窗体内容
mainForm.map.redraw();
hwgo();
return win.loopMessage();