Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentationHS15/src/modules/hover/MazeGenerator.cc @ 11042

Last change on this file since 11042 was 11040, checked in by landauf, 8 years ago

hover: maze size is now fully configurable in xml

  • Property svn:eol-style set to native
File size: 7.3 KB
RevLine 
[10658]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
[10930]23 *      Manuel Meier
[10658]24 *   Co-authors:
[11036]25 *      Cyrill Burgener
[10658]26 *
[11036]27 *   Based on random-maze-generator by Sergey Kosarevsky, 2014
28 *   https://github.com/corporateshark/random-maze-generator
29 *
[10658]30 */
31
32/**
[11035]33    @file MazeGenerator.cc
34    @brief Implementation of the MazeGenerator class. Generates the maze.
[10658]35*/
36
[11035]37#include "MazeGenerator.h"
[10708]38
[10894]39#include <vector>
[10835]40
[11035]41#include "util/Output.h"
42#include "util/Math.h"
43
[10658]44namespace orxonox
45{
[11040]46    MazeGenerator::MazeGenerator(int numCells)
[10835]47    {
[11040]48        this->numCells_ = numCells;
49
[11035]50        //levelcode_ represents the pitch: It's a 10x10 field.
51        // 1 represents a Wall on the right side of this square
52        // 2 represents a Wall on the top of this square
53        // 3 represents 2 and 1 at the same time
54        // Note: the levelcode_ is generated from the Maze-Generator functions at the beginning of the game
[11040]55        this->levelcode_ = new int[ numCells_*numCells_ ];;
56        std::fill( levelcode_, levelcode_ + numCells_*numCells_, 0 );
[10835]57
[11040]58        this->maze_ = new unsigned char[ numCells_*numCells_ ];
59        std::fill( maze_, maze_ + numCells_*numCells_, 0 );
[10835]60
[11035]61        // current traversing position
62        this->ptX_ = 0;
63        this->ptY_ = 0;
[10835]64
[11035]65        //                  0  1  2  3  4  5  6  7  8
66        //                     U  R     D           L
67        int headingX[9] = { 0, 0,+1, 0, 0, 0, 0, 0,-1 };
68        int headingY[9] = { 0,-1, 0, 0,+1, 0, 0, 0, 0 };
69        int mask[9]     = {
70                              0,
71                              eDirection_Down | eDirection_Down << 4,
72                              eDirection_Left | eDirection_Left << 4,
73                              0,
74                              eDirection_Up | eDirection_Up << 4,
75                              0,
76                              0,
77                              0,
78                              eDirection_Right | eDirection_Right << 4
79                          };
[10835]80
[11035]81        std::copy(headingX, headingX + 9, this->headingX_);
82        std::copy(headingY, headingY + 9, this->headingY_);
83        std::copy(mask,     mask + 9,     this->mask_);
[10658]84    }
85
[10930]86    /**
87    @brief
88        Checks if Direction is valid (for Maze-Generator)
89    */
[11035]90    bool MazeGenerator::isDirValid( eDirection Dir )
[10835]91    {
[11035]92        int NewX = ptX_ + headingX_[ Dir ];
93        int NewY = ptY_ + headingY_[ Dir ];
[10835]94
[11040]95        if ( !Dir || NewX < 0 || NewY < 0 || NewX >= numCells_ || NewY >= numCells_ ) return false;
[10835]96
[11040]97        return !maze_[ NewX + numCells_ * NewY ];
[10835]98    }
99
[10930]100    /**
101    @brief
102        Generates new Direction (for Maze-Generator)
103    */
[11035]104    eDirection MazeGenerator::getDirection()
[10835]105    {
[11035]106        eDirection Dir = eDirection( 1 << randomInt4() );
[10835]107
108        while ( true )
109        {
110            for ( int x = 0; x < 4; x++ )
111            {
[11035]112                if ( isDirValid( Dir ) ) { return eDirection( Dir ); }
[10835]113
114                Dir = eDirection( Dir << 1 );
115
116                if ( Dir > eDirection_Left ) { Dir = eDirection_Up; }
117            }
118
[11035]119            Dir = eDirection( ( maze_[ cellIdx() ] & 0xf0 ) >> 4 );
[10835]120
121            // nowhere to go
122            if ( !Dir ) return eDirection_Invalid;
123
[11035]124            ptX_ += headingX_[ Dir ];
125            ptY_ += headingY_[ Dir ];
[10835]126
[11035]127            Dir = eDirection( 1 << randomInt4() );
[10835]128        }
129    }
130
[10930]131    /**
132    @brief
133        Generates a Maze (for Maze-Generator)
134    */
[11035]135    void MazeGenerator::generateMaze()
[10835]136    {
137
[11035]138        for ( eDirection Dir = getDirection(); Dir != eDirection_Invalid; Dir = getDirection() )
[10835]139        {
[11035]140            maze_[ cellIdx() ] |= Dir;
[10835]141
[11035]142            ptX_ += headingX_[ Dir ];
143            ptY_ += headingY_[ Dir ];
[10835]144
[11035]145            maze_[ cellIdx() ] = mask_[ Dir ];
[10835]146        }
147    } 
148   
[10930]149    /**
150    @brief
151        Print Maze (for Debugging only)
152    */
[11035]153    void MazeGenerator::mazeOut(){
[11040]154        for ( int y = 0; y < numCells_; y++ )
[10835]155        {
[11040]156            for ( int x = 0; x < numCells_; x++ )
[10835]157            {
[11040]158                char v = maze_[ y * numCells_ + x ];
[10835]159                orxout()<<"[";
160                if ( ( v & eDirection_Up    ) ) orxout()<<"U";
161                else orxout()<<" ";
162                if ( ( v & eDirection_Right ) ) orxout()<<"R";
163                else orxout()<<" ";
164                if ( ( v & eDirection_Down  ) ) orxout()<<" ";
165                else orxout()<<" ";
166                if ( ( v & eDirection_Left  ) ) orxout()<<" ";
167                else orxout()<<" ";
168                orxout()<<"]";
169            }
170            orxout()<<endl;
171        }
172
173    }
174
[10930]175    /**
176    @brief
[11035]177        Print levelcode_ (for Debugging only)
[10930]178    */
[11035]179    void MazeGenerator::levelOut(){
[11040]180        for ( int y = 0; y < numCells_; y++ )
[10835]181        {
[11040]182            for ( int x = 0; x < numCells_; x++ )
[10835]183            {
[10930]184                orxout()<<"[";
[11040]185                if ( levelcode_[ y * numCells_ + x ] < 2) orxout()<<"U";
[10835]186                else orxout()<<" ";
[11040]187                if ( levelcode_[ y * numCells_ + x ] % 2 == 0) orxout()<<"R";
[10835]188                else orxout()<<" ";
189
190                orxout()<<" ";
191                orxout()<<" ";
[10930]192                orxout()<<"]";
[10835]193            }
194            orxout()<<endl;
195        }
196    }
197
[10930]198    /**
199    @brief
[11035]200        Generate levelcode_ from Maze
[10930]201    */
[11035]202    void MazeGenerator::renderMaze()
[10835]203    {
[11040]204        for ( int y = 0; y < numCells_; y++ )
[10835]205        {
[11040]206            for ( int x = 0; x < numCells_; x++ )
[10835]207            {
[11040]208                char v = maze_[ y * numCells_ + x ];
[10835]209
[11040]210                if ( !( v & eDirection_Up    ) && y >0) levelcode_[ y * numCells_ + x ] |= 2;
211                if ( !( v & eDirection_Right ) && x <(numCells_-1)) levelcode_[ y * numCells_ + x ] |= 1;
[10835]212            }
213        }
[11040]214
215        // leave an empty space in the middle of the maze
216        int lowerBound = numCells_ / 2 - 2;
217        int upperBound = numCells_ / 2 + 2;
218        for ( int y = lowerBound; y < upperBound; y++ )
[10835]219        {
[11040]220            for ( int x = lowerBound; x < upperBound; x++ )
[10835]221            {
222
[11040]223                if(y == lowerBound && x != upperBound)
224                    levelcode_[ y * numCells_ + x ] &= 2;
225                else if (x == upperBound && y != lowerBound)
226                    levelcode_[ y * numCells_ + x ] &= 1;
227                else if(x != upperBound)
228                    levelcode_[ y * numCells_ + x ] = 0;
[10835]229            }
230        }
231
232    }
233
[11035]234    // return the current index in maze_
235    int MazeGenerator::cellIdx()
236    {
[11040]237        return ptX_ + numCells_ * ptY_;
[11035]238    }
[10835]239
[11035]240    int MazeGenerator::randomInt()
241    {
[11040]242        return (rand() % numCells_);
[11035]243    }
[10835]244
[11035]245    int MazeGenerator::randomInt4()
246    {
247        return (rand() % 4);
248    }
[10658]249}
Note: See TracBrowser for help on using the repository browser.