首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 開發智慧型手機軟體:推箱子遊戲(四)Common/FindPath.cs 程式碼原始碼

     編輯:關於C語言

前言

本文提供 Common/FindPath.cs 完整原始碼(優化前版本),供參考對比第 5 篇優化後版本。

完整原始碼


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;
        }

        static bool Seek(ushort[,] map, Point to, out int value)
        {
            Queue q = new Queue();
            Block.Mark(ref map[to.Y, to.X], 1);
            Point nbr = Point.Empty;
            for (;;)
            {
                value = Block.Value(map[to.Y, to.X]) + 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;
        }
    }
}

關鍵型別相依

  • Fcl.Add(Point, Size):座標加法(CF 相容)。
  • Block.Mark/Value/CleanAllMark/IsMan/IsBlank:位元操作與狀態查詢。
  • Direction:列舉 None, East, South, West, North (見 Step.cs)。

與優化後版本差異

項目原始版本優化後 (第 5 篇)
地圖型別ushort[,]byte[,]
標記值範圍1 ~ 8191 (距離+1)1, 2, 3 循環
最大搜尋距離8191 步無限制
記憶體佔用基準減半
Mark/Value 實作位移 3 bits,存完整距離僅用 2 bits 存 1~3

結語

此版本為演算法邏輯基準,理解其雙階段 BFS 流程後,再閱讀第 5 篇優化設計將更清晰。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved