js解决”跳”马问题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/zhoujiaaw/article/details/78326717
 跳马问题算法代码         

要求:

有一m*n的棋盘(即棋盘由m行和n列),一马放在棋盘中任意位置,马按中国象棋跳法,从初始位置起跳,跳至边界后返回,求所有能返回初始位置的周游路线。



原理:

1.       马向八个方向跳“日”字;

2.       利用递归算法进行路径的查找,当马在棋盘上跳出边界时,就返回上一步重新选择方向,直到跳到符合条件(没有走过的点)的位置;

3.       查找到一种方案后,打印输出路径。

4.       利用回溯算法,回退一步,进入步骤2,继续查找。直至找完所有路径。



1技术路线:

①       界面设计:用户自主定义棋盘大小、用户定义起跳点;点击“确定”后

运行函数;打印结果

②       点击“确定”后,运行函数“main()”,完成初始化工作;并进入查找路径的递归函数“Jump()”;

③       Jump()函数中,通过循环依次寻找八个方向,并判断所找点是否已经“走过”或者跳出棋盘,若无,则进入递归;判断到达出发点,打印输出

④       查找到一条路径后,回溯上一个点,继续运行当前“Jump()”,直至找完所有路径;

  

3.结果展示:

 ①界面

  

 ②测试4*3棋盘,起始点(1,1)

  






【算法描述】         
本题有较多方法求解,在此仅对回溯法进行分析。         一只马在棋盘的某一点,它可以朝8个方向前进,方向向量分别是:(2,1)、(2,-1)、(1,2)、(1,-2)、(-2,1)、(-2,-1)、(-1,2)、(-1,-2)。从中任选择一个方向前进,到达新的位置。在从新的位置选择一个方向前进,继续,直到无法前进为止。无法前进可能有如下原因:下一位置超出边界、下一位置已经被访问过。当马已经无法前进时,就回退到上一位置,从新选择一个新的方向前进;如果还是无法前进,就再回退到上一位置……
<DOCTYPRE html>
    <html>
        <head>
            <title>
                跳马
            </title>
    
        </head>
            <body>   
                <!输入框设计>
                <form action="/test.php" method="get">
                        跳马
                        <br><br><br>
                        
                        棋盘坐标系:行为y轴,列为x轴<br>
                        棋盘行列说明:如3*4指   3行格子*4列格子,若理解为线条为4行线条*5列线条<br>
                        输入数据说明:为了您使用体验,请勿输入过大数据,这里我们的限制为10*10
                      
                        <br>
                        <hr>
                        棋盘设计:
                        <br>
                        棋盘行数:<input type="number" name="row" id="row"  min="0" max="10" />
                        棋盘列数:<input type="number" name="column" id="column"  min="0" max="10"/>
                        <hr>
                        原始起跳点:
                        <br>
                        起跳点所在行:<input type="number" name="fromRow" id="fromRow"  min="0" max="10" />
                        起跳点所在列:<input type="number" name="fromColumn" id="fromColumn"  min="0" max="10"/>
                        <br>
                        <input type="submit" value="确定" οnclick="main()"/>
                    </form>


                <script>
                    var direction=8;    //跳跃方向
                    var MAX_STEP=50;  //最大步数
                    var num=0;
                    var path=new Array(MAX_STEP + 1); 

                    
                    for(var i=0;i<(MAX_STEP+1);i++){
                        path[i]=new Array(2);
                    }//存路径
                    var dx=new Array( 0, 1, 2, 2, 1, -1, -2, -2, -1);//表示方向
                    var dy=new Array( 0, 2, 1, -1, -2, 2, 1, -1, -2);//表示方向
                   
                    
                    function Path(MAX_X, MAX_Y, step,xy){
                        for (var i = 0; i < MAX_Y;i++)
                        for (var j = 0; j < MAX_X; j++)
                            xy[i][j] = 0;
                        for (var i = 1; i < step; i++){
                            xy[path[i][1]][path[i][0]] = 1;
                        }
                    }


                    function Judgment(x, y, xy){
                        var judge = false;

                        if (xy[y][x]!=0)//重复结点,错误路径
                            judge = true;	
                        else
                            xy[y][x] = 1;
                        return judge;//false为可行路径
                    }


                    function Jump( MAX_X, MAX_Y,x,y,step,xy){
                        var t1, t2, t3, t4;
                        var x1, y1;

                        Path(MAX_X, MAX_Y,step,xy);
                        for (var k = 1; k <= direction; k++){
                            //朝八个方向中的某个方向跳跃
                            x1 = x + dx[k];
                            y1 = y + dy[k];

                            //跳出边界,进入下一种路径的查找
                            if (x1 > MAX_X || y1 > MAX_Y || x1 < 0 || y1 < 0)
                                continue;

                            t1 = (x1 >= 0) && (x1 <= MAX_X);//左右边界内
                            t2 = (y1 >= 0) && (y1 <= MAX_Y);//上下边界内
                            //边界
                           
                            t3 = (x1 == path[0][0]);
                            t4 = (y1 == path[0][1]);

                            if (t1 && t2){//在棋盘内
                                //记录位置
                                if (!Judgment(x1, y1,xy)){//返回false表示没有重复,可以继续寻找路径
                                    //continue;
                                    path[step][0] = x1;
                                    path[step][1] = y1;

                                  
                                    if (t3 && t4){
                                        num++;
                                        document.write("方案"+num+":");

                                        for (var i = 0; i <= step; i++){
                                            document.write( "("+path[i][0]+","+path[i][1]+")");
                                            if (i != step)
                                                document.write(" -> ");
                                        }//for(i)                                    
                                        document.write("<br>");
                                    }//if(t3456)
                                    else{
                                        Jump(MAX_X, MAX_Y,x1, y1, step + 1,xy); 
                                    }//else
                                }//if (!Judgment(x1, y1))
                            }//if(t1 && t2)
                        }//for(k)
                    }


                    function main(){
                        //初始位置           
                       
                        var MAX_X;      //X轴最大边界
                        var MAX_Y;      //Y轴最大边界
                        var a,b;
                      
                       
                        MAX_X=document.getElementById("column").value;
                        MAX_Y=document.getElementById("row").value;
                        a=path[0][0]=document.getElementById("fromColumn").value;          
                        b=path[0][1]=document.getElementById("fromRow").value;
                       
                        

                        if(MAX_X>10 || MAX_Y>10 || a>10 ||b>10 || (a+1)>MAX_X || (b+1)>MAX_Y){
                          document.write("拒绝服务!请按照规范输入数据");
                        }
                        var xy=new Array(MAX_Y+1);
                        for(var i=0;i<MAX_Y+1;i++){
                            xy[i]=new Array(MAX_X+1);
                        }
                        for(var i=0;i<MAX_Y+1;i++){
                            for(var j=0;j<MAX_X+1;j++){
                                xy[i][j]=0;
                            }
                        }
                 
                        Jump(MAX_X, MAX_Y,0, 0, 1,xy);
                        document.write("总方案数"+ num);    
                        if(num==0){
                            document.write("没有唉!!!");
                        }
                    }

                </script>
            </body>
    </html>
</DOCTYPRE>






猜你喜欢

转载自blog.csdn.net/zhoujiaaw/article/details/78326717