N-Puzzle Game

N-Puzzle 是一种滑块类推盘游戏,常见的有15-puzzle和8-puzzle。

如下图所示,由15个方块和一个空位组成,规则很简单,移动方块,让所有的方块按照数字的顺序排列。

 使用Silverlight实现如下:

Get Microsoft Silverlight

 那么如何使用算法来解决15-puzzle,已得到一个在任意状态下到达最终按顺序排列的一个路径呢?
IDA*(Iterative Deepening A*) 算法

IDA*是迭代加深的A*算法,深度优先,一次只记录一条路径,减少空间需求。

简单来说,给定一个限定值limit,开始深度优先搜索,当前节点的F()(估值函数)值超过limit时结束,然后每次增加limit,循环迭代搜索直到找到最终路径。

1. GoalState : 最终按数字顺序排列的状态

2. StartState : 任意打乱顺序的开始状态

3. IsResolved : 判断当前状态是否已达到GoalState

4. Manhattan Distance : 对于当前状态的任一点 P1(X1,Y1),到其值在目标状态的位置 P2(X2,Y2)的距离, D= Abs(X1-X2) + Abs(Y1-Y2)

算法如下:

View Code
 1     public class PuzzleNode 
 2     {
 3         public PuzzleNode(int[] state, int blank, PuzzleNode node)
 4         {
 5             this.state = state;
 6             this.BlankPosition = blank;
 7             this.parent = node;
 8             if (parent != null)
 9                 cost = parent.Cost + 1;
10         }
11 
12         /// <summary>
13         /// The current state
14         /// </summary>
15         /// <returns></returns>
16         public int[] CurrentState()
17         {
18             return state;
19         }
20 
21         /// <summary>
22         /// Total cost
23         /// </summary>
24         public int Cost { get { return cost; } }
25 
26         /// <summary>
27         /// The position of blank 
28         /// </summary>
29         public int BlankPosition { get; set; }
30 
31         /// <summary>
32         /// The move from parent to the current node
33         /// </summary>
34         public Direction Direction { get; set; }
35 
36         private int[] state;
37         private int cost;
38         private PuzzleNode parent;
39     }
View Code
 1 public List<PuzzleNode> IDAStar(int[] startboard)
 2 {
 3     int limit = SearchHelper.Heuristic(root);
 4 
 5     List<PuzzleNode> solution = null;
 6     List<PuzzleNode> path = new List<PuzzleNode>();
 7     path.Add(root);
 8     while (solution == null)
 9     {
10         solution = DepthLimitSearch(limit, path);
11         limit += 1;
12     }
13 
14     return solution;
15 }
16 
17 private List<PuzzleNode> DepthLimitSearch(int cost, List<PuzzleNode> path)
18 {
19     if (cost >= Int32.MaxValue)
20         throw new ArgumentException("cost over flow");
21 
22     var node = path.Last();
23     if (IsSolved(node))
24     {
25         return path;
26     }
27 
28     foreach (var child in GetSuccessors(node))
29     {
30         if (((int)child.Direction + (int)node.Direction != 0) && (SearchHelper.Heuristic(child) + child.Cost) <= cost)
31         {
32             var nextpath = new List<PuzzleNode>(path);
33             nextpath.Add(child);
34             var solution = DepthLimitSearch(cost, nextpath);
35             if (solution != null)
36             {
37                 return solution;
38             }
39         }
40     }
41     return null;

我们将数字换成图片,变成一个拼图游戏。大家来试一下吧。

Get Microsoft Silverlight

posted on 2012-07-02 22:27  蒲西  阅读(4637)  评论(0编辑  收藏  举报