# dungeoncrawler

• 02-20-2011
bobknows
dungeoncrawler
hey, i am making a dungeoncrawler and was wondering what the best way to set up random movement for the monsters and moving the hero would be.

i am using a 9 by 9 array for the dungeon and moving them like this
hero
Code:

```void heromove() {     int movehero2;     char movehero;     retry:;     cout << "go" << endl;     bool hmoved;     hmoved = 1;     cin >> movehero;     if(movehero == 'w')     {         movehero2 = 1;     }     else if(movehero == 'a')     {         movehero2 = 2;     }     else if(movehero == 's')     {         movehero2 = 3;     }     else if(movehero == 'd')     {         movehero2 = 4;     }     switch(movehero2)     {         case 1:         {             dungeon[heroposition[0]][heroposition[1]] = 'O';             heroposition[0]++;             if(heroposition[0] < 0 || heroposition[0] >= 9)             {                 cout << "you cant move through walls, try again.\n";                 heroposition[0]--;                 hmoved = 0;             }             dungeon[heroposition[0]][heroposition[1]] = 'H';             break;         }         case 2:         {             dungeon[heroposition[0]][heroposition[1]] = 'O';             heroposition[1]--;             if(heroposition[1] < 0 || heroposition[1] >= 9)             {                 cout << "you cant move through walls, try again.\n";                 heroposition[1]++;                 hmoved = 0;             }             dungeon[heroposition[0]][heroposition[1]] = 'H';             break;         }         case 3:         {             dungeon[heroposition[0]][heroposition[1]] = 'O';             heroposition[0]--;             if(heroposition[0] < 0 || heroposition[0] >= 9)             {                 cout << "you cant move through walls, try again.\n";                 heroposition[0]++;                 hmoved = 0;             }             dungeon[heroposition[0]][heroposition[1]] = 'H';             break;         }         case 4:         {             dungeon[heroposition[0]][heroposition[1]] = 'O';             heroposition[1]++;             if(heroposition[1] < 0 || heroposition[1] >= 9)             {                 cout << "you cant move through walls, try again.\n";                 heroposition[1]--;                 hmoved = 0;             }             dungeon[heroposition[0]][heroposition[1]] = 'H';             break;         }         default:         {             cout << "that is not valid input, try again.\n";             hmoved = 0;             break;         }     }     if(hmoved == 0)     {         goto retry;     }     return; }```
and doing something similar for the monsters, but using rand and time("NULL")

how can i improve these and what keeps it from working well?
i have some times where it will run fine and other times it will just return
go
go
go
go
go
thanks for any help
• 02-20-2011
auralius
in your case, when you select number randomly you must make sure it is between one to four.
better to give proper seeding for random number generator;

Code:

`srand(static_cast<unsigned>(time(NULL)));`
it will generate random number from 0 to 32767
you have to do something to make sure it is between 1 to 4.
• 02-21-2011
bobknows
i did, i used this:

Code:

```srand(time(NULL)); int randoms[500]; for(int a = 0; a < 500; a++) {     randoms[a] = (rand() % 4);     randoms[a]++; }```
what i really need is a better way to move a char in a char array.
• 02-22-2011
dwks
Code:

```/** Moves the unit currently at (x,y) by x_add in the x direction, y_add in the y direction.     Returns true upon success, false otherwise. */ bool move_unit(int x, int y, int x_add, int y_add) {     char unit = dungeon[x][y];     int new_x = x + x_add;     int new_y = y + y_add;     if(new_x < 0 || new_y < 0 || new_x >= 9 || new_y >= 9) {         return false;     }     dungeon[x][y] = ' ';  // or whatever the "clear" character is     dungeon[new_x][new_y] = unit;     return true; }```
If you had a function like that, your entire heromove() function could be replaced with
Code:

```void heromove() {     for(;;) {         cout << "Enter direction (w,a,s,d): ";         char direction;         cin >> direction;         int x_add = 0, y_add = 0;         if(direction == 'w') y_add --;         if(direction == 'a') x_add --;         if(direction == 's') y_add ++;         if(direction == 'd') x_add ++;         if(move_unit(heroposition[0], heroposition[1], x_add, y_add)) {             heroposition[0] += x_add;             heroposition[1] += y_add;             break;  // exit infinite for(;;) loop         }         else {             cout << "Invalid move, try again." << endl;         }     } }```
There are other ways to do this, of course. I tried to make my example understandable. But don't copy-paste code just to change a few --'s to ++'s!

Now I'm not really sure what your question is. If you have random monsters, presumably you're keeping track of them somehow. If there are monsterposition[] arrays you can use a similar scheme as the above. But even if you aren't remembering where monsters are, you could just use something like
Code:

```for(int x = 0; x < 9; x ++) {     for(int y = 0; y < 9; y ++) {         if(dungeon[x][y] == '!') {  // whatever monster symbol is             int x_add = 0, y_add = 0;             if(rand() % 2) {                 if(rand() % 2) x_add = -1;                 else x_add = +1;             }             else {                 if(rand() % 2) y_add = -1;                 else y_add = +1;             }             move_unit(x, y, x_add, y_add);  // don't care if this fails         }     } }```
If you want to be really fancy:
Code:

```void random_movement(int x, int y) {     int moves[][2] = {         {+1, 0},         {-1, 0},         {0, +1},         {0, -1}     };     int r = rand() % 4;     move_unit(x, y, moves[r][0], moves[r][1]); }```
I could typing code snippets all day but I'm not sure what your question is, so I'll stop . . . .
• 02-24-2011
bobknows
i dont have a monsterposition, i just test if there is an H character and if there is none i cout "you have lost", this allows you to kill monsters by moving onto them.

i will use thos code snippets like you said, i knew there was a better way i just didnt know how to make it. that was exactly what i needed, thanks
• 02-26-2011
bobknows
ok, i modified your snippets until they worked, but for some reason the monsters movement still dosent work,

sometimes it will run fine but other times the monsters will move multiple spaces or just appear randomly at the edges

here is the relevant code:
Code:

```void monstermove() {     int move_m = 0;     bool moved = 0;     for(int a = 0; a < 9; a++)     {         for(int b = 0; b < 9; b++)         {             if(dungeon[a][b] == 'X')             {                 moved = 0;                 while(!moved)                 {                     move_m = (rand() % 4);                     switch (move_m)                     {                         case 0:                             moved = move_unit(a, b, 1, 0, 0);                             break;                         case 1:                             moved = move_unit(a, b, -1, 0, 0);                             break;                         case 2:                             moved = move_unit(a, b, 0, -1, 0);                             break;                         case 3:                             moved = move_unit(a, b, 0, 1, 0);                             break;                     };                 }             }         }     } return; }```
and the modified move_unit
Code:

```bool move_unit(int x, int y, int x_add, int y_add, bool ishero) {     char unit = dungeon[x][y];     int new_x = x + x_add;     int new_y = y + y_add;     if(new_x < 0 || new_y < 0 || new_x >= 9 || new_y >= 9) {         return false;     }     if(!ishero)     {         if(dungeon[new_x][new_y] == 'S')         {             return false;         }     }     dungeon[x][y] = 'O';     dungeon[new_x][new_y] = unit;     return true; }```
• 03-16-2011
dwks
You're probably on to other programs now, but -- one issue with that code is that if the for loops notice an 'X', and move it to the right, the 'X' will be noticed in the next iteration and moved yet again. You could fix this by actually storing the positions of the monsters etc somewhere rather than just relying on the existence of the 'X'. Or you could build up a new dungeon[][] based on the old one and then once everything has moved, copy the new dungeon into the old one, replacing the data.

Something I didn't think of when I presented you my snippets, apparently. Sorry about that . . . .
• 03-17-2011
bobknows
thanks!!!
i have moved on but that was really bugging me.