Thread: dungeoncrawler

  1. #1
    Registered User
    Join Date
    Jan 2011
    Posts
    87

    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

  2. #2
    a newbie :p
    Join Date
    Aug 2008
    Location
    Zurich, Switzerland, Switzerland
    Posts
    91
    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.
    Last edited by auralius; 02-20-2011 at 09:55 PM. Reason: misstyping

  3. #3
    Registered User
    Join Date
    Jan 2011
    Posts
    87
    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.

  4. #4
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    First of all, use arrays to your advantage.
    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 . . . .
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  5. #5
    Registered User
    Join Date
    Jan 2011
    Posts
    87
    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

  6. #6
    Registered User
    Join Date
    Jan 2011
    Posts
    87
    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;
    }

  7. #7
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    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 . . . .
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  8. #8
    Registered User
    Join Date
    Jan 2011
    Posts
    87
    thanks!!!
    i have moved on but that was really bugging me.

Popular pages Recent additions subscribe to a feed