Code:
#include <windows.h>
#include <iostream>
#include <string>
// link with gdi32
#include <allegro5/allegro.h>
#include <allegro5/allegro_primitives.h>
//--------------------------------------------------------------------------------------------------
using namespace std;
//--------------------------------------------------------------------------------------------------
const int BMP_SIZE = 512, CELL_SIZE = 15;
//--------------------------------------------------------------------------------------------------
enum directions { NONE, NOR = 1, EAS = 2, SOU = 4, WES = 8 };
//--------------------------------------------------------------------------------------------------
class mazeGenerator
{
public:
mazeGenerator()
{
_world = 0;
///_bmp.create( BMP_SIZE, BMP_SIZE );
///_bmp.setPenColor( RGB( 0, 255, 0 ) );
}
~mazeGenerator() { killArray(); }
void create( int side )
{
_s = side;
generate();
display();
}
private:
void generate()
{
killArray();
_world = new BYTE[_s * _s];
ZeroMemory( _world, _s * _s );
_ptX = rand() % _s; _ptY = rand() % _s;
carve();
}
void carve()
{
while( true )
{
int d = getDirection();
if( d < NOR ) return;
switch( d )
{
case NOR:
_world[_ptX + _s * _ptY] |= NOR; _ptY--;
_world[_ptX + _s * _ptY] = SOU | SOU << 4;
break;
case EAS:
_world[_ptX + _s * _ptY] |= EAS; _ptX++;
_world[_ptX + _s * _ptY] = WES | WES << 4;
break;
case SOU:
_world[_ptX + _s * _ptY] |= SOU; _ptY++;
_world[_ptX + _s * _ptY] = NOR | NOR << 4;
break;
case WES:
_world[_ptX + _s * _ptY] |= WES; _ptX--;
_world[_ptX + _s * _ptY] = EAS | EAS << 4;
}
}
}
void display()
{
///_bmp.clear();
///HDC dc = _bmp.getDC();
for( int y = 0; y < _s; y++ )
{
int yy = y * _s;
for( int x = 0; x < _s; x++ )
{
BYTE b = _world[x + yy];
int nx = x * CELL_SIZE,
ny = y * CELL_SIZE;
if( !( b & NOR ) )
{
///MoveToEx( dc, nx, ny, NULL );
///LineTo( dc, nx + CELL_SIZE + 1, ny );
al_draw_line( nx, ny, nx + CELL_SIZE, ny, al_map_rgb(255, 0, 0), 1);
}
if( !( b & EAS ) )
{
///MoveToEx( dc, nx + CELL_SIZE, ny, NULL );
///LineTo( dc, nx + CELL_SIZE, ny + CELL_SIZE + 1 );
al_draw_line( nx + CELL_SIZE, ny, nx + CELL_SIZE, ny + CELL_SIZE, al_map_rgb(255, 0, 0), 1);
}
if( !( b & SOU ) )
{
///MoveToEx( dc, nx, ny + CELL_SIZE, NULL );
///LineTo( dc, nx + CELL_SIZE + 1, ny + CELL_SIZE );
al_draw_line( nx, ny + CELL_SIZE, nx + CELL_SIZE, ny + CELL_SIZE, al_map_rgb(255, 0, 0), 1);
}
if( !( b & WES ) )
{
///MoveToEx( dc, nx, ny, NULL );
///LineTo( dc, nx, ny + CELL_SIZE + 1 );
al_draw_line( nx, ny, nx, ny + CELL_SIZE, al_map_rgb(255, 0, 0), 1);
}
///al_flip_display(); //for testing purposes
///system("pause");
}
}
//_bmp.saveBitmap( "f:\\rc\\maze.bmp" );
///BitBlt( GetDC( GetConsoleWindow() ), 10, 60, BMP_SIZE, BMP_SIZE, _bmp.getDC(), 0, 0, SRCCOPY );
}
int getDirection()
{
int d = 1 << rand() % 4;
while( true )
{
for( int x = 0; x < 4; x++ )
{
if( testDir( d ) ) return d;
d <<= 1;
if( d > 8 ) d = 1;
}
d = ( _world[_ptX + _s * _ptY] & 0xf0 ) >> 4;
if( !d ) return -1;
switch( d )
{
case NOR: _ptY--; break;
case EAS: _ptX++; break;
case SOU: _ptY++; break;
case WES: _ptX--; break;
}
d = 1 << rand() % 4;
}
}
bool testDir( int d )
{
switch( d )
{
case NOR: return ( _ptY - 1 > -1 && !_world[_ptX + _s * ( _ptY - 1 )] );
case EAS: return ( _ptX + 1 < _s && !_world[_ptX + 1 + _s * _ptY] );
case SOU: return ( _ptY + 1 < _s && !_world[_ptX + _s * ( _ptY + 1 )] );
case WES: return ( _ptX - 1 > -1 && !_world[_ptX - 1 + _s * _ptY] );
}
return false;
}
void killArray() { if( _world ) delete [] _world; }
BYTE* _world;
int _s, _ptX, _ptY;
///myBitmap _bmp;
};
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
int main(void)
{
ALLEGRO_DISPLAY *display = NULL;
if(!al_init())
return -1;
display = al_create_display(640, 480);
if(!display)
return -1;
al_init_primitives_addon();
srand( GetTickCount() );
mazeGenerator mg;
int s;
while(true)
{
cout << "Enter the maze size, an odd number bigger than 2 ( 0 to QUIT ): "; cin >> s;
if( !s )
{
al_destroy_display(display);
return 0;
}
if( !( s & 1 ) ) s++;
if( s >= 3 ) mg.create( s );
cout << endl;
al_flip_display();
al_clear_to_color( al_map_rgb(0, 0, 0));
}
al_destroy_display(display);
return 0;
}
Here is my initial Irrlicht version:
Code:
#include <windows.h>
#include <iostream>
#include <string>
// link with gdi32
#include <irrlicht.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
//--------------------------------------------------------------------------------------------------
using namespace std;
//--------------------------------------------------------------------------------------------------
const int BMP_SIZE = 512, CELL_SIZE = 8;
float cubeSize = 4;
//--------------------------------------------------------------------------------------------------
enum directions { NONE, NOR = 1, EAS = 2, SOU = 4, WES = 8 };
int CreateMazeNode(IVideoDriver *driver, ISceneManager *smgr, ISceneNode* node, float x, float y, float z);
IVideoDriver *driver;
ISceneManager *smgr;
//--------------------------------------------------------------------------------------------------
class mazeGenerator
{
public:
mazeGenerator()
{
_world = 0;
///_bmp.create( BMP_SIZE, BMP_SIZE );
///_bmp.setPenColor( RGB( 0, 255, 0 ) );
}
~mazeGenerator() { killArray(); }
void create( int side )
{
_s = side;
generate();
display();
}
private:
void generate()
{
killArray();
_world = new BYTE[_s * _s];
ZeroMemory( _world, _s * _s );
_ptX = rand() % _s; _ptY = rand() % _s;
carve();
}
void carve()
{
while( true )
{
int d = getDirection();
if( d < NOR ) return;
switch( d )
{
case NOR:
_world[_ptX + _s * _ptY] |= NOR; _ptY--;
_world[_ptX + _s * _ptY] = SOU | SOU << 4;
break;
case EAS:
_world[_ptX + _s * _ptY] |= EAS; _ptX++;
_world[_ptX + _s * _ptY] = WES | WES << 4;
break;
case SOU:
_world[_ptX + _s * _ptY] |= SOU; _ptY++;
_world[_ptX + _s * _ptY] = NOR | NOR << 4;
break;
case WES:
_world[_ptX + _s * _ptY] |= WES; _ptX--;
_world[_ptX + _s * _ptY] = EAS | EAS << 4;
}
}
}
void display()
{
///_bmp.clear();
///HDC dc = _bmp.getDC();
ISceneNode *mazeNode[(_s * _s)];
int nodeCount = 0;
for( int y = 0; y < _s; y++ )
{
int yy = y * _s;
for( int x = 0; x < _s; x++ )
{
BYTE b = _world[x + yy];
int nx = x * CELL_SIZE,
ny = y * CELL_SIZE;
if( !( b & NOR ) )
{
///MoveToEx( dc, nx, ny, NULL );
CreateMazeNode(driver, smgr, mazeNode[nodeCount], nx, 0, ny);
nodeCount++;
///LineTo( dc, nx + CELL_SIZE + 1, ny );
CreateMazeNode(driver, smgr, mazeNode[nodeCount], nx + CELL_SIZE + cubeSize, 0, ny);
nodeCount++;
}
if( !( b & EAS ) )
{
///MoveToEx( dc, nx + CELL_SIZE, ny, NULL );
CreateMazeNode(driver, smgr, mazeNode[nodeCount], nx + CELL_SIZE, 0, ny);
nodeCount++;
///LineTo( dc, nx + CELL_SIZE, ny + CELL_SIZE + 1 );
CreateMazeNode(driver, smgr, mazeNode[nodeCount], nx + CELL_SIZE, 0, ny + CELL_SIZE + cubeSize);
nodeCount++;
}
if( !( b & SOU ) )
{
///MoveToEx( dc, nx, ny + CELL_SIZE, NULL );
CreateMazeNode(driver, smgr, mazeNode[nodeCount], nx, 0, ny + CELL_SIZE);
nodeCount++;
///LineTo( dc, nx + CELL_SIZE + 1, ny + CELL_SIZE );
CreateMazeNode(driver, smgr, mazeNode[nodeCount], nx + CELL_SIZE + cubeSize, 0, ny + CELL_SIZE + cubeSize);
nodeCount++;
}
if( !( b & WES ) )
{
///MoveToEx( dc, nx, ny, NULL );
CreateMazeNode(driver, smgr, mazeNode[nodeCount], nx, 0, ny);
nodeCount++;
///LineTo( dc, nx, ny + CELL_SIZE + 1 );
CreateMazeNode(driver, smgr, mazeNode[nodeCount], nx, 0, ny + CELL_SIZE + cubeSize);
nodeCount++;
}
///al_flip_display(); //for testing purposes
///system("pause");
}
}
//_bmp.saveBitmap( "f:\\rc\\maze.bmp" );
///BitBlt( GetDC( GetConsoleWindow() ), 10, 60, BMP_SIZE, BMP_SIZE, _bmp.getDC(), 0, 0, SRCCOPY );
}
int getDirection()
{
int d = 1 << rand() % 4;
while( true )
{
for( int x = 0; x < 4; x++ )
{
if( testDir( d ) ) return d;
d <<= 1;
if( d > 8 ) d = 1;
}
d = ( _world[_ptX + _s * _ptY] & 0xf0 ) >> 4;
if( !d ) return -1;
switch( d )
{
case NOR: _ptY--; break;
case EAS: _ptX++; break;
case SOU: _ptY++; break;
case WES: _ptX--; break;
}
d = 1 << rand() % 4;
}
}
bool testDir( int d )
{
switch( d )
{
case NOR: return ( _ptY - 1 > -1 && !_world[_ptX + _s * ( _ptY - 1 )] );
case EAS: return ( _ptX + 1 < _s && !_world[_ptX + 1 + _s * _ptY] );
case SOU: return ( _ptY + 1 < _s && !_world[_ptX + _s * ( _ptY + 1 )] );
case WES: return ( _ptX - 1 > -1 && !_world[_ptX - 1 + _s * _ptY] );
}
return false;
}
void killArray() { if( _world ) delete [] _world; }
BYTE* _world;
int _s, _ptX, _ptY;
///myBitmap _bmp;
};
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
int main(void)
{
IrrlichtDevice *device = createDevice(EDT_DIRECT3D9, dimension2d<u32>(640, 480), 16, false, false, false, 0);
if(!device)
return 1;
device->setWindowCaption(L"Maze Generator");
driver = device->getVideoDriver();
smgr = device->getSceneManager();
srand( GetTickCount() );
mazeGenerator mg;
int s;
cout << "Enter the maze size, an odd number bigger than 2 ( 0 to QUIT ): "; cin >> s;
if( !s )
{
device->drop();
return 0;
}
if( !( s & 1 ) ) s++;
if( s >= 3 ) mg.create( s );
cout << endl;
smgr->addCameraSceneNodeFPS();
s32 lastFPS = -1;
while(device->run())
{
driver->beginScene(true, true, SColor(255,0,0,0));
smgr->drawAll();
driver->endScene();
const s32 fps = driver->getFPS();
if (lastFPS != fps)
{
core::stringw str = L"Maze Generator [";
str += driver->getName();
str += "] FPS:";
str += fps;
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
}
device->drop();
return 0;
}
int CreateMazeNode(IVideoDriver *driver, ISceneManager *smgr, ISceneNode* node, float x, float y, float z)
{
node = smgr->addCubeSceneNode( cubeSize, 0, -1, core::vector3df(0, 0, 0), core::vector3df(0, 0, 0), core::vector3df(1.0f, 1.0f, 1.0f));
if(node)
{
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
node->setPosition(core::vector3df(x, y, z));
node->setMaterialTexture(0, driver->getTexture("hedge_texture.jpg"));
node->setMaterialFlag(video::EMF_LIGHTING, false);
node->setMaterialFlag(video::EMF_ANISOTROPIC_FILTER, true);
node->setMaterialFlag(video::EMF_ANTI_ALIASING, true);
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
return 1;
}
else
return 0;
}
My question is, what must you take into account when going 3D? Obviously there is the z axis, which I believe I have covered, and the y axis will just be how tall the maze is.