aardio 写了个 扫雷

此博客展示了一段实现扫雷游戏的代码。代码中定义了游戏所需的各种变量,如行列数、雷数等,还包含了显示雷位置、测试是否为雷、测试四周雷ID等多个功能函数,通过鼠标点击、移动等操作来控制游戏,实现了扫雷游戏的基本功能。

//扫雷 
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){//测试当前是否为雷
    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){
    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.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();

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值