国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

用C#開發智能手機軟件:推箱子(五)

2019-11-18 16:27:20
字體:
來源:轉載
供稿:網友

在這篇文章中介紹經過改進后的 Common/FindPath.cs 源程序文件。也就是說,已經實現了“使用 C# 開發智能手機軟件:推箱子(四)”的第二個評論中的想法,將地圖 ushort[,] map 改為 byte[,] map 了。下面就是改進后的 FindPath 類:

以下是引用片段:
1 using System;
  2 using System.Drawing;
  3 using System.Collections.Generic;
  4
  5 namespace Skyiv.Ben.PushBox.Common
  6 {
  7 /// 
  8 /// 尋找最短路線
  9 /// 
  10 static class FindPath
  11 {
  12 static Size[] offsets = { new Size(0, 1), new Size(1, 0), new Size(0, -1), new Size(-1, 0) };
  13 static Direction[] directions = { Direction.South, Direction.East, Direction.North, Direction.West };
  14
  15 /// 
  16 /// 尋找最短路線
  17 /// 
  18 /// 地圖
  19 /// 出發點
  20 /// 目的地
  21 /// 最短路線
  22 public static Queue Seek(byte[,] map, Point from, Point to)
  23 {
  24 Queue moveQueue = new Queue(); // 路線
  25 int value; // 與離目的地距離相關的一個量,變化規律:  => 2 => 1 => 3 => 2 => 1 => 3 => 2 => 1
  26 if (Seek(map, to, out value)) // 找到了一條路線
  27 {
  28 Point here = from; // 出發點(即工人的位置)
  29 Point nbr = new Point(); // 四周的鄰居
  30 for (value = (value + 1) % 3 + 1; here != to; value = (value + 1) % 3 + 1) // 逐步走向目的地
  31 {
  32 for (int i = 0; i < offsets.Length; i++)
  33 {
  34 nbr = Fcl.Add(here, offsets[i]); // 開始尋找四周的鄰居
  35 if (Block.Value(map[nbr.Y, nbr.X]) == value) // 就往這個方向走
  36 {
  37 moveQueue.Enqueue(directions[i]); // 路線向目的地延伸一步
  38 break;
  39 }
  40 }
  41 here = nbr; // 繼續前進
  42 }
  43 }
  44 Block.CleanAllMark(map); // 清除所有標志,恢復現場
  45 return moveQueue; // 所尋找的路線,如果無法到達目的地則為該路線的長度為零
  46 }
  47
  48 /// 
  49 /// 尋找最短路線,使用廣度優先搜索
  50 /// 
  51 /// 地圖
  52 /// 目的地
  53 /// 輸出:搜索完成時標記的值
  54 /// 是否成功
  55 static bool Seek(byte[,] map, Point to, out int value)
  56 {
  57 Queue q = new Queue();
  58 Block.Mark(ref map[to.Y, to.X], 1); // 從目的地開始往回尋找出發點,目的地標記為1
  59 Point nbr = Point.Empty; // 四周的鄰居
  60 for (; ; )
  61 {
  62 value = Block.Value(map[to.Y, to.X]) % 3 + 1; // 與離目的地距離相關的一個量,用作標記,變化規律:
  63 for (int i = 0; i < offsets.Length; i++) // 1 => 2 => 3 => 1 => 2 => 3 => 1 => 2 => 3 => 
  64 {
  65 nbr = Fcl.Add(to, offsets[i]); // 開始尋找四周的鄰居
  66 if (Block.IsMan(map[nbr.Y, nbr.X])) break; // 到達出發點(即工人的位置)
  67 if (Block.IsBlank(map[nbr.Y, nbr.X])) // 可以走的路
  68 {
  69 Block.Mark(ref map[nbr.Y, nbr.X], value); // 標記,防止以后再走這條路
  70 q.Enqueue(nbr); // 加入隊列,等待以后繼續尋找
  71 }
  72 }
  73 if (Block.IsMan(map[nbr.Y, nbr.X])) break; // 到達出發點
  74 if (q.Count == 0) return false; // 無法到達出發點
  75 to = q.Dequeue(); // 出隊,繼續尋找,這是廣度優先搜索,因為前面已經把四周能夠走的路全部加入隊列中了.
  76 }
  77 return true; // 找到一條路線
  78 }
  79 }
  80 }

  上面的源程序已經對搜索算法作了很好的注釋。我們還是來看兩幅反映算法運行時地圖上各標記值的圖片吧:

  

c#開發手機游戲推箱子

c#開發手機游戲推箱子

  圖中,帶圓圈的紅色的數字“1”是“目的地”,也就是算法開始的地方,因為該算法是從目的地開始往回尋找出發點。在改進后的算法中,標記值始終是在“1、2、3”這三個數中循環,而不是象以前一樣一直增大。在圖中,算法按“紅、黃、綠、藍、粉紅、青”的順序從目的地往外搜索,直到遇到“工人”而返回成功,或者填滿能夠到達的空地而返回失敗。

  算法經過這次改進,搜索的距離就不象原來一樣受限于 8192 步。而且也將地圖所占用的內存空間減少到原來的二分之一。

  這次改進,除了仔細重寫了 FindPath 類以外,程序其余地方只是將所有的“ushort”替換為“byte”就行了,因為本程序只在涉及地圖的地方使用過“ushort”。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宿迁市| 揭阳市| 镇平县| 丰顺县| 图们市| 海宁市| 繁峙县| 万全县| 隆昌县| 穆棱市| 岑溪市| 泗阳县| 凉城县| 历史| 兴隆县| 剑阁县| 敦煌市| 新巴尔虎右旗| 婺源县| 金湖县| 故城县| 平邑县| 闵行区| 乐至县| 明光市| 彝良县| 沭阳县| 七台河市| 洱源县| 山丹县| 博湖县| 如东县| 科尔| 天柱县| 西昌市| 靖宇县| 万山特区| 庄河市| 丰县| 兴文县| 上思县|