在2D游戏的一张地图中随机分布着n个NPC,玩家君莫笑进入地图时随机出生在了一个坐标(x,y)。请找到距离玩家最近的NPC。假设地图大小为128*128,NPC和玩家均不能出现在地图外面。
在2D游戏的一张地图中随机分布着n个NPC,玩家君莫笑进入地图时随机出生在了一个坐标(x,y)。请找到距离玩家最近的NPC。假设地图大小为128*128,NPC和玩家均不能出现在地图外面。
参数一:整形,玩家出生坐标x
参数二:整形,玩家出生坐标y
参数三:整形,NPC数量n
参数四:NPC二维坐标数组的一维表示,使用字符串形式传入,注意逗号前后不要加空格,比如地图中有两个NPC,坐标分别是(32,33)和(25,25),则此处传入32,33,25,25
查询到的NPC坐标,注意坐标值前后有圆括号
32,48,3,33,40,40,50,32,45
(32,45)
NPC数量不超过1000个
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>
#define NOT !
#define NPC 2
typedef enum { UNKNOW = 0, OK = 1, ERROR = -1, MEMORY_OVERFLOW = -2 } Status;
typedef struct Coordinate {
int x;
int y;
} Coord;
// ==================== 链式队列存储结构表示与实现 ====================
typedef Coord QElemType;
typedef struct QNode {
QElemType data; // 链式队列节点的数据域
struct QNode* next; // 链式队列节点的指针域
} QNode, *PQNode;
typedef struct {
PQNode front; // 教材上front “始终” 指向头节点,而非首元节点
PQNode rear;
size_t length;
} LinkQueue;
Status InitQueue(LinkQueue* Q) {
if (!((*Q).front = (PQNode) calloc(1, sizeof(QNode)))) { // may be no enough space!
fprintf(stderr, "InitQueue Memory Overflow: %s\n", strerror(errno));
exit(MEMORY_OVERFLOW);
}
(*Q).rear = (*Q).front;
(*Q).length = 0;
return OK;
}
bool QueueEmpty(LinkQueue* Q) {
return (*Q).length == 0;
}
size_t QueueLength(LinkQueue* Q) {
return (*Q).length;
}
Status EnQueue(LinkQueue* Q, QElemType e) {
PQNode new_node = (PQNode) calloc(1, sizeof(QNode));
if (!new_node) { // may be no enough space!
fprintf(stderr, "EnQueue Memory Overflow: %s\n", strerror(errno));
exit(MEMORY_OVERFLOW);
}
(*new_node).data = e;
(*Q).rear = (*((*Q).rear)).next = new_node;
++(*Q).length;
return OK;
}
Status DeQueue(LinkQueue* Q, QElemType* e) {
if (QueueEmpty(Q)) {
fputs("DeQueue ERROR: The Queue is empty!\n", stderr);
return ERROR;
}
PQNode node_to_delete = (*(*Q).front).next;
*e = (*node_to_delete).data;
(*(*Q).front).next = (*node_to_delete).next;
if (!(*(*Q).front).next)
(*Q).rear = (*Q).front;
free(node_to_delete);
--(*Q).length;
return OK;
}
QElemType GetFront(LinkQueue* Q) {
if (QueueEmpty(Q)) {
fputs("DeQueue ERROR: The Queue is empty!\n", stderr);
return (Coord) {-1, -1};
}
return (*(*(*Q).front).next).data;
}
Status DestroyQueue(LinkQueue* Q) {
PQNode p = (*Q).front, next;
while (p) {
next = (*p).next;
free(p);
p = next;
}
(*Q).front = (*Q).rear = NULL;
return OK;
}
// ==================== 链式队列存储结构表示与实现 ====================
// ==================== memory static area ====================
const int N = 130; // 内存全局区,一般用来存放全局变量或静态变量
int board[N][N];
// ==================== memory static area ====================
// ==================== Function Prototype (函数原型区) ====================
void breadth_first_search_algorithm(const int sx, const int sy);
// ==================== Function Prototype ====================
int main(const int argc, const char* argv[]) {
int x, y, n;
fscanf(stdin, "%d,%d,%d", &y, &x, &n);
int tx, ty;
while (n--) {
fscanf(stdin, ",%d,%d", &ty, &tx);
*(*(board + ty) + tx) = NPC; // NPC
}
breadth_first_search_algorithm(x, y);
return 0;
}
void breadth_first_search_algorithm(const int sx, const int sy) {
usleep(900 * 1000);
LinkQueue Q;
InitQueue(&Q);
EnQueue(&Q, (Coord) {.x = sx, .y = sy});
*(*(board + sy) + sx) = 1; // mark as visited
static const int dirs[] = { 0, -1, 0, 1, 0 }; // 存放在全局区
Coord coord;
int i, x, y, nx, ny;
while (NOT QueueEmpty(&Q)) {
DeQueue(&Q, &coord);
x = coord.x, y = coord.y;
for (i = 0; i < 4; ++i) {
nx = x + *(dirs + i), ny = y + *(dirs + i + 1);
if (nx < 0 || ny < 0 || nx == 127 || ny == 127 || *(*(board + ny) + nx) == 1)
continue;
if (*(*(board + ny) + nx) == NPC) { // 找到了解
fprintf(stdout, "(%d,%d)", ny, nx);
DestroyQueue(&Q); // 把堆内存还给操作系统
return;
}
EnQueue(&Q, (Coord) {.x = nx, .y = ny});
*(*(board + ny) + nx) = 1;
}
}
DestroyQueue(&Q);
}