二维瓦片网格边界检测

 

二维瓦片网格边界检测

1. 每个网格只考虑ENWS四个相邻格子

四个相邻格子ENSW编号为0~3

2. 当前方向D(0~3): 如果当前格子是上一个格子选择的ENSW(0~3)中的一个, 则这个选择就是当前方向

3. 选择下一个的策略:

按找以下优先级判断 (D+3)%4, (D+4)%4, (D+5)%4, (D+6)%4

(第一优选是右手侧, 最后一项是原路返回)

如果这四个点都不是, 则本点是孤立点.

4. 头节点

检测到的第一个边界点作为头节点, 把与头节点相邻的外界点(或者边界)看作上一个点.

如果是按照W->E, N->S的顺序检测, 则头节点的方向是E

5. 结束

当再次遇到头结点, 则结束

 

 

#include 

enum Dir {
  E = 0,
  N,
  W,
  S,

  DirMax
};

enum { Empty = 0, Full = 1, Flag = 2 };

struct Point {
  int x;
  int y;

  bool operator==(const Point& p) const { return x == p.x && y == p.y; }
  bool operator!=(const Point& p) const { return !(*this == p); }

  // 边界和外部
  bool CheckPoint(int* map, int w, int h) {
    if (x < 0 || y < 0) return false;
    if (x >= w || y >= h) return false;
    return map[y * w + x] != Empty;
  }

  // 相邻点
  void GetNearPoints(Point near[DirMax]) const {
    // E
    near[E].x = x + 1;
    near[E].y = y;

    // N
    near[N].x = x;
    near[N].y = y - 1;

    // W
    near[W].x = x - 1;
    near[W].y = y;

    // S
    near[S].x = x;
    near[S].y = y + 1;
  }

  // 下一个点
  Point GetNextPoint(int* map, int w, int h, Point near[DirMax], Dir& d) {
    for (int i = 0; i < DirMax; ++i) {
      Dir next_d = Dir((d + i + (DirMax-1)) % DirMax);
      if (near[next_d].CheckPoint(map, w, h)) {
        d = next_d;
        return near[next_d];
      }
    }

    // 孤点, 返回自己
    return *this;
  }
};

int main() {
  int map[][9] = {
{0, 0, 0, 1, 1, 1, 0, 0, 0},
{0, 0, 1, 1, 1, 1, 1, 0, 0},
{0, 1, 1, 1, 1, 1, 1, 1, 0},
{1, 1, 1, 1, 1, 0, 0, 0, 0},
{0, 0, 0, 1, 1, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 1, 1, 1, 1, 1, 1, 1, 0},
{0, 1, 1, 1, 1, 1, 1, 1, 0}, 
{0, 1, 1, 1, 1, 1, 1, 1, 0},
{0, 1, 1, 1, 1, 1, 0, 0, 0}, 
{0, 0, 0, 0, 0, 1, 1, 1, 1}};

  int w = 9;
  int h = 12;

  // 查找头点
  Point head = {0, 0};
  bool findHead = false;
  for (int i = 0; i < h && !findHead; ++i) {
    for (int j = 0; j < w; ++j) {
      head.x = j;
      head.y = i;
      if (head.CheckPoint(&map[0][0], w, h)) {
        findHead = true;
        break;
      }
    }
  }

  // (本程序只处理其中的一块区域, 并且不考虑内部空洞)
  if (!findHead) return 1;
  
  Point cur = head;
  Dir d = E;
  Point near[DirMax];
  do {
    map[cur.y][cur.x] = Flag;

    cur.GetNearPoints(near);
    cur = cur.GetNextPoint(&map[0][0], w, h, near, d);

  } while (cur != head);

  // 显示
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      std::cout << map[i][j];
    }
    std::cout << std::endl;
  }

  return 0;
}
/*
运行输出:
000222000
002212200
022122220
222220000
000220000
000200000
000200000
022222220
021111120
021112220
022222000
000002222
*/

 

你可能感兴趣的:(游戏,算法,AI)