技术开发 频道

用C#开发智能手机软件:推箱子(四)


【IT168技术文档】

  在这篇文章中,介绍 Common/FindPath.cs 源程序文件。
using System;   using System.Drawing;   using System.Collections.Generic;   namespace Skyiv.Ben.PushBox.Common   {   ///   /// 寻找最短路线   ///   static class FindPath   {   static Size[] offsets = { new Size(0, 1), new Size(1, 0), new Size(0, -1), new Size(-1, 0) };   static Direction[] directions = { Direction.South, Direction.East, Direction.North, Direction.West };   ///   /// 寻找最短路线   ///   /// 地图   /// 出发点   /// 目的地   /// 最短路线   public static Queue Seek(ushort[,] map, Point from, Point to)   {   Queue moveQueue = new Queue(); // 路线   int value; // 离目的地距离   if (Seek(map, to, out value)) // 找到了一条路线   {   Point here = from; // 出发点(即工人的位置)   Point nbr = new Point(); // 四周的邻居   for (value--; value > 0; value--) // 逐步走向目的地   {   for (int i = 0; i < offsets.Length; i++)   {   nbr = Fcl.Add(here, offsets[i]); // 开始寻找四周的邻居   if (Block.Value(map[nbr.Y, nbr.X]) == value) // 就往这个方向走   {   moveQueue.Enqueue(directions[i]); // 路线向目的地延伸一步   break;   }   }   here = nbr; // 继续前进   }   }   Block.CleanAllMark(map); // 清除所有标志,恢复现场   return moveQueue; // 所寻找的路线,如果无法到达目的地则为该路线的长度为零   }   ///   /// 寻找最短路线,使用广度优先搜索   ///   /// 地图   /// 目的地   /// 输出:路线的长度(加1)   /// 是否成功   static bool Seek(ushort[,] map, Point to, out int value)   {   Queue q = new Queue();   Block.Mark(ref map[to.Y, to.X], 1); // 从目的地开始往回寻找出发点,目的地标记为1   Point nbr = Point.Empty; // 四周的邻居   for (; ; )   {   value = Block.Value(map[to.Y, to.X]) + 1; // 离开目的地的距离(加1),用作标记   for (int i = 0; i < offsets.Length; i++)   {   nbr = Fcl.Add(to, offsets[i]); // 开始寻找四周的邻居   if (Block.IsMan(map[nbr.Y, nbr.X])) break; // 到达出发点(即工人的位置)   if (Block.IsBlank(map[nbr.Y, nbr.X])) // 可以走的路   {   Block.Mark(ref map[nbr.Y, nbr.X], value); // 标记,防止以后再走这条路   q.Enqueue(nbr); // 加入队列,等待以后继续寻找   }   }   if (Block.IsMan(map[nbr.Y, nbr.X])) break; // 到达出发点   if (q.Count == 0) return false; // 无法到达出发点   to = q.Dequeue(); // 出队,继续寻找,这是广度优先搜索,因为前面已经把四周能够走的路全部加入队列中了.   }   return true; // 找到一条路线   }   }   }
0
相关文章