我正在尝试在大小为 100x100 的二维数组中随机生成房间。如果正在生成的房间与已经存在的房间发生碰撞,它会为该房间生成新的点。生成代码在概念上是有意义的,但是当我尝试运行时,程序无限循环,检查日志揭示了原因。
Room created successfully with dimensions x=0, y=0, width=976761120, height=809120052
出于某种原因,在 create_room() 内部的第 65-68 行,房间的宽度和高度被随机分配为巨大的数字,而它们应该在 1 到 11 之间。为了好玩,我运行了程序Valgrind 使用选项 --track-origins=yes -v,我的发现让我感到惊讶。突然,程序运行起来了!
Room created successfully with dimensions x=0, y=0, width=0, height=0
虽然仍然不是我想要的,但这至少可以防止无限循环的碰撞被检测到一个不可能巨大的房间。
那么,我的问题是,为什么代码在正常执行时会生成如此大的数字,但在 Valgrind 中生成的数字却较小?
这是程序的代码。
#include <time.h>
#include <stdlib.h>
#include "global.h"
#include "draw.h"
#include "log.h"
#include "generate.h"
#define NUM_ROOMS 10
#define ROOM_SIZE 10
#define MAP_HEIGHT 100
#define MAP_WIDTH 100
static struct ROOM* create_room (unsigned int);
struct ROOM {
int x, y, width, height;
int feature;
};
struct ROOM* rooms[NUM_ROOMS] = {NULL};
static FILE* gen_log;
static WINDOW* gen_window;
int** generate_dungeon(unsigned int seed){
char* log_entry = malloc (80);
int i = 0, j, k;
gen_window = create_window (0, 0, LINES, COLS);
gen_log = log_open (GEN_LOG);
if (seed == 0){
time_t t;
seed = time (&t);
}
srand (seed);
for (int i = 0; i < NUM_ROOMS; i++){
rooms[i] = create_room (seed);
sprintf (log_entry,"Room created successfully with dimensions x=%d, y=%d, width=%d, height=%d\n", rooms[i]->x, rooms[i]->y, rooms[i]->width, rooms[i]->height);
LOG_DEBUG (gen_log,log_entry);
}
LOG_DEBUG(gen_log, "Beginning to draw rooms\n");
for (i=0;i < NUM_ROOMS;i++){
sprintf (log_entry, "Drawing room %d\n", i);
LOG_DEBUG (gen_log, log_entry);
for (j = rooms[i]->y; j < rooms[i]->y + rooms[i]->height; j++){
for (k = rooms[i]->x; k < rooms[i]->x + rooms[i]->width; k++){
sprintf (log_entry, "Clearing %d,%d]\n", j,k);
LOG_DEBUG (gen_log, log_entry);
map_array[j][k] = 1;
}
}
}
destroy_window (gen_window);
}
static struct ROOM* create_room (unsigned int seed){
int i = 0, flag;
srand (seed);
if (rooms[0] == NULL)
flag = 0;
else
flag = 1;
char* log_entry = malloc (80);
struct ROOM* new_room = malloc (sizeof(struct ROOM));
while (flag){
draw_notify (gen_window, "Creating room\n");
new_room->x = (rand() % MAP_WIDTH);
new_room->y = (rand() % MAP_HEIGHT);
new_room->width = (rand() % ROOM_SIZE + 1);
new_room->height = (rand() % ROOM_SIZE + 1);
sprintf (log_entry, "New room created with points x=%d, y=%d,width=%d, height=%d\n", new_room->x, new_room->y, new_room->width, new_room->height);
LOG_DEBUG (gen_log, log_entry);
draw_notify (gen_window, "Log entry made\n");
if (new_room->x + new_room->width >= MAP_WIDTH || new_room->y + new_room->height >= MAP_HEIGHT){
LOG_DEBUG (gen_log, "Room out of bounds\n");
continue;
}
i=0;
draw_notify(gen_window, "Entering loop\n");
while (rooms[i] != NULL && i < NUM_ROOMS){
sprintf (log_entry, "Testing room %d\n", i);
draw_notify (gen_window, log_entry);
LOG_DEBUG(gen_log, log_entry);
if (new_room->x < rooms[i]->x + rooms[i]->width &&
new_room->x + new_room->width > rooms[i]->x &&
new_room->y < rooms[i]->y + rooms[i]->height &&
new_room->y + new_room->height > rooms[i]->y){
sprintf (log_entry, "Collision detected with room %d\n", i);
draw_notify (gen_window, log_entry);
LOG_DEBUG (gen_log, log_entry);
flag = 1;
break;
}
else{
sprintf (log_entry, "Room %d passed.\n", i);
flag = 0;
i++;
}
}
draw_notify(gen_window, "Exited loop\n");
}
return new_room;
}
最佳答案
你有一些逻辑错误并以未初始化的值结束。
您将 rooms
初始化为 NULL 指针数组。
在 create_room
中,您有:
if (rooms[0] == NULL)
flag = 0;
else
flag = 1;
第一次,flag
将被设置为 0
。然后,您使用:
struct ROOM* new_room = malloc (sizeof(struct ROOM));
while (flag){
由于 flag
设置为 0
,while
下的任何内容都不会执行,您最终会在 new_room< 中得到未初始化的成员
.
您需要重新考虑您的逻辑并确保始终初始化 new_room
的成员。
关于c - rand() 在 valgrind 中使用时生成不同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32803956/