我正在尝试以大小为100x100的二维数组随机生成房间。如果生成的房间与现有房间发生碰撞,则会为房间生成新点。生成代码在概念上有意义,但是当我尝试运行时,程序无休止地循环,并且检查日志会显示原因。
Room created successfully with dimensions x=0, y=0, width=976761120, height=809120052
出于某种原因,在第65-68行,在create_room()内部,房间的宽度和高度被随机分配了大量数字,当它们应该在1到11之间时。为了好玩,我运行了程序Valgrind使用选项--track-originins = 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;
}
答案 0 :(得分:2)
您有一些逻辑错误,最终会得到未初始化的值。
将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
的成员。