日期:2014-05-16  浏览次数:20466 次

javascript 写个拼图并不容易 保证有解
今天才发现写拼图这样的小游戏并不是那么容易  
以前我觉可设置行数 列数 打乱各版块,当用户点击空白版块周围的版块是可移动就行了。  
我还加了个轨迹回放 现在看了这写都是让电脑干点苦力活。
我的拼图地址(http://www.yxsss.com/apps/pintu/) 欢迎大家来玩玩

以前我总觉得是我拼不出来,我发布出来后发现那么多人挑战 但是就没有一个人拼出来。仔细研究发现拼图被随即打乱后并不是所有的都能移动到原来的样子,这样制作的拼图有一半的拼图都是无解的。

折腾了白天终于找到必须满足一定的条件:  
1、两个矩阵互相转化的过程当中,需要进行奇数次交换,这两个矩阵将永远无法相互转换,反之偶数次交换,则两个矩阵可以互相转换   
2、图形A与图形B等价的充要条件图形A的排列的逆序数加上空白元素行号和列号的奇偶性==图形B的排列的逆序数加上空白元素行号和列号的奇偶性   
两个条件满足一个这拼图就有解了  
于是我更改了打乱拼图的随机函数 

/**
 * Psx:列队数组,Puan:空白版块的位置,Ph:行数,Pl列数
 **/
function luan(){
    var _sx=[];
    function a(){
        var l=Psx.length;
        var k=rand(0,l-1);
        _sx.push(Psx[k]);
        Psx.splice(k,1);
        if(Psx.length > 0){
            a();
        }
    }
    a();
    //运用奇偶性 验证是否有解
    function b(t){
        var l=t.length,o=0,j=0;
        while(o<l){
            if(o!=Puan){
            for(i=o;i<l;i++){
                if(o==t[i]){
                    j+=i-o;
                    t.splice(i,1);
                    t.splice(o,0,o);
                    break;
                }
            }
            }
            o++;
        }
        return (j+Ph+Pl)%2!=(Puan%Pl+Math.floor(Puan/Pl))%2;
    }
    //如果没有 运用第一个 条件 更改
    if(b(_sx)){
        _sx.splice(0,0,_sx[1]);
        _sx.splice(2,1);
    }
    
    Psx=_sx;
}

这两个条件都是在网上看见的 是不同的人写的,我一起用了不知道行不行,测试了几个都还Ok; 
如果要我证明我真没那实力 各位自己去找数学高手了

------解决方案--------------------
操,拼个烂图也要登陆
------解决方案--------------------
楼主很讨厌,登的蛋呀
------解决方案--------------------
你可以随机生成一个最终图,然后利用遍历(回溯),将图形走几步(走的过程方向选择也是可以随机的),比如移动8次,那么,用户至少可以在不超过8步内,还原到你最开始生成的那个“最终图”
------解决方案--------------------