网格道路中的格子状态计算

一、分析

下图包含了由正方形格子组成的道路的全部形态。(没有斜向)

 

单个格子的状态共有6种:

 

 

已知构成道路的格子集合:[(x1,y1),(x2,y2)...(xn,yn)],(x,y)代表格子位置。计算道路上每个格子的状态。(格子坐标系,x右正,y上正)

因为每个格子有4个临边,对格子(x,y)有临边:

 左边 L: (x-1, y)

 上边 T: (x,y+1)

 右边 R: (x+1, y)

 下边 B: (x,y-1)


假设最终格子状态为s。计算过程:

1、设置s=无邻格

2、判断L,如果有格,则s=s + L,否则s不变。(s + L)含义为s增加L方向有邻格

3、按步骤2依次判断T R B。为了方便记,如果对应临边有道路格子,则记为1,没有记为0。对于一个格子描述其临边状态可表示为:_ _ _ _ 

                

State(LTRB):0000                 State(LTRB):1101             State(LTRB):1010          State(LTRB):1011      State(LTRB):1111            State(LTRB):0110

 

由图可见,(2)有4种旋转,(3)有两种,(4)有3种,(6)有4种。

 

二、主要思路

   //按位记录4个方向的邻格状态,有为1,无为0
   const int L = 1 << 0;
   const int T = 1 << 1;
   const int R = 1 << 2;
   const int B = 1 << 3;

   //计算x,y 格子的邻格状态
   int s = 0; // 初始为无邻格
   // 依次检查
   if(IsExist(x-1, y))
       s |= L;
   if(IsExist(x, y+1))
       s |= T;
   if(IsExist(x+1, y))
       s |= R;
   if(IsExist(x, y-1))
       s |= B;
   // 最终s的值可知道在各个方向上的邻格情况

 

三、实现

class Road
{
    //对邻格按左->上->右->下的顺序检查
    const int L = 1 << 0;
    const int T = 1 << 1;
    const int R = 1 << 2;
    const int B = 1 << 3;
    const int NONE = 0;

    // 坐标
    struct Coord
    {
        public int x;
        public int y;
    }

    /// 格子邻居
    struct Neibour
    {
        // 与格子的偏移量
        public int ox;
        public int oy;

        // 标识自己是哪个方向的邻居,左->上->右->下
        public int state;
    }

    // 邻居描述集合
    List<Neibour> _neibourMap = new List<Neibour>()
    {
        // 左
        new Neibour {  ox = -1, oy = 0, state = L },
        // 上
        new Neibour {  ox = 0, oy = 1, state = T },
        // 右
        new Neibour {  ox = 1, oy = 0, state = R },
        // 下
        new Neibour {  ox = 0, oy = -1, state = B }
    };

    int GetState(int x, int y)
    {
        var s = NONE;
        foreach (var neibour in _neibourMap)
        {
            if (IsExist(x + neibour.ox, y + neibour.oy))
                s |= neibour.state;
        }

        return s;
    }

    bool IsExist(int x, int y)
    {
        // TODO:判断是否存在
    }

    /// 格子状态对应的信息
    class StateInfo
    {
        // 比如表现
    }

    // 格子状态描述
    Dictionary<int, StateInfo> _stateInfoConfig = new Dictionary<int, StateInfo>()
    {
        // 单格路
        { NONE, new StateInfo()},
        // 末端
        { L, new StateInfo()},
        { T, new StateInfo()},
        { R, new StateInfo()},
        { B, new StateInfo()},
        // 转角
        { L | T, new StateInfo()},
        { T | R, new StateInfo()},
        { R | B, new StateInfo()},
        { B | L, new StateInfo()},
        // 直路 水平或竖直
        { L | R, new StateInfo()},
        { T | B, new StateInfo()},
        // T字路口
        { L | T | R, new StateInfo()},
        { T | R | B, new StateInfo()},
        { R | B | L, new StateInfo()},
        { B | L | T, new StateInfo()},
        // 十字路口
        { L | T | R | B, new StateInfo()}
    };

    /// 测试
    void Test(Coord[] coords)
    {
        foreach (var coord in coords)
        {
            var s = GetState(coord.x, coord.y);
            var info = _stateInfoConfig[s];
            Print(info);
        }
    }

    private void Print(StateInfo info)
    {
        //TODO:状态信息
    }
}

  

posted on 2018-11-21 18:06  dongzee  阅读(700)  评论(0编辑  收藏  举报