Pointer list doesn't seem to fill.

Hello there,

I am currently making a sort of roguelike game, but there is an annoying error in the current dungeon generator.

This is the code:

From "Generator.cpp":
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include "Generator.h" //<-- This contains just a declaration of the class.

Rect::Rect(int var0, int var1, int var2, int var3)
{
    x1 = var0 - 1;
    y1 = var1 - 1;
    x2 = var0 + var2 + 1;
    y2 = var1 + var3 + 1;

    xCenter = (int) (x1 + x2) / 2;
    yCenter = (int) (y1 + y2) / 2;
}

/* Returns whether two Rectangles intersect each other. */
bool Rect::Intersect(Rect* var0Rect)
{
    if (x1 <= (var0Rect->x2) and x2 >= (var0Rect->x1) and
        y1 <= (var0Rect->y2) and y2 >= (var0Rect->y1))
    {
        return true;
    }
    else
    {
        return false;
    }
}

/* Creates a room. */
void Rect::CreateRoom(World* var0World)
{
    for (int par0 = x1; par0 <= x2; ++par0)
    {
        for (int par1 = y1; par1 <= y2; ++par1)
        {
            if (par0 == x1 || par0 == x2 || par1 == y1 || par1 == y2)
            {
                var0World -> TileWorld[par0][par1] -> Symbol = '\333';
                var0World -> TileWorld[par0][par1] -> Blocked = true;
                var0World -> TileWorld[par0][par1] -> BlockSight = true;
            }
            else
            {
                var0World -> TileWorld[par0][par1] -> Symbol = '.';
                var0World -> TileWorld[par0][par1] -> Blocked = false;
                var0World -> TileWorld[par0][par1] -> BlockSight = false;
            }
        }
    }
}

/* The dungeon generator */
void GenerateDungeon(World* var0World, int var1, int var2, int var3, int var4)
{
    srand( time( NULL ) ); /* From the C standard library */

    int par0 = floor((var3 * var4) / 120);
    if (par0 < 1)
    {
        par0 = 1;
    }

    Rect** par1Rect = new Rect*[par0];

    for (int par2 = 0; par2 < par0; ++par2)
    {
        par1Rect[par0] = new Rect(-1,-1,-1,-1);
    }

    for (int par3 = 0; par3 < par0; ++par3)
    {
        int par4 = rand() % 4 + 4;
        int par5 = rand() % 4 + 4;
        int par6 = rand() % (var3 - par4) + var1 + 1;
        int par7 = rand() % (var4 - par5) + var2 + 1;

        Rect * par8Rect = new Rect(par6,par7,par4,par5);

        bool par9Bool = false;
        if (par3 == 0)
        {
            par1Rect[par3] = &(*par8Rect);

            par8Rect -> CreateRoom(var0World);

            var0World->SpawnX = par8Rect->xCenter;
            var0World->SpawnY = par8Rect->yCenter;

            delete par8Rect;
        }
        else
        {
            bool par9Bool = true; /** Whether the room can be created */
            for (int par10 = 0; par10 < par3; ++par10)
            {
                if ((par8Rect->Intersect(par1Rect[par10])) == true)
                {
                    par9Bool = false;
                    break;
                }
            }

            if (par9Bool == true) // << this appears to be a glitchy (?) line. I will talk about this later.
            {
                par1Rect[par3] = &(*par8Rect);
                par8Rect -> CreateRoom(var0World);
            }

            delete par8Rect;
        }
    }
}


However, what I find very strange, it whenever I change this part:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
bool par9Bool = true; /** Whether the room can be created */
for (int par10 = 0; par10 < par3; ++par10)
{
    if ((par8Rect->Intersect(par1Rect[par10])) == true)
    {
        par9Bool = false;
        break;
    }
}

if (par9Bool == true)
{
    par1Rect[par3] = &(*par8Rect);
    par8Rect -> CreateRoom(var0World);
}


and change this line:

if (par9Bool == true)

by removing one of the equal-symbols, changing it into
if (par9Bool = true)

It does work, apart from the fact that all the rooms are messed up (overlap each other).

Can someone help me, because I can't figure it out.

- Ojima

ps.

Here is some other code, in case you need it:

From "World.cpp":
1
2
3
4
5
6
7
8
9
10
11
12
13
14
World::World()
{
    TileWorld = new Tile**[WORLD_WIDTH];
    for (int par0 = 0; par0 < WORLD_WIDTH; ++par0)
    {
        TileWorld[par0] = new Tile*[WORLD_HEIGHT];
        for (int par1 = 0; par1 < WORLD_HEIGHT; ++par1)
        {
            TileWorld[par0][par1] = new Tile(false,false,' ');
        }
    }

    GenerateDungeon(this,0,0,70,30);
}


From "Tile.cpp":
1
2
3
4
5
6
Tile::Tile(bool var0Bool, bool var1Bool, unsigned char var2UChar)
{
    Blocked = var0Bool;
    BlockSight = var1Bool;
    Symbol = var2UChar;
}
by removing one of the equal-symbols, changing it into
if (par9Bool = true)

It does work, apart from the fact that all the rooms are messed up (overlap each other).


You quite clearly cannot do this, because it is assignment not equality. I am not sure whether you knew that already. It works because the assignment will always be true, thus executing the body of the if statement.

But the problem is because of par9Bool being set to false (the room overlaps?). So you will have to figure out why this is so - have you tried the debugger?

My other question may not have anything to do with errors, but why does the generator.cpp file have Rect function definitions? Should they not be in a Rect.cpp file?

And why is GenerateDungeon not a class function?

Hope this helps :)
You quite clearly cannot do this, because it is assignment not equality. I am not sure whether you knew that already. It works because the assignment will always be true, thus executing the body of the if statement.


Ah, I didn't know it then returned 'true', so I was astonished why it "worked".

But the problem is because of par9Bool being set to false (the room overlaps?). So you will have to figure out why this is so - have you tried the debugger?


I think I've got it.

The problem is that I add a pointer to the list, and then immediately delete that pointer, thus removing it from the list.

However, the problem now is, that whenever I remove the two
delete par8Rect;
lines (line 88 and line 108), it causes the 'game' to crash immediately. (Code::Blocks says: Process terminated with status 0 (0 minutes, 0 seconds)).

I don't know why that is.

My other question may not have anything to do with errors, but why does the generator.cpp file have Rect function definitions? Should they not be in a Rect.cpp file?

And why is GenerateDungeon not a class function?


I've now changed that. The "Rect"-class has now its own .cpp and .h file, and "Generator" is now a class.



I hope you (or someone else) can help me with the new problem.

- Ojima
However, the problem now is, that whenever I remove the two
delete par8Rect;
lines (line 88 and line 108), it causes the 'game' to crash immediately.


Are you sure? Did you test that conclusion using the debugger? The Code::Blocks message doesn't tell you where the program exited, you should use the debugger to find that out. I don't see why not deleting an object would cause the program to crash - normally the converse might be true, because one tries to refer to the deleted object later.

On another idea, your variables names are not very helpful to understanding what is happening - var1, var2, par4, par5 etc are not good variable names. After changing the names, maybe you can put in some comments to explain what all the variable names mean?

With this:
par1Rect[par3] = &(*par8Rect);

Why the address of a dereference ?
Okay, so I updated the code and renamed the variables (you were right, it was quite a mess).

I have no idea how the debugger in CodeBlocks works, but here's what happens whenever I click the "start debugger" button (or press F8):

- It starts, I see a black screen and in the console it says "warning: GDB: Failed to set controlling terminal: Operation not permitted". The screens get disabled and in the "call stack" screen, I can see these 6 lines:
(exactly copied)
Nr Address    Function            File
0  (          0x080491db in ??()
1  (          0x0804903f in ??()
2  (          0x080496b8 in ??()
3  (          0x08049296 in ??()
4  (          0x08048ad1 in ??()
5  0xb7c754d3 __libc_start_main() /lib/i386-linux-gnu/libc.so.6
6  (          0x08048c61 in ??()


In the message log, it says:

Debugger name and version: GNU gdb (GDB) 7.5-ubuntu
Child process PID: 14020
Program received signal SIGSEGV, Segmentation fault.
In ?? () ()


I have no idea what's going on, and I have no idea how the debugger works.

I hope you do, because I'm out of ideas.

- Ojima.

ps.

Oh, and this part:

par1Rect[par3] = &(*par8Rect);

I changed that already. I forgot it was there in the sample I posted. It is now similar to

par1Rect[par3] = par8Rect;
Can you get your code back to something similar (change to sensible variable names) to when it didn't crash?

I am not familiar with Code Blocks - maybe you can Google for help on how to use the debugger in CB. I am sure there are plenty of others on this site who do know how. Sounds as though it is a setting somewhere about the terminal - it might just fire up the shell version of gdb & not use the GUI?

gdb can be used form the shell - though you will have to learn how to use it - there is an article in the Articles section of this site (top left of this screen).

In terms of debugging, you could go the super basic route of doing cout statements everywhere to see what values are what, or even just find out where the program gets to before it crashes.

I use KDevelop and everything works fine through the GUI. All I had to do was tell it which debugger to use. KDEvelop is supposed to be a very mature application, so I have heard. I can't really compare because the only other one I have used is QtCreator - which is also supposed to be good for things like cross compiling & integration with all kinds of other technologies.

Topic archived. No new replies allowed.