Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/modules/hover/MazeGenerator.cc @ 12080

Last change on this file since 12080 was 11043, checked in by landauf, 9 years ago

more cleanup & deleting member objects in destructor

  • Property svn:eol-style set to native
File size: 7.4 KB
Line 
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:
23 *      Manuel Meier
24 *   Co-authors:
25 *      Cyrill Burgener
26 *
27 *   Based on random-maze-generator by Sergey Kosarevsky, 2014
28 *   https://github.com/corporateshark/random-maze-generator
29 *
30 */
31
32/**
33    @file MazeGenerator.cc
34    @brief Implementation of the MazeGenerator class. Generates the maze.
35*/
36
37#include "MazeGenerator.h"
38
39#include <vector>
40
41#include "util/Output.h"
42#include "util/Math.h"
43
44namespace orxonox
45{
46    MazeGenerator::MazeGenerator(int numCells)
47    {
48        this->numCells_ = numCells;
49
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
55        this->levelcode_ = new int[ numCells_*numCells_ ];;
56        std::fill( levelcode_, levelcode_ + numCells_*numCells_, 0 );
57
58        this->maze_ = new unsigned char[ numCells_*numCells_ ];
59        std::fill( maze_, maze_ + numCells_*numCells_, 0 );
60
61        // current traversing position
62        this->ptX_ = 0;
63        this->ptY_ = 0;
64
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                          };
80
81        std::copy(headingX, headingX + 9, this->headingX_);
82        std::copy(headingY, headingY + 9, this->headingY_);
83        std::copy(mask,     mask + 9,     this->mask_);
84    }
85
86    MazeGenerator::~MazeGenerator()
87    {
88        delete[] this->levelcode_;
89        delete[] this->maze_;
90    }
91
92    /**
93    @brief
94        Checks if Direction is valid (for Maze-Generator)
95    */
96    bool MazeGenerator::isDirValid( eDirection Dir )
97    {
98        int NewX = ptX_ + headingX_[ Dir ];
99        int NewY = ptY_ + headingY_[ Dir ];
100
101        if ( !Dir || NewX < 0 || NewY < 0 || NewX >= numCells_ || NewY >= numCells_ ) return false;
102
103        return !maze_[ NewX + numCells_ * NewY ];
104    }
105
106    /**
107    @brief
108        Generates new Direction (for Maze-Generator)
109    */
110    eDirection MazeGenerator::getDirection()
111    {
112        eDirection Dir = eDirection( 1 << randomInt4() );
113
114        while ( true )
115        {
116            for ( int x = 0; x < 4; x++ )
117            {
118                if ( isDirValid( Dir ) ) { return eDirection( Dir ); }
119
120                Dir = eDirection( Dir << 1 );
121
122                if ( Dir > eDirection_Left ) { Dir = eDirection_Up; }
123            }
124
125            Dir = eDirection( ( maze_[ cellIdx() ] & 0xf0 ) >> 4 );
126
127            // nowhere to go
128            if ( !Dir ) return eDirection_Invalid;
129
130            ptX_ += headingX_[ Dir ];
131            ptY_ += headingY_[ Dir ];
132
133            Dir = eDirection( 1 << randomInt4() );
134        }
135    }
136
137    /**
138    @brief
139        Generates a Maze (for Maze-Generator)
140    */
141    void MazeGenerator::generateMaze()
142    {
143
144        for ( eDirection Dir = getDirection(); Dir != eDirection_Invalid; Dir = getDirection() )
145        {
146            maze_[ cellIdx() ] |= Dir;
147
148            ptX_ += headingX_[ Dir ];
149            ptY_ += headingY_[ Dir ];
150
151            maze_[ cellIdx() ] = mask_[ Dir ];
152        }
153    } 
154   
155    /**
156    @brief
157        Print Maze (for Debugging only)
158    */
159    void MazeGenerator::mazeOut(){
160        for ( int y = 0; y < numCells_; y++ )
161        {
162            for ( int x = 0; x < numCells_; x++ )
163            {
164                char v = maze_[ y * numCells_ + x ];
165                orxout()<<"[";
166                if ( ( v & eDirection_Up    ) ) orxout()<<"U";
167                else orxout()<<" ";
168                if ( ( v & eDirection_Right ) ) orxout()<<"R";
169                else orxout()<<" ";
170                if ( ( v & eDirection_Down  ) ) orxout()<<" ";
171                else orxout()<<" ";
172                if ( ( v & eDirection_Left  ) ) orxout()<<" ";
173                else orxout()<<" ";
174                orxout()<<"]";
175            }
176            orxout()<<endl;
177        }
178
179    }
180
181    /**
182    @brief
183        Print levelcode_ (for Debugging only)
184    */
185    void MazeGenerator::levelOut(){
186        for ( int y = 0; y < numCells_; y++ )
187        {
188            for ( int x = 0; x < numCells_; x++ )
189            {
190                orxout()<<"[";
191                if ( levelcode_[ y * numCells_ + x ] < 2) orxout()<<"U";
192                else orxout()<<" ";
193                if ( levelcode_[ y * numCells_ + x ] % 2 == 0) orxout()<<"R";
194                else orxout()<<" ";
195
196                orxout()<<" ";
197                orxout()<<" ";
198                orxout()<<"]";
199            }
200            orxout()<<endl;
201        }
202    }
203
204    /**
205    @brief
206        Generate levelcode_ from Maze
207    */
208    void MazeGenerator::renderMaze()
209    {
210        for ( int y = 0; y < numCells_; y++ )
211        {
212            for ( int x = 0; x < numCells_; x++ )
213            {
214                char v = maze_[ y * numCells_ + x ];
215
216                if ( !( v & eDirection_Up    ) && y >0) levelcode_[ y * numCells_ + x ] |= 2;
217                if ( !( v & eDirection_Right ) && x <(numCells_-1)) levelcode_[ y * numCells_ + x ] |= 1;
218            }
219        }
220
221        // leave an empty space in the middle of the maze
222        int lowerBound = numCells_ / 2 - 2;
223        int upperBound = numCells_ / 2 + 2;
224        for ( int y = lowerBound; y < upperBound; y++ )
225        {
226            for ( int x = lowerBound; x < upperBound; x++ )
227            {
228
229                if(y == lowerBound && x != upperBound)
230                    levelcode_[ y * numCells_ + x ] &= 2;
231                else if (x == upperBound && y != lowerBound)
232                    levelcode_[ y * numCells_ + x ] &= 1;
233                else if(x != upperBound)
234                    levelcode_[ y * numCells_ + x ] = 0;
235            }
236        }
237
238    }
239
240    // return the current index in maze_
241    int MazeGenerator::cellIdx()
242    {
243        return ptX_ + numCells_ * ptY_;
244    }
245
246    int MazeGenerator::randomInt()
247    {
248        return (rand() % numCells_);
249    }
250
251    int MazeGenerator::randomInt4()
252    {
253        return (rand() % 4);
254    }
255}
Note: See TracBrowser for help on using the repository browser.