内容其实跟以前写的《十字链表的AOI算法实现》一样的,改一个C语言版本。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct DoubleNode {
int roleId;
int x;
int y;
struct DoubleNode* xPrev;
struct DoubleNode* xNext;
struct DoubleNode* yPrev;
struct DoubleNode* yNext;
} DoubleNode;
typedef struct Scene {
DoubleNode* _head;
DoubleNode* _tail;
} Scene;
void _add_node(struct Scene* scene, DoubleNode* node);
void _leave_scene(DoubleNode* node);
// 初始化场景
struct Scene* new_scene();
// 进入场景
DoubleNode* enter_scene(struct Scene* scene, int roleId, int x, int y);
// 离开场景
void leave_scene(DoubleNode* node);
// 场景内移动
void role_move(struct Scene* scene, DoubleNode* node, int x, int y);
// 获取AOI
void get_aoi(struct Scene* scene, DoubleNode* node, int xAreaLen, int yAreaLen);
// --------------------------------------------------
struct Scene* new_scene() {
struct Scene* scene = (struct Scene*)malloc(sizeof(struct Scene));
DoubleNode* _head = (struct DoubleNode*)malloc(sizeof(struct DoubleNode));
DoubleNode* _tail = (struct DoubleNode*)malloc(sizeof(struct DoubleNode));
_head->roleId = _head->x = _head->y = 0;
_tail->roleId = _tail->x = _tail->y = 0;
_head->xPrev = _tail->xNext = NULL;
_head->yPrev = _tail->yNext = NULL;
_head->xNext = _head->yNext = _tail;
_tail->xPrev = _tail->yPrev = _head;
scene->_head = _head;
scene->_tail = _tail;
return scene;
}
DoubleNode* enter_scene(struct Scene* scene, int roleId, int x, int y) {
DoubleNode* node = (DoubleNode*)malloc(sizeof(DoubleNode));
node->roleId = roleId;
node->x = x;
node->y = y;
_add_node(scene, node);
return node;
}
void _add_node(struct Scene* scene, DoubleNode* node) {
DoubleNode* cur = scene->_head->xNext;
while(cur != NULL){
if((cur->x > node->x) || cur == scene->_tail) {
node->xNext = cur;
node->xPrev = cur->xPrev;
cur->xPrev->xNext = node;
cur->xPrev = node;
break;
}
cur = cur->xNext;
}
cur = scene->_head->yNext;
while(cur != NULL){
if((cur->y > node->y) || cur == scene->_tail) {
node->yNext = cur;
node->yPrev = cur->yPrev;
cur->yPrev->yNext = node;
cur->yPrev = node;
break;
}
cur = cur->yNext;
}
}
void _leave_scene(DoubleNode* node) {
node->xPrev->xNext = node->xNext;
node->yPrev->yNext = node->yNext;
node->xNext->xPrev = node->xPrev;
node->yNext->yPrev = node->yPrev;
node->xPrev = node->xNext = NULL;
node->yPrev = node->yNext = NULL;
}
void leave_scene(DoubleNode* node) {
_leave_scene(node);
free(node);
}
void print_scene(struct Scene* scene) {
DoubleNode* cur = scene->_head->xNext;
while(cur != scene->_tail) {
printf("%d(%d, %d)\n", cur->roleId, cur->x, cur->y);
cur = cur->xNext;
}
printf("\n");
cur = scene->_head->yNext;
while(cur != scene->_tail) {
printf("%d(%d, %d)\n", cur->roleId, cur->x, cur->y);
cur = cur->yNext;
}
}
void role_move(struct Scene* scene, DoubleNode* node, int x, int y) {
_leave_scene(node);
node->x = x;
node->y = y;
_add_node(scene, node);
}
void get_aoi(struct Scene* scene, DoubleNode* node, int xAreaLen, int yAreaLen) {
DoubleNode* cur = node->xNext;
while(cur != scene->_tail){
if(cur->x < node->x + xAreaLen){
if(abs(cur->y - node->y) < yAreaLen){
printf("aoi = %d(%d, %d)\n", cur->roleId, cur->x, cur->y);
}
}else{
break;
}
cur = cur->xNext;
}
cur = node->xPrev;
while(cur != scene->_tail){
if(node->x < cur->x + xAreaLen){
if(abs(cur->y - node->y) < yAreaLen){
printf("aoi = %d(%d, %d)\n", cur->roleId, cur->x, cur->y);
}
}else{
break;
}
cur = cur->xPrev;
}
}
void main() {
struct Scene* scene = new_scene();
printf("\n== enter_scene == \n");
enter_scene(scene, 1001, 1, 5);
enter_scene(scene, 1002, 6, 6);
enter_scene(scene, 1003, 3, 1);
enter_scene(scene, 1004, 2, 2);
struct DoubleNode* node1 = enter_scene(scene, 1005, 5, 4);
struct DoubleNode* node2 = enter_scene(scene, 1006, 3, 3);
print_scene(scene);
printf("\n== leave_scene == \n");
leave_scene(node1);
print_scene(scene);
printf("\n== role_move == \n");
role_move(scene, node2, 2, 2);
print_scene(scene);
printf("\n== get_aoi == \n");
get_aoi(scene, node2, 2, 2);
}