import win.ui;
/*DSG{{*/
mainForm = win.form(text="扫雷";right=494;bottom=556;bgcolor=12632256;border="dialog frame";max=false)
mainForm.add(
button={cls="button";text="开始";left=320;top=13;right=375;bottom=36;z=8};
button3={cls="button";text="随机";left=396;top=10;right=463;bottom=39;z=7};
crs={cls="edit";text="行数";left=102;top=11;right=156;bottom=35;edge=1;num=1;z=4};
ls={cls="edit";text="雷数";left=241;top=13;right=295;bottom=37;edge=1;num=1;z=6};
map={cls="plus";left=5;top=43;right=489;bottom=527;bgcolor=15780518;clipBk=false;edge=1;notify=1;z=1};
static={cls="static";text="行/列:";left=51;top=14;right=103;bottom=39;transparent=1;z=3};
static3={cls="static";text="最大雷数:";left=171;top=14;right=236;bottom=35;transparent=1;z=5};
sts={cls="static";text="Static";left=3;top=527;right=491;bottom=553;border=1;db=1;dl=1;dr=1;edge=1;transparent=1;z=2}
)
/*}}*/
import win.timer;
import math;
mtimer=win.timer(mainForm);
math.randomize();
var dflag=false;//画图标志位
var mflag=true;//随机标志位
var map={};//初始图表
var slm={};//已选中图表id
var crs=24;//行列数
var lei=math.floor(crs*crs/6);//雷数 .floor下取整,.ceil 上取整
var tlei={};//雷 位id
var ylei={};//已排出 雷 位id
var tspace={};//空 位id
var step=20;//步长
mainForm.crs.text=crs;
mainForm.ls.text=lei;
var argb={//0xAARRGGBB
red=0xFFFF0000;
green=0xFF00FF00;
blue=0xFF0000FF;
yellow=0xFFFFFF00;
black=0xFF000000;
white=0xFFFFFFFF;
};//定义几个常用 色
showlei=function(mp,flag=true){//显示雷的位置
if(flag)
{
for(i=1;#tlei;1){
selmap(mp,tlei[i],argb.black);
}
} else {
for(i=1;#tlei;1){
unselmap(mp,tlei[i]);
}
}
}//显示 所有雷
toxyline=function(mp,x,y,dx,dy,cl=0xFFFFFFFF){
import gdip;
var gph = gdip.graphics(mp)
var penrect = gdip.pen( cl, 1, 2/*_GdipUnitPixel*/ );//笔
gph.smoothingMode = 4/*_GdipSmoothingModeAntiAlias*/ ; //加上抗锯齿功能
gph.drawBezier(x,y,math.random(x,dx),math.random(y,dy),dx,dy);
}//没用得上
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);
}
testlei=function(cid){//测试当前是否为雷
/*
4 9 2
3 5 7
8 1 6
*/
var rtn=0;
if(table.find(tlei,cid)){rtn=9;};//当前是雷
return(rtn);
}
testcr=function(cid){//测试四周 雷 ID,并存入table返回
var leiRangle={};
var leiBit={cid-crs-1,cid-crs,cid-crs+1,//上面
cid-1,cid+1,//中间
cid+crs-1,cid+crs,cid+crs+1//下面
};
if(cid<=crs){//第一行
leiBit[1]=0;
leiBit[2]=0;
leiBit[3]=0;
}
if(cid>(crs*(crs-1))){//最后一行
leiBit[6]=0;
leiBit[7]=0;
leiBit[8]=0;
}
if(cid%crs==1){//第一列
leiBit[1]=0;
leiBit[4]=0;
leiBit[6]=0;
}
if(cid%crs==0){//最后一列
leiBit[3]=0;
leiBit[5]=0;
leiBit[8]=0;
}
for(i=1;#leiBit;1){
if(testlei(leiBit[i])){tadd(leiRangle,leiBit[i]);}
}
return(leiRangle);
}
testspace=function(mp,cid){//测试四周 非雷 ID,并存入table返回,
var leiRangle={};
var leiBit={cid-crs-1,cid-crs,cid-crs+1,//上面
cid-1,cid+1,//中间
cid+crs-1,cid+crs,cid+crs+1//下面
};
if(cid<=crs){//第一行
leiBit[1]=0;
leiBit[2]=0;
leiBit[3]=0;
}
if(cid>(crs*(crs-1))){//最后一行
leiBit[6]=0;
leiBit[7]=0;
leiBit[8]=0;
}
if(cid%crs==1){//第一列
leiBit[1]=0;
leiBit[4]=0;
leiBit[6]=0;
}
if(cid%crs==0){//最后一列
leiBit[3]=0;
leiBit[5]=0;
leiBit[8]=0;
}
selmap(mp,cid,argb.white);
var tl=testcr(cid);
if(#tl){drawtext(mp,map[cid],#tl,12,argb.blue);}
for(i=1;#leiBit;1){
tl=testcr(leiBit[i]);
//import console;
if(leiBit[i]!=0){//没有超出地图范围
if(#tl>0 and #tl<9){//周围没有雷,或不全是雷
if(!testlei(leiBit[i]) and !table.find(ylei,leiBit[i])){//显示周围雷数
//console.log(leiBit[i]);
selmap(mp,leiBit[i],argb.white);
tadd(leiRangle,leiBit[i]);
drawtext(mp,map[leiBit[i]],#tl,12,argb.blue);
}
} else {
if(!testlei(leiBit[i]) and !table.find(slm,leiBit[i]) and !table.find(ylei,leiBit[i])){//未知区域且不是雷
selmap(mp,leiBit[i],argb.white);
tadd(leiRangle,testspace(mp,leiBit[i]));
}
}
}
}
return(leiRangle);
}
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,,argb.black);
}//被雷炸得乱动
initmap=function(mp,ca=3){//ca<=10,大于10无变化
var xx;
crs=tonumber(mainForm.crs.text);
lei=tonumber(mainForm.ls.text);
map={};
slm={};
var mid=1;
tlei={};
ylei={};
tspace={};
mp.width=mp.height;
step=math.floor(mp.width-5)/(crs);
//fm.width=crs*step+4;
//fm.height=crs*step+4;
for(i=1;crs*step-step+1;step){// row*step-step+1
for(j=1;crs*step-step+1;step){// col*step-step+1
tadd(map,{j+ca,i+ca,j+step-ca,i+step-ca,"hz"++mid,mid,0});//x,y,w,h,name,id,flag=0
mid++;
}
}
for(i=1;lei;1){//初始化 雷 位
xx=math.random(1,mid-1);
tadd(tlei,xx);//雷位不能大于最大格子数
}
mainForm.sts.text="最大雷数:"++ lei++" 已布置雷数:"++ #tlei++ "";
} //初始化地图
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);
}
redraw=function(fm,argb1=0xFAFF0000,argb2=0xFA0000FF){
for(i=1;#map;1){//drawup drawdown,着色不同显示的立体效果不一样
if(map[i][7]!=0) {
drawup(fm,map[i],argb.black);
drawdown(fm,map[i],argb.yellow);
drawrect(fm,map[i],argb2);
}
else {
drawup(fm,map[i],argb.black);
drawdown(fm,map[i],argb.yellow);
drawrect(fm,map[i],argb1);
}
}
}//重画地图
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();
} //画矩形
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){
var id=0;
for(i=1;table.count(map);1){
if(mx>=map[i][1]&&mx<=map[i][3]&&my>=map[i][2]&&my<=map[i][4]){
id=tonumber(map[i][6]);
}
}
return(id);
} //测试 ID
selmap=function(mp,d,rrgbs=0xFA0000FF,trgbs=0x0022ff22){//选中
drawrect(mp,map[d],rrgbs);
tadd(slm,d);
map[d][7]=1;
}//点选
unselmap=function(mp,d,oargb=0xFAFF0000){
drawrect(mp,map[d],oargb);
map[d][7]=0;
}//取消选择
getid=function(nm){
var id=0;
for(i=1;#map;1){
if(nm==map[i][5]){id=map[i][6];}
}
return (id);
} //根据名称反查ID
hoho=function(mp){
if(#ylei==#tlei and #ylei+#slm==#map){
dflag=false;
drawrect(mp,{50,90,430,170},argb.blue);
drawtext(mp,{60,110,430,150},"You Are NO.1!",45,argb.yellow);
}
}
gameover=function(fm,mp,mid){
selmap(mp,mid,argb.black);
showlei(mp);
doudong(fm);
drawrect(mp,{70,80,430,170},argb.blue);
drawtext(mp,{70,110,430,130},"Game Over!!",45,argb.yellow);
dflag=false;
}
initline=function(graphics,ps=2,pm=2){
//import gdip;
var gh=graphics;//gdip.graphics(mp);
var pen=gdip.pen( 0xFF009900,ps/* 2*/, pm /* 2=_GdipUnitPixel*/ );
var icrs=crs*step+1;
for(i=1;icrs;step){
gh.drawLine(pen,i,1,i,icrs);
gh.drawLine(pen,1,i,icrs,i);
}
pen.delete();
}//画背景线
mainForm.onActivate = function(state,hwndOther,minimized){
if(state && dflag){//防止画布变成空白
redraw(mainForm.map);
}
}//窗口恢复显示
mainForm.map.onMouseDown = function(wParam,lParam){
var x,y = win.getMessagePos(lParam);
if( wParam & 0x1/*_MK_LBUTTON*/ ){
var mid =testxy(x,y) ;
if(mid!=0 && dflag){
if(testlei(mid)){//踩雷了,游戏结束。
gameover(mainForm,mainForm.map,mid);
}
else{
if(!table.find(slm,mid) and !table.find(ylei,mid)){//如果不是已经翻开的
var xspace=testspace(mainForm.map,mid);
hoho(owner);
}
}
}
}
}//鼠标左键点击
mainForm.map.onMouseMove = function(wParam,lParam){
mainForm.sts.text="已发现雷数:"++#ylei++" 已发现非雷数:"++#slm++" 共有雷数:"++#tlei++" 总格子数:"++#map++"";
}//鼠标移动
mainForm.button3.oncommand = function(id,event){
if(mflag){
mtimer.setInterval(100);
mtimer.enable();
mflag=false;
owner.text="停止";
} else {
//mtimer.setInterval(0);
mtimer.disable();
mflag=true;
owner.text="随机";
}
}//开启随机屏保
mtimer.onTimer = function(){
var sl=math.random(1,#map);
var argbx=tonumber(string.format("0x%2X%2X%2X%2X",math.random(0,255),math.random(0,255),math.random(0,255),math.random(1,255)));
mainForm.sts.text=argbx;
selmap(mainForm.map,sl,argbx);
var usl=math.random(1,#slm);
unselmap(mainForm.map,slm[usl]);
} //屏保。。
mainForm.map.onDrawContent = function(graphics,rc,txtColor,rcContent,foreColor){
if(dflag){
initline(graphics);
}
}//前景刷新
mainForm.button.oncommand = function(id,event){
var cr=tonumber(mainForm.crs.text);
var l=tonumber(mainForm.ls.text);
if(cr>24||cr<3) {
mainForm.crs.setFocus(0,-1);
return ;
}
if(l>math.floor(cr*cr/6)){ mainForm.ls.setFocus(0,-1);return ; }
dflag=true;//允许画画
initmap(mainForm.map);//初始化图块
mainForm.map.redraw();//画线
redraw(mainForm.map);//画块
}
/*
mainForm.map.onMouseDoubleClick = function(wParam,lParam){
//var x,y = win.getMessagePos(lParam);
if(dflag){
showlei(mainForm.map);
}
}//显示所有雷
*/
mainForm.map.wndproc = function(hwnd,message,wParam,lParam){
var x,y = win.getMessagePos(lParam);
if(wParam & 0x2/*_MK_RBUTTON*/){
var mid=testxy(x,y);
if(mid!=0 and dflag){
//mainForm.sts.text=wParam;
var yx=table.find(ylei,mid);
if(yx){
table.removeByValue(ylei,mid);
drawrect(owner,map[mid],argb.red);
} else {
drawtext(owner,map[mid],'@',11,argb.black);
tadd(ylei,mid);
hoho(owner);
}
}
}
//无返回值则继续调用默认回调函数
}//标记 雷位
mainForm.crs.onChange = function(){
if(owner.onModified)owner.onModified(true);
crs=tonumber(owner.text);
mainForm.ls.text=math.floor(crs*crs/6);
}//地图 行 列
initmap(mainForm.map);
mainForm.show();
dflag=true;//窗体完全载入并显示后,设置为true,然后重画窗体内容
mainForm.map.redraw();
redraw(mainForm.map);
return win.loopMessage();