九宫格拼图游戏大家都很熟悉,这里给大家如介绍何应用状态空间搜索的方式求解拼图的最佳路径和一个游戏dome及自动求解方法;

本文分web版游戏的实现和启发式搜索算法两部分;

先看dome,直接鼠标点击要移动的方块开始游戏,点击 提示 开始最佳路径搜索(启发式)直到最后一步;

(如果提示无解,则表示没有找到最佳路点击重置重新试一次,可通过console查看全部搜索的每一步节点状态,或在js/main.js中打断点看每一步结果,详细内容见下文)

项目地址:https://github.com/pangyongsheng/puzzle

dome演示:http://pangyongsheng.github.io/puzzle/

一、游戏的实现方法

  首先我们考虑如何用数据表示拼图游戏的状态,即将拼图游戏视图与数据绑定;

  如下图所示:

    

  (1)以左上角为原点,建立坐标系,蓝色数字表示位置序号,

      则该位置div(拼图块)的left和right(向左和向下的偏移距离)等于为其左上角绿点的坐标(x,y),即:

      left    =  x * 小方块边长

      right =   y* 小方块边长

  (2)这样的话,我们就可以用一个长度为9数组表示当前拼图的状态空间,

      如 [2,0,1,5,4,6,7,8,3] 可表示 一号方块在2号位置,二号方块在0号位置...    如下图所示:

      自此我们就实现了视图与数据的对应关系,把拼图问题转化成为一个数组排列组合问题;

  (3)对于任意号位置a的坐标c我们可通过建立一个如下二维数组来获取, 

      var place= [ 
        [0, 0],[1, 0],[2, 0],

        [0, 1],[1, 1],[2, 1],   

        [0, 2],[1, 2],[2, 2]

      ]

    位置序号与坐标则有如下关系

      c=place[a]

     由以上可知获取a坐标方法

    

   初始化每一个小方块位置方法(block为全部小方块dom,这里借用数组方法forEach遍历div)

    

   (4)对于任意两个坐标的距离我们可以表示为

      d=| x1 - x2 | +  | y1-y2 |

     代码如下

    

  (5)那么我们可以求得当前状态和目标状态的全部距离为,(每个小方块距离目标的距离求和),f(x)第x方块距离目标位置的距离

    

    代码如下

    

  (6)如何判断点击的方块是否能移动,首先我们将最后一个方块隐藏,如果点击的方块距离最后(8号)方块距离为1则表示可以移动,及两个状态可以转化,

     这个方法也可以看做两个状态的数组能否相互转化,可作为后面启发式搜索判断节点扩展的方法;

    

    以上代码为每个方块添加点击事件

    至此游戏的基本实现方式介绍完毕,详细看代码

二、启发式搜索

  启发式搜索就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标。这样可以省略大量无谓的搜索路径,提高了效率。在启发式搜索中,对位置的估价是十分重要的。采用了不同的估价可以有不同的效果。

它把到达节点的耗散g(n)和从该节点到目标节点的消耗h(n)结合起来对节点进行评价:f(n)=g(n)+h(n)

  简单的说就是扩展当前状态节点的所有可能下一步节点,通过一个方式来估算那个节点最快能到到目标,不断重复知道实现达到目标状态;

  我们这里的估计方法为 当前状态的全部距离+走的步数;

  

  搜索过程可能描述如下:

(1)把初始节点S0放入Open表中,f(S0)=g(S0)+h(S0);

(2)如果Open表为空,则问题无解,失败退出;

(3)把Open表的第一个节点取出放入Closed表,并记该节点为n;

(4)考察节点n是否为目标节点。若是,则找到了问题的解,成功退出;

(5)若节点n不可扩展,则转到第(2)步;

(6)扩展节点n,生成子节点ni(i=1,2,……),计算每一个子节点的估价值f(ni) (i=1,2,……),并为每一个子节点设置指向父节点的指针,然后将这些子节点放入Open表中;

(7)根据各节点的估价函数值,对Open表中的全部节点按从小到大的顺序重新进行排序;

(8)转第(2)步。

  代码太长 截图不够,详细还是看代码吧:O(∩_∩)O

  

  

  我是把一步的搜索结果直接展示在视图中的,所以closed表中没有保留节点状态,单通过console.log输出,大家可以点击F12在调试模式下查看全部节点;

  若希望查看每一步视图状态,则可以在searchA方法的while循环中打断点查看效果;

  网上找个图说明一下搜索的方法:容易明白

  

js版九宫格拼图与启发式搜索(A*算法)的更多相关文章

  1. 原生JS实现九宫格拼图

    实现这个案例,需要考虑到鼠标的拖拽效果(onmousedown/onmousemove/mouseup) 拖拽分解: 按下鼠标---->移动鼠标----->松开鼠标 1.给目标元素添加on ...

  2. Twitter面试题蓄水池蓄水量算法(原创 JS版,以后可能会补上C#的)

    之前在群里有人讨论Twitter的面试题,蓄水池蓄水量计算,于是自己写了个JS版的(PS:主要后台代码还要编译,想想还是JS快,于是就使用了JS了.不过算法主要还是思路嘛,而且JS应该都没问题吧^_^ ...

  3. 常见排序算法(JS版)

    常见排序算法(JS版)包括: 内置排序,冒泡排序,选择排序,插入排序,希尔排序,快速排序(递归 & 堆栈),归并排序,堆排序,以及分析每种排序算法的执行时间. index.html <! ...

  4. LeetCode 算法题解 js 版 (001 Two Sum)

    LeetCode 算法题解 js 版 (001 Two Sum) 两数之和 https://leetcode.com/problems/two-sum/submissions/ https://lee ...

  5. 【干货】JS版汉字与拼音互转终极方案,附简单的JS拼音输入法

    前言 网上关于JS实现汉字和拼音互转的文章很多,但是比较杂乱,都是互相抄来抄去,而且有的不支持多音字,有的不支持声调,有的字典文件太大,还比如有时候我仅仅是需要获取汉字拼音首字母却要引入200kb的字 ...

  6. H5版俄罗斯方块(3)---游戏的AI算法

    前言: 算是"long long ago"的事了, 某著名互联网公司在我校举行了一次"lengend code"的比赛, 其中有一题就是"智能俄罗斯方 ...

  7. JS版汉字与拼音互转终极方案,附简单的JS拼音输入法

    原文:http://www.cnblogs.com/liuxianan/p/pinyinjs.html 前言 网上关于JS实现汉字和拼音互转的文章很多,但是比较杂乱,都是互相抄来抄去,而且有的不支持多 ...

  8. JS版汉字与拼音互转终极方案,附简单的JS拼音

    前言 网上关于JS实现汉字和拼音互转的文章很多,但是比较杂乱,都是互相抄来抄去,而且有的不支持多音字,有的不支持声调,有的字典文件太大,还比如有时候我仅仅是需要获取汉字拼音首字母却要引入200kb的字 ...

  9. 启发式搜索——A*算法

    启发式搜索 启发式搜索是一种对搜索到的每一个位置进行评估,然后从评估的最优位置进行搜索直到目的地, 由于搜索时对每一个位置的评估是基于直观或经验的所有叫启发式搜索 A*算法 历史: 1964年Nils ...

随机推荐

  1. freemarker自定义标签(二)

    freemarker自定义标签 1.自定义标签 通过自定义标签,写一个重复指定字符串 2.实现源码 <html> <head> <meta http-equiv=&quo ...

  2. faultString = "java.lang.NullPointerException : null"

    1.错误描述 (mx.messaging.messages::ErrorMessage)#0 body = (null) clientId = "E75F6AF8-5E0E-4184-3AF ...

  3. Flex中对表格中某列的值进行数字格式化并求百分比

    1.问题背景 一般的,需要对表格中某列的数值进行格式化,对该数值乘以100,并保留两位小数,添加"%" 2.实现实例 <?xml version="1.0" ...

  4. Web.config中设置启用webservice远程调试访问

    在.NET 中已经默认将webservice的远程调试功能关闭,有的时候我们需要远程调试程序的时候,就需要打开此功能我们只需在webservice的项目的中添web.config的<system ...

  5. javaWeb学习之页面js树

    常用方法add(parameters):添加节点信息 Index Name Type Discription 1 id Number 当前节点的ID 2 preId Number 当前节点的父节点ID ...

  6. Python基础__Python序列基本类型及其操作(1)

    本节考虑的Python的一个中要的内置对象序列, 所谓的序列即一个有序对象的集合.这里的对象可以是数字.字符串等.根据功能的不同将序列分为字符串.列表.元组,本文将以下这几种对象做一些介绍. 一. 字 ...

  7. 第二篇:操纵MySQL数据库(2) - 基于ORM思想的SQLAlchemy库

    前言 本文讲解在Python语言中使用SQLAlchemy库操纵MySQL数据库的方法. 由于具体内容涉及较多,本文仅以插入及展示数据为例,更多内容请查阅有关文档. ORM ORM也即对象 - 关系映 ...

  8. CF908G Original Order

    题目大意: 定义\(R(x) = 每个数在各数位排序后得到的数\) 例如:\(R(321597) = 123579\) 给定一个\(n<=10^{700}\),求\(\sum _{i=1}^n ...

  9. 【BZOJ4237】稻草人(CDQ分治,单调栈)

    [BZOJ4237]稻草人(CDQ分治,单调栈) 题面 BZOJ 题解 \(CDQ\)分治好题呀 假设固定一个左下角的点 那么,我们可以找到的右下角长什么样子??? 发现什么? 在右侧是一个单调递减的 ...

  10. 【NOI2014】起床困难综合症(贪心)

    [NOI2014]起床困难综合症(贪心) 题面 Description 21 世纪,许多人得了一种奇怪的病:起床困难综合症,其临床表现为:起床难,起床后精神不佳.作为一名青春阳光好少年,atm 一直坚 ...