千里马-modulo

继扫地机器人之后的又一道mac题,不过这次只有63关,号称"最简单的mac题",手快有手慢无啊....

先介绍下这个游戏的玩法:

每关会提供一个n行m列的二维地图,这里(n=3,m=3) 初始值

010
011
010

然后每关会提供a块piece。(这里等于3)

piece1 由3块组成,格式为:X.,XX,该格式代表的形状如下:

X
XX

piece2 由2块组成,格式为XX,该格式代表的形状如下:

XX

piece3 由3块组成,格式为X,X,X,该格式代表的形状如下:

X
X
X

再提供一个modu值,这里的modu=2。

然后你可以把这3块piece放在地图上任意一个位置,不能超出地图的边界。piece不可旋转,每个piece只能用1次也必须用1次。

当你放置一个piece之后,地图上被这个piece覆盖的格子的值会相应的加1。 如果格子中的值等于modu,又会被重置为0..

地图最初的状态

010
011
010

如果把piece1放在地图的1,1位置(第2行第2列) piece放置的位置:

000
0X0
0XX

地图变成了:

010
001
001

接着把piece2放在地图的0,1位置(第1行第2列) piece放置的位置:

0XX
000
000

map变成了

001
001
001

接着再把piece3放在地图的0,2位置(第一行第三列) piece放置的位置:

00x
00x
00x

map变成了

000
000
000

当map中的每个元素都是0,该题通过。

然后是demo部分,这里选取了49关,每一关信息都会通过一个json串得到,like:

var mod={"level":49,"modu":"3","map":["0222210","0201210","2210112","1022020","1200120","2120120","0211000"],"pieces":["X..,XX.,.XX,.X.","...X,..XX,.XX.,XX..",".X,XX,.X,.X","XXX,..X,.XX",".X.,.XX,XX.,.XX","...X,XXXX,.X..","XXX.,.XX.,..XX","XX.,XXX,.X.","XXX,X..,X..,X..,X..","XX,XX,.X,.X",".X..,XXXX","XX,XX,XX",".X.,XXX,X..","..X.,X.X.,XXXX","XXX,XXX,..X","XX..,.X.X,.XXX","XX.,.XX,..X","X..X,XXXX,.X..","XX,X.","X..,X..,X..,XX.,.XX"]};

html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>千里码</title>
    <link href="http://www.qlcoder.com//css/bootstrap.min.css" rel="stylesheet">
    <link href="http://www.qlcoder.com//css/bootstrap-theme.css" rel="stylesheet">
    <link rel="stylesheet" type="text/css" media="screen" href="http://www.qlcoder.com//css/bootstrap-markdown.min.css">
    <link href="http://www.qlcoder.com//css/reset4.css" rel="stylesheet">

    <style>
        #piece .piece-item{
            padding:10px;
            border:1px solid #ddd;
            width:32%;
            float:left;
            margin:10px 0 50px 1%;
        }
        #piece .piece-item span{
            float: left;
            font-size: 20px;
            margin-right: 10px;
        }
    </style>

</head>
<body>
<div class="container">
    <div>
        你好,gaga,现在的level:0

        <br>
        <input type="button" value="重玩本关" onclick="NextLevel(0)" style="margin:10px 0;">
        <br>

        <input id="level" type="hidden" value="0">
        <!--<input type="button" value="游戏说明" onclick="DoHelp()">-->
        <input type="button" value="上一关" onclick="NextLevel(-1)">
        <input type="button" value="下一关" onclick="NextLevel(1)">

    </div>
    <div class="">
        <div style="float:left;margin-top:10px;max-width: 450px;overflow: auto;">
            <canvas id="canvas" width="700" height="500">提示:你的浏览器不支持canvas标签 </canvas>
        </div>

            <div id="piece" style="float: right;border:1px solid #ddd;margin:10px 0 0 20px;width:750px;">
                <!--<div class="piece-item"><input type="radio" name="piece" /><span></span></div>-->
            </div>

    </div>


<img src="images/iconfont-0.png" id="num0" style="display: none;" />
<img src="images/iconfont-1.png" id="num1" style="display: none;" />
<img src="images/iconfont-2.png" id="num2" style="display: none;" />
<img src="images/iconfont-3.png" id="num3" style="display: none;" />
<img src="images/iconfont-4.png" id="num4" style="display: none;" />
</div>
<!-- Footer -->
<footer>
    <p>Copyright © 2015 qlcoder.com. All Rights Reserved. 浙ICP备15038807号-1. | 联系我们:oreo@qlcoder.com <a target="_blank" href="http://shang.qq.com/wpa/qunwpa?idkey=08dcd44232943b517c2ed04dceb097155575f604791c57bbd2f9759e90e22d58">qq群480394714</a></p>
</footer>
<script> var mod={"level":49,"modu":"3","map":["0222210","0201210","2210112","1022020","1200120","2120120","0211000"],"pieces":["X..,XX.,.XX,.X.","...X,..XX,.XX.,XX..",".X,XX,.X,.X","XXX,..X,.XX",".X.,.XX,XX.,.XX","...X,XXXX,.X..","XXX.,.XX.,..XX","XX.,XXX,.X.","XXX,X..,X..,X..,X..","XX,XX,.X,.X",".X..,XXXX","XX,XX,XX",".X.,XXX,X..","..X.,X.X.,XXXX","XXX,XXX,..X","XX..,.X.X,.XXX","XX.,.XX,..X","X..X,XXXX,.X..","XX,X.","X..,X..,X..,XX.,.XX"]};</script>
<script src="js/jquery.min.js"></script>
<script src="http://www.qlcoder.com//js/bootstrap.min.js"></script>
<script src="js/module.js"></script>
<script>

//    console.log(pieces[1][0][1]);
    if(document.getElementsByClassName("container")[0]!=null)
        document.getElementsByClassName("container")[0].style.minHeight=window.innerHeight-133+"px";
</script>
</body>
</html>

js:

/**
 * Created by Diego on 16/1/11. v1.3
 * v1.2修改了单选piece在点击地图的方式,改为默认当前碎片的第一个,点击地图成功后原来第一个碎片移除,新增piece有无判断.修改地图长宽错误.修改几处样式(虽然还是很丑)
 * 取消map.js和piece.js,通过转换json(html中的mod)来得到map和piece,新增toArrMap函数
 * js加jq这样的写法还有谁吗?!  16/1/17
 * v1.3 新增提示框,经过map的时候就显示piece大小的透明度为0.2的框
 */

var w=h=32;

var num0=document.getElementById("num0");
var num1=document.getElementById("num1");
var num2=document.getElementById("num2");
var num3=document.getElementById("num3");
var num4=document.getElementById("num4");
var canvas=document.getElementById("canvas");
var piece=document.getElementById("piece");
//var level=parseInt(document.getElementById("level").getAttribute("value"));
var context = canvas.getContext('2d');
var curMap;//当前地图数据数组,初始与curLevel相同,游戏中改变
var curPiece;
var curLevel;//当前级地图数据,游戏中不变,用来判断游戏是否结束
var modu;
var pos={};
var flag=true;
var clickCount=0;//点击次数
var level=mod.level;
function init(){
    initLevel();

}
//关卡初始化
function initLevel()
{
    modu=mod.modu;
    //console.log(modu);
    curMap=toArrMap(mod.map);
    //console.log(curMap);
    curLevel=toArrMap(mod.map);
    canvas.setAttribute("width",(curLevel[0].length)*(w));//这里的宽高原来是反的原来是w:curLevel.length
    canvas.setAttribute("height",(curLevel.length)*(h));
    DrawMap(curMap,context);
    curPiece= toArr(mod.pieces);
    //console.log(curPiece);
    DrawPieceMap(curPiece);
    $(".piece-item").first().css("border-color","red");
}

//初始化piece,防止进入前后关只增
function initPiece(){
    //var remove=document.getElementsByClassName("piece-item");
    //for(;remove.length>0;){
    //    piece.removeChild(piece.lastChild);
    //    //打代码快点么??没感觉出来的咯
    //}
    $(".piece-item").remove();
}
//初始化地图
function DrawMap(level,con){

    var pic;
    for(var i=0;i<level.length;i++)//y轴
    {
        for(var j=0;j<level[i].length;j++)//x轴
        {
            var num=level[i][j];
            switch (num){
                case 0:
                    pic=num0;
                    break;
                case 1:
                    pic=num1;
                    break;
                case 2:
                    pic=num2;
                    break;
                case 3:
                    pic=num3;
                    break;
                case 4:
                    pic=num4;
                    break;
            }
            con.fillStyle="#fff";
            con.fillRect(w*j,h*i+1,pic.width,pic.height);//重新画个矩形把原来的覆盖了,不然新的会在原有的上面叠加
            con.drawImage(pic,w*j,h*(i)+1,pic.width,pic.height);//(图片,x,y,width,height)
        }
    }
}

//piece字符串转成数字表示的数组
function toArr(level){

    //console.log(level);
    var arr=new Array();

    //创建多维数组
    for(var i=0;i<level.length;i++){
        arr[i]=new Array();

        var _arr=level[i].split(",").length;
        //console.log(_arr);
        for(var j=0;j<_arr;j++){
            arr[i][j]=new Array();
        }
    }
    //把piece转化为数组
    for(var i=0;i<level.length;i++)
    {
        var x=0;
        var y=0;
        for(var j=0;j<level[i].length;j++){
            //console.log("x1:"+x);
            //console.log(arr[i][x]);
            //console.log("y1:"+y);

            //有逗号的时候,数组成员要多一个
            if(level[i][j]=="X"){arr[i][x][y]=1;y++;}
            else if(level[i][j]=="."){arr[i][x][y]=0;y++;}
            else if(level[i][j]==","){
                x++;
                y=0;

            }
            //console.log(arr[i][x][y-1]);
            //console.log("y2:"+y);
        }
    }
    return arr;
}
//var map=mod.map;
//var x=toArrMap(map);
//console.log(x);

//把mod.map转化成数组
function toArrMap(map){

    var mapArr=new Array();  //一维数组mod.map
    for(var i=0;i<map.length;i++){ //二维数组mod.map[i]
        mapArr[i]=new Array();
        for(var j=0;j<map[i].length;j++){
            mapArr[i][j]=new Array();//三维数组mod.map[i][j]
            mapArr[i][j]=parseInt(map[i][j]);
        }
    }
    //for(var i=0;i<map.length;i++){
    //    for(var j=0;j<map[i].length;j++){
    //      mapArr[i][j]=parseInt(map[i][j]);
    //    }
    //}
    return mapArr;
}

//把piece转化成图片
function DrawPieceMap(level){
    for(var i=0;i<level.length;i++){
        //console.log(level[i]);
        //动态创建piece图片
        for(var j=0;j<level[i].length;j++){
            var pcanvas=document.createElement("canvas");
            var pcontext=pcanvas.getContext('2d');
            pcanvas.setAttribute("width",(level[i][j].length)*(w+1));//这里的宽高原来写反了.已改正
            pcanvas.setAttribute("height",(level[i].length)*(h+1));
        }
        //绘制piece
        DrawMap(level[i],pcontext);
        //动态生成piece前面的单选按钮和它的父元素,最后统一放到id=piece的容器中(好多piece真乱...)
        var div=document.createElement("div");
        div.setAttribute("class","piece-item");
        var span=document.createElement("span");//原先的单选改成默认第一个,后面取消单选判断
        span.innerHTML=i+" :";
        span.setAttribute("data",i);
        span.setAttribute("datay",level[i].length);
        span.setAttribute("datax",level[i][0].length);
        div.appendChild(span);
        div.appendChild(pcanvas);
        piece.appendChild(div);
    }
}

//添加事件响应
canvas.addEventListener('click', function(e){
    if(flag){
        p = getEventPosition(e);
        showPos(p);
        clickCount++;
        tip(p);
    }
}, false);

canvas.addEventListener("mousemove",function(e){
    var t=getEventPosition(e);
    DrawMap(curMap,context);
    tip(t);

});

//得到点击的坐标
function getEventPosition(ev){
    var x, y;
    if (ev.layerX || ev.layerX == 0) {
        x = ev.layerX;
        y = ev.layerY;
    }else if (ev.offsetX || ev.offsetX == 0) { // Opera
        x = ev.offsetX;
        y = ev.offsetY;
    }
    return {x: x, y: y};
}

//选中的piece覆盖到地图上
function showPos(p){

    for(var j =0;j<curLevel.length;j++)
    {
        for(var i=0;i<curLevel[0].length;i++)
        {
            if(w*i<p.x && w*(i+1)>p.x && h*j<p.y &&h*(j+1)>p.y)//获得地图点击位置的坐标
            {
                //console.log(i+" "+j);
                var x=curLevel[0].length-i;//距边界的距离
                var y=curLevel.length-j;
                var _i=i;
                var _j=j;//嗯..这是piece上个部分的坐标..
                //console.log(x+" "+y);
                change(x,y,_i,_j);//zhenshi caodan de hanshu...

            }
        }
    }

}

//caodan hanshu start..
function change(x,y,ci,cj){
    var piecex=$(".piece-item").first().children("span").attr("datax");
    var piecey=$(".piece-item").first().children("span").attr("datay");
    var index=$(".piece-item").first().children("span").attr("data");
    //console.log(piecex+"  piecex");
    //console.log(piecey+"  piecey");

    //先判断是否有碎片
    if($(".piece-item").length<1)
    {
        alert("诶诶,碎片没了!");
        return;
    }
    else{
        //判断是否超出边界
        if(x>=piecex && y>=piecey)
        {

            //console.log(curPiece[index].length);
            //curMap[ci][cj]=1;
            for(var i=0;i<curPiece[index].length;i++){
                for(var j=0;j<curPiece[index][i].length;j++){
                    var val=curPiece[index][i][j];
                    //console.log(i+"  i");
                    //console.log(j+"  j");
                    //console.log(val+"  val");
                    var _ci=ci;
                    var _cj=cj;
                    //console.log(_ci+"  _ci");
                    //console.log(_cj+"  _cj");
                    changeMap(i,j,_ci,_cj,val);
                }
            }
            DrawMap(curMap,context);
            $(".piece-item").first().remove();
            $(".piece-item").first().css("border-color","red");

            if(CheckFinish()){
                alert("过关了!恭喜!")
                NextLevel(1);
            }
        }
        else{
            alert("碎片在这个位置的话会超出边界了呢亲~");
        }
    }
}

//点击地图之后,遍历piece转化成数组之后里面的值,传到这里去修改地图的值,这函数越改越多了= =!
function changeMap(ti,tj,tti,ttj,value){//参数分别对应,piece对应的数组下标,当前地图点击的坐标和当前piece对应的值

    curMap[ttj+ti][tti+tj]=(curMap[ttj+ti][tti+tj]+value)%modu;
    //console.log(CheckFinish());
}

//点击地图后出现提示piece在地图中的位置
function tip(t){
    if(clickCount>19)
    {return;}


    context.strokeStyle="rgb(255,0,0)";
    context.lineWidth=4;
    context.strokeRect(t.x, t.y,(curPiece[clickCount][0].length-0.5)*(w),(curPiece[clickCount].length-1)*(h));
    context.fillStyle="rgba(255,255,255,0.5)";
    context.fillRect(t.x, t.y,(curPiece[clickCount][0].length-0.5)*(w),(curPiece[clickCount].length-1)*(h));


}

//判断是否完成本关
function CheckFinish()
{
    for(var i=0;i<curMap.length;i++)//y轴
    {
        for(var j=0;j<curMap[i].length;j++)//x轴
        {

            if(curMap[i][j]!=0)
            {
                //console.log("asd");
                return false;
            }
        }
    }
    return true;
}

function NextLevel(i)
{

    flag=true;
    level=level+i;
    if(level<0)
    {
        iCurLevel=0;
        return;
    }
    var len=level.length;
    if(level>len-1)
    {
        iCurLevel=len-1;
        return;
    }
    document.getElementById("level").setAttribute("value",level);
    initPiece();
    initLevel();

}

//克隆二维数组
function copyArray(arr)
{
    var b=[];
    for(var i=0;i<arr.length;i++)
    {
        b[i]=arr[i].concat();
    }
    return b;
}
window.onload=init;
-fno-gcse-las:此选项禁用通用局部优化(Global Common Subexpression Elimination),这是编译器用于消除重复表达式的技术。它允许编译器在不同的函数或代块中共享变量的值。-fno-loop-nest-optimize:此选项禁用循环嵌套优化,这是一种在循环中重新排列指令的技术,提高循环的性能。-fsched-spec-load-dangerous:此选项禁用规格加载指令优化,这是一种技术,可以消除在循环中重复加载变量的指令。-fno-tree-loop-distribution:此选项禁用树循环分布优化,它是一种重新排列循环体,使得某些循环可以并行运行,从而提高性能的技术。-fno-unwind-tables:此选项禁用表格解除,它是一种技术,用于解决当出现异常时,编译器如何跟踪堆栈帧的问题。-ffp-contract=fast:此选项指定编译器使用快速浮点合同优化,它是一种技术,可以将多个浮点运算合并为一个运算,从而提高程序的性能。-fno-float-store:此选项禁用浮点存储优化,它是一种技术,可以将变量以浮点数的形式存储在内存中,从而提高程序的性能。-fno-modulo-sched-allow-regmoves:此选项禁止模块调度器在重新排序中使用寄存器移动,模块调度器是一种技术,可以重新排列指令,使其在处理器中运行更快。-fno-peel-loops:此选项禁用循环削减,它是一种技术,可以在循环的开始和结束处插入指令,以提高循环的性能。-fno-sched-pressure:此选项禁止调度器压力优化,它是一种技术,可以根据处理器负载重新排列指令,以提高程序性能。-fsplit-paths:此选项激活路径分裂优化,它是一种技术,可以在运行时将多条指令路径分割为几个部分,从而提高程序的性能。-ftree-slp-vectorize:此选项激活树结构优化,它是一种技术,可以将许多连续的指令组合成一条指令,从而提高程序的性能。-fwrapv:此选项激活符号溢出检查和溢出处理,它是一种技术,可以在运行时检查整数溢出,以便防止程序的不可预料的行为。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值