一、分析
下图包含了由正方形格子组成的道路的全部形态。(没有斜向)
单个格子的状态共有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:状态信息
}
}