From 518619603ab3c49b7fdfcf19c439c1a30668164f Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Thu, 2 Apr 2015 15:28:31 -0600 Subject: Everything works, it could use more stuff. --- .gitignore | 6 ++ build.sh | 3 + src/cell.cpp | 11 +++ src/cell.h | 14 +++ src/main.cpp | 95 +++++++++++++++++++ src/map.cpp | 140 +++++++++++++++++++++++++++ src/map.h | 28 ++++++ src/position.cpp | 85 +++++++++++++++++ src/position.h | 24 +++++ src/renderascii.cpp | 264 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/renderascii.h | 18 ++++ src/renderpng.cpp | 266 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/renderpng.h | 18 ++++ src/worm.cpp | 124 ++++++++++++++++++++++++ src/worm.h | 23 +++++ 15 files changed, 1119 insertions(+) create mode 100644 .gitignore create mode 100644 build.sh create mode 100644 src/cell.cpp create mode 100644 src/cell.h create mode 100644 src/main.cpp create mode 100644 src/map.cpp create mode 100644 src/map.h create mode 100644 src/position.cpp create mode 100644 src/position.h create mode 100644 src/renderascii.cpp create mode 100644 src/renderascii.h create mode 100644 src/renderpng.cpp create mode 100644 src/renderpng.h create mode 100644 src/worm.cpp create mode 100644 src/worm.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5b77fa2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.png +*.exe +*.txt +/lost +.*.swp +*.o diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..5e8bb26 --- /dev/null +++ b/build.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +exec g++ src/*.cpp -o lost.exe -L/usr/lib -lpng16 -I/usr/include -lz diff --git a/src/cell.cpp b/src/cell.cpp new file mode 100644 index 0000000..4aeb32d --- /dev/null +++ b/src/cell.cpp @@ -0,0 +1,11 @@ +#include "cell.h" + +#include + +Cell::Cell() : + iWalls( 0 ), + iDist( 0 ), + iPath( 0 ) +{ +} + diff --git a/src/cell.h b/src/cell.h new file mode 100644 index 0000000..4fb137e --- /dev/null +++ b/src/cell.h @@ -0,0 +1,14 @@ +#ifndef CELL_H +#define CELL_H + +class Cell +{ +public: + Cell(); + + int iWalls; + int iDist; + int iPath; +}; + +#endif diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..ef3f3de --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,95 @@ +#include + +#include "map.h" +#include "cell.h" +#include "position.h" +#include "worm.h" +#include "renderascii.h" +#include "renderpng.h" + +#include +#include + +int main( int argc, char *argv[] ) +{ + srand( time( NULL ) ); + + if( argc <= 2 ) + { + printf( + "Specify dimensions as paramters, and at least two e.g.:\n" + " %s 10 10\n" + " %s 5 5 5\n" + " %s 10 5 8 3\n" + "\n", + argv[0], argv[0], argv[0] + ); + return 0; + } + + Position p( argc-1 ); + bool bOk = false; + for( int j = 0; j < argc-1; j++ ) + { + int tmp = strtol( argv[j+1], NULL, 10 ); + if( tmp > 1 ) + { + bOk = true; + } + p[j] = tmp; + } + if( !bOk ) + { + printf("At least one dimension must be greater than 1.\n"); + return 0; + } + +// Position p( 4, 4, 4, 4, 4 ); +// Position p( 3, 5, 5, 5 ); + Map m( p ); + for( int j = 0; j < p.getDims(); j++ ) + p[j]--; + + int iCount = 2; + Worm **pWorm = new Worm*[iCount]; + pWorm[0] = new Worm( 1, Position( p.getDims() ), m ); + pWorm[1] = new Worm( 2, p, m ); +/* + Position t( p.getDims() ); + pWorm[0] = new Worm( 1, t, m ); + t[0] = p[0]; + pWorm[1] = new Worm( 2, t, m ); + */ + + while( iCount > 0 ) + { + for( int j = 0; j < iCount; j++ ) + { + if( pWorm[j]->timestep() == false ) + { + delete pWorm[j]; + if( j < iCount-1 ) + { + pWorm[j] = pWorm[iCount-1]; + pWorm[iCount-1] = 0; + j--; + } + else + { + pWorm[j] = 0; + } + iCount--; + } + } + } + + m.connect( 1, 2 ); + +// RenderAscii r( m ); + RenderPng r( m ); + r.render(); + + + return 0; +} + diff --git a/src/map.cpp b/src/map.cpp new file mode 100644 index 0000000..17f9bd8 --- /dev/null +++ b/src/map.cpp @@ -0,0 +1,140 @@ +#include "map.h" +#include "cell.h" +#include "position.h" + +#include +#include +#include + +Map::Map( const Position &rpMax ) : + iDims( rpMax.getDims() ), + aiSize( 0 ), + acMap( 0 ) +{ + int iTotal = 1; + aiSize = new int[iDims]; + for( int j = 0; j < iDims; j++ ) + { + aiSize[j] = rpMax[j]; + iTotal *= aiSize[j]; + } + acMap = new Cell[iTotal]; +} + +Map::~Map() +{ + delete[] aiSize; + delete[] acMap; +} + +Cell &Map::operator[]( const Position &rpIdx ) const +{ + return acMap[getIndex( rpIdx )]; +} + +Cell &Map::operator[]( const Position &rpIdx ) +{ + return acMap[getIndex( rpIdx )]; +} + +int Map::getDims() const +{ + return iDims; +} + +int Map::getSize( int iDim ) const +{ + return aiSize[iDim]; +} + +int Map::getIndex( const Position &rpIdx ) const +{ + if( !isInside( rpIdx ) ) + throw std::exception(); + + int iIdx = 0; + int iScale = 1; + for( int j = 0; j < iDims; j++ ) + { + iIdx += rpIdx[j]*iScale; + iScale *= aiSize[j]; + } + return iIdx; +} + +bool Map::isInside( const Position &rpIdx ) const +{ + if( rpIdx.getDims() != iDims ) + throw std::exception(); + + for( int j = 0; j < iDims; j++ ) + { + if( rpIdx[j] < 0 ) + return false; + if( rpIdx[j] >= aiSize[j] ) + return false; + } + + return true; +} + +int opposite( int iDir ); + +void Map::connect( int iId1, int iId2 ) +{ + Position p( iDims ); + + Position pMax1, pMax2; + int iDistMax = 0; + int iDirMax = 0; + + int iDim; + for(;;) + { + Cell &c = (*this)[p]; + if( c.iPath == iId1 || c.iPath == iId2 ) + { + // Could be the thing! + for( iDim = 0; iDim < iDims; iDim++ ) + { + Position t( p ); + t[iDim]--; + for( int iDir = 0; iDir < 2; iDir++ ) + { +// int w = (1<<(iDim*2+iDir)); + if( t[iDim] >= 0 && t[iDim] < aiSize[iDim] ) + { + Cell &c2 = (*this)[t]; + if( c.iPath != c2.iPath && + (c2.iPath == iId1 || c2.iPath == iId2) ) + { + int iDist = c.iDist+c2.iDist; + if( iDist > iDistMax ) + { + iDistMax = iDist; + pMax1 = p; + pMax2 = t; + iDirMax = iDim*2+iDir; + } + } + } + t[iDim] += 2; + } + } + } + + for( iDim = 0; iDim < iDims; iDim++ ) + { + if( ++p[iDim] < aiSize[iDim] ) + break; + p[iDim] = 0; + } + if( iDim == iDims ) + break; + } + + (*this)[pMax1].iWalls |= (1< +#include +#include + +Position::Position() : + iDims( 0 ), + aiValues( 0 ) +{ +} + +Position::Position( int iDims ) : + iDims( iDims ), + aiValues( 0 ) +{ + aiValues = new int[iDims]; + memset( aiValues, 0, sizeof(int)*iDims ); +} + +Position::Position( int iDims, int iX, ...) : + iDims( iDims ), + aiValues( 0 ) +{ + aiValues = new int[iDims]; + memset( aiValues, 0, sizeof(int)*iDims ); + + aiValues[0] = iX; + va_list ap; + va_start( ap, iX ); + for( int j = 1; j < iDims; j++ ) + { + aiValues[j] = va_arg( ap, int ); + } + va_end( ap ); +} + +Position::Position( const Position &rhs ) : + iDims( rhs.iDims ), + aiValues( 0 ) +{ + aiValues = new int[iDims]; + memcpy( aiValues, rhs.aiValues, sizeof(int)*iDims ); +} + +Position::~Position() +{ + delete[] aiValues; +} + +int Position::operator[]( int iIdx ) const +{ + if( iIdx < 0 ) + throw std::exception(); + else if( iIdx >= iDims ) + throw std::exception(); + + return aiValues[iIdx]; +} + +int &Position::operator[]( int iIdx ) +{ + if( iIdx < 0 ) + throw std::exception(); + else if( iIdx >= iDims ) + throw std::exception(); + + return aiValues[iIdx]; +} + +Position &Position::operator=( const Position &rhs ) +{ + delete[] aiValues; + iDims = rhs.iDims; + aiValues = new int[iDims]; + memcpy( aiValues, rhs.aiValues, sizeof(int)*iDims ); + + return *this; +} + +int Position::getDims() const +{ + return iDims; +} + diff --git a/src/position.h b/src/position.h new file mode 100644 index 0000000..0f044c6 --- /dev/null +++ b/src/position.h @@ -0,0 +1,24 @@ +#ifndef POSITION_H +#define POSITION_H + +class Position +{ +public: + Position(); + Position( int iDims ); + Position( int iDims, int iX, ...); + Position( const Position &rhs ); + virtual ~Position(); + + int operator[]( int iIdx ) const; + int &operator[]( int iIdx ); + Position &operator=( const Position &rhs ); + + int getDims() const; + +private: + int iDims; + int *aiValues; +}; + +#endif diff --git a/src/renderascii.cpp b/src/renderascii.cpp new file mode 100644 index 0000000..62a7028 --- /dev/null +++ b/src/renderascii.cpp @@ -0,0 +1,264 @@ +#include "renderascii.h" +#include "position.h" +#include "map.h" +#include "cell.h" + +#include +#include +#include + +RenderAscii::RenderAscii( Map &rMap ) : + rMap( rMap ) +{ +} + +RenderAscii::~RenderAscii() +{ +} + +void postProcess( char *buf, int w, int h ) +{ + static const char *cJunct[] = { + "", // 0 blank + "\xe2\x94\x80", // 1 left + "\xe2\x94\x80", // 2 right + "\xe2\x94\x80", // 1 2 left right + "\xe2\x94\x82", // 4 up + "\xe2\x94\x98", // 1 4 left up + "\xe2\x94\x94", // 2 4 right up + "\xe2\x94\xb4", // 1 2 4 left right up + "\xe2\x94\x82", // 8 down + "\xe2\x94\x90", // 1 8 left down + "\xe2\x94\x8c", // 2 8 right down + "\xe2\x94\xac", // 1 2 8 left right down + "\xe2\x94\x82", // 4 8 up down + "\xe2\x94\xa4", // 1 4 8 left up down + "\xe2\x94\x9c", // 2 4 8 right up down + "\xE2\x94\xBC", // 1 2 4 8 left right up down + "" + }; + /* +// Double lines + ' ', // 0 blank + '\xcd', // 1 left + '\xcd', // 2 right + '\xcd', // 1 2 left right + '\xba', // 4 up + '\xbc', // 1 4 left up + '\xc8', // 2 4 right up + '\xca', // 1 2 4 left right up + '\xba', // 8 down + '\xbb', // 1 8 left down + '\xc9', // 2 8 right down + '\xcb', // 1 2 8 left right down + '\xba', // 4 8 up down + '\xb9', // 1 4 8 left up down + '\xcc', // 2 4 8 right up down + '\xce', // 1 2 4 8 left right up down + '\0' + */ + + for( int y = 0; y < h; y++ ) + { + for( int x = 0; x < w; x++ ) + { + if( buf[x+y*w] == '+' ) + { + int iJunct = 0; + if( x > 0 && buf[(x-1)+y*w] == '-' ) + iJunct |= 1; + if( x < w-1 && buf[(x+1)+y*w] == '-' ) + iJunct |= 2; + if( y > 0 && buf[x+(y-1)*w] == '|' ) + iJunct |= 4; + if( y < h-1 && buf[x+(y+1)*w] == '|' ) + iJunct |= 8; + printf(cJunct[iJunct]); + } + else + { + switch( buf[x+y*w] ) + { + case '-': + printf("\xe2\x94\x80"); + break; + + case '|': + printf("\xe2\x94\x82"); + break; + + case '^': + printf("\xe2\x86\x91"); + break; + + case 'v': + printf("\xe2\x86\x93"); + break; + + default: + printf("%c", buf[x+y*w]); + break; + } + } + } + } +} + +void RenderAscii::render() +{ + static char cPassages[] = {"~~~~^v<>/*aAbBcCdDeE"}; + + printf("\xef\xbb\xbf"); + + int iDims = rMap.getDims(); + int iSize = 1; + if( iDims > 2 ) + iSize = (int)ceil(sqrt((rMap.getDims()-2)*2)); + + int iBufWidth = ((iSize+1)*rMap.getSize( 0 )+2); + int iBufHeight = (iSize+1)*rMap.getSize( 1 )+1; + int iBufSize = iBufWidth*iBufHeight+1; + + char *buf = new char[iBufSize]; + memset( buf, '\n', iBufSize ); + buf[iBufSize-1] = '\0'; + + Position p( iDims ); + for(;;) + { + int x = p[0]*(iSize+1); + int y = p[1]*(iSize+1); + int iWalls = rMap[p].iWalls; + + for( int iRow = 0; iRow < iSize+2; iRow++ ) + { + for( int iCol = 0; iCol < iSize+2; iCol++ ) + { + char &c = buf[x+iCol+(y+iRow)*iBufWidth]; + if( (iRow == 0 || iRow == iSize+1) && + (iCol == 0 || iCol == iSize+1) ) + c = '+'; + else if( iRow == 0 && (iWalls&(1<<2)) == 0 ) + c = '-'; + else if( iRow == iSize+1 && (iWalls&(1<<3)) == 0 ) + c = '-'; + else if( iCol == 0 && (iWalls&(1<<0)) == 0 ) + c = '|'; + else if( iCol == iSize+1 && (iWalls&(1<<1)) == 0 ) + c = '|'; + else + c = ' '; + } + } + + for( int j = 2; j < iDims; j++ ) + { + for( int side = 0; side < 2; side++ ) + { + int d = j*2+side; + if( iWalls&(1< 2 ) + { + printf("Floor: (%d", rMap.getSize(2)-p[2]); + for( int j = 3; j < iDims; j++ ) + { + printf(", %d", rMap.getSize(j)-p[j] ); + } + printf(")\n"); + } + + postProcess( buf, iBufWidth, iBufHeight ); +// printf(buf); + memset( buf, '\n', iBufSize ); + buf[iBufSize-1] = '\0'; + } + } + /* + printf("[%d", p[0]); + for( int j = 1; j < iDims; j++ ) + { + printf(", %d", p[j] ); + } + printf("]\n"); + */ + if( iDim == iDims ) + break; + } +// printf(buf); + + delete[] buf; +} +/* + int iSizeX = rMap.getSize( 0 ); + int iSizeY = 1; + if( iDims >= 2 ) + iSizeY = rMap.getSize( 1 ); + + for( int y = 0; y < iSizeY; y++ ) + { + for( int iRow = (y==0)?0:1; iRow < iSize+2; iRow++ ) + { + for( int x = 0; x < iSizeX; x++ ) + { + int iWalls = rMap[Position(2, x, y)].iWalls; + for( int iCol = (x==0)?0:1; iCol < iSize+2; iCol++ ) + { + if( (iRow == 0 || iRow == iSize+1 ) && + (iCol == 0 || iCol == iSize+1 )) + { + printf("+"); + } + else if( iRow == 0 ) + { + if( (iWalls&(1<<2)) == 0 ) + printf("-"); + else + printf(" "); + } + else if( iRow == iSize+1 ) + { + if( (iWalls&(1<<3)) == 0 ) + printf("-"); + else + printf(" "); + } + else if( iCol == 0 ) + { + if( (iWalls&(1<<0)) == 0 ) + printf("|"); + else + printf(" "); + } + else if( iCol == iSize+1 ) + { + if( (iWalls&(1<<1)) == 0 ) + printf("|"); + else + printf(" "); + } + else + printf(" "); + } + } + printf("\n"); + } + } +} +*/ diff --git a/src/renderascii.h b/src/renderascii.h new file mode 100644 index 0000000..6e9822b --- /dev/null +++ b/src/renderascii.h @@ -0,0 +1,18 @@ +#ifndef RENDER_ASCII_H +#define RENDER_ASCII_H + +class Map; + +class RenderAscii +{ +public: + RenderAscii( Map &rMap ); + virtual ~RenderAscii(); + + void render(); + +private: + Map &rMap; +}; + +#endif diff --git a/src/renderpng.cpp b/src/renderpng.cpp new file mode 100644 index 0000000..21d35ba --- /dev/null +++ b/src/renderpng.cpp @@ -0,0 +1,266 @@ +#include "renderpng.h" +#include "position.h" +#include "map.h" +#include "cell.h" + +#include +#include +#include +#include +#include + +RenderPng::RenderPng( Map &rMap ) : + rMap( rMap ) +{ +} + +RenderPng::~RenderPng() +{ +} + +void RenderPng::render() +{ + int iDims = rMap.getDims(); + int iSize = 1; + if( iDims > 2 ) + iSize = (int)ceil(sqrt((rMap.getDims()-2)*2)); + + int iBufWidth = ((iSize+1)*rMap.getSize( 0 )+1)*5; + int iBufHeight = ((iSize+1)*rMap.getSize( 1 )+1)*5; + int iBufSize = iBufWidth*iBufHeight; + uint8_t *pBuf = new uint8_t[iBufSize]; + uint8_t **pRows = new uint8_t*[iBufHeight]; + for( int r = 0; r < iBufHeight; r++ ) + { + pRows[r] = pBuf+(iBufWidth*r); + } + memset( pBuf, 1, iBufSize ); + + Position p( iDims ); + for(;;) + { + int x = p[0]*(iSize+1); + int y = p[1]*(iSize+1); + int iWalls = rMap[p].iWalls; + + for( int iRow = 0; iRow < iSize+2; iRow++ ) + { + for( int iCol = 0; iCol < iSize+2; iCol++ ) + { + if( (iRow == 0 || iRow == iSize+1) && + (iCol == 0 || iCol == iSize+1) ) + { + pRows[(y+iRow)*5+2][(x+iCol)*5+2] = 0; + if( iRow == 0 && iCol == 0 ) + { + if( (iWalls&(1<<2)) == 0 ) + { + for( int i = 0; i < 3; i++ ) + pRows[(y+iRow)*5+2][(x+iCol)*5+i+3] = 0; + } + if( (iWalls&(1<<0)) == 0 ) + { + for( int i = 0; i < 3; i++ ) + pRows[(y+iRow)*5+i+3][(x+iCol)*5+2] = 0; + } + } + else if( iRow == 0 && iCol == iSize+1 ) + { + if( (iWalls&(1<<2)) == 0 ) + { + for( int i = 0; i < 3; i++ ) + pRows[(y+iRow)*5+2][(x+iCol)*5+i] = 0; + } + if( (iWalls&(1<<1)) == 0 ) + { + for( int i = 0; i < 3; i++ ) + pRows[(y+iRow)*5+i+3][(x+iCol)*5+2] = 0; + } + } + else if( iRow == iSize+1 && iCol == 0 ) + { + if( (iWalls&(1<<3)) == 0 ) + { + for( int i = 0; i < 3; i++ ) + pRows[(y+iRow)*5+2][(x+iCol)*5+i+3] = 0; + } + if( (iWalls&(1<<0)) == 0 ) + { + for( int i = 0; i < 3; i++ ) + pRows[(y+iRow)*5+i][(x+iCol)*5+2] = 0; + } + } + else if( iRow == iSize+1 && iCol == iSize+1 ) + { + if( (iWalls&(1<<3)) == 0 ) + { + for( int i = 0; i < 3; i++ ) + pRows[(y+iRow)*5+2][(x+iCol)*5+i] = 0; + } + if( (iWalls&(1<<1)) == 0 ) + { + for( int i = 0; i < 3; i++ ) + pRows[(y+iRow)*5+i][(x+iCol)*5+2] = 0; + } + } + } + else if( iRow == 0 && (iWalls&(1<<2)) == 0 ) + { + for( int i = 0; i < 5; i++ ) + { + pRows[(y+iRow)*5+2][(x+iCol)*5+i] = 0; + } + } + else if( iRow == iSize+1 && (iWalls&(1<<3)) == 0 ) + { + for( int i = 0; i < 5; i++ ) + { + pRows[(y+iRow)*5+2][(x+iCol)*5+i] = 0; + } + } + else if( iCol == 0 && (iWalls&(1<<0)) == 0 ) + { + for( int i = 0; i < 5; i++ ) + { + pRows[(y+iRow)*5+i][(x+iCol)*5+2] = 0; + } + } + else if( iCol == iSize+1 && (iWalls&(1<<1)) == 0 ) + { + for( int i = 0; i < 5; i++ ) + { + pRows[(y+iRow)*5+i][(x+iCol)*5+2] = 0; + } + } + } + } + + for( int j = 2; j < iDims; j++ ) + { + for( int side = 0; side < 2; side++ ) + { + int d = j*2+side; + if( iWalls&(1< 2 ) + { + char buf[1024]; + sprintf( buf, "-%d", rMap.getSize(2)-p[2] ); + strcat( fname, buf ); + for( int j = 3; j < iDims; j++ ) + { + sprintf( buf, "-%d", rMap.getSize(j)-p[j] ); + strcat( fname, buf ); + } + } + strcat( fname, ".png"); + printf("Output: %s\n", fname ); + + png_structp png_ptr = png_create_write_struct( + PNG_LIBPNG_VER_STRING, NULL, NULL, NULL + ); + png_infop info_ptr = png_create_info_struct(png_ptr); + png_set_IHDR(png_ptr, info_ptr, iBufWidth, iBufHeight, + 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT + ); + png_color col[2]; + col[0].red = col[0].green = col[0].blue = 0; + col[1].red = col[1].green = col[1].blue = 255; + png_set_PLTE( png_ptr, info_ptr, col, 2); + + png_set_rows( png_ptr, info_ptr, pRows ); + + FILE *fp = fopen(fname, "wb"); + if( fp == NULL ) + { + printf("Error opening file!\n"); + exit( 1 ); + } + + png_init_io( png_ptr, fp ); + png_write_png( png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL ); + png_destroy_write_struct( &png_ptr, &info_ptr ); + fclose( fp ); + + memset( pBuf, 1, iBufSize ); + } + } + if( iDim == iDims ) + break; +/* + for( int j = 2; j < iDims; j++ ) + { + for( int side = 0; side < 2; side++ ) + { + int d = j*2+side; + if( iWalls&(1< + +Worm::Worm( int iId, const Position &rpStart, Map &rMap ) : + iId( iId ), + pCur( rpStart ), + rMap( rMap ), + iDist( 1 ) +{ + Cell &rCur = rMap[pCur]; + rCur.iDist = iDist; + rCur.iPath = iId; + + int iCount = 0; + int *iDirs = new int[2]; + if( pCur[0] == 0 ) + iDirs[iCount++] = 1; + else if( pCur[0] == rMap.getSize(0)-1 ) + iDirs[iCount++] = 2; + if( pCur[1] == 0 ) + iDirs[iCount++] = 4; + else if( pCur[1] == rMap.getSize(1)-1 ) + iDirs[iCount++] = 8; + + rCur.iWalls |= iDirs[rand()%iCount]; + delete[] iDirs; +} + +Worm::~Worm() +{ +} + +int opposite( int iDir ) +{ + if( iDir%2 == 1 ) + return iDir-1; + return iDir+1; +} + +bool Worm::timestep() +{ + int iDims = rMap.getDims(); + int iCount = 0; + Position *pDirs = new Position[iDims*2]; + int *iDirs = new int[iDims*2]; + + for(;;) + { + iCount = 0; + bool bFoundBack = false; + Position pBack; + for( int j = 0; j < iDims; j++ ) + { + int iSize = rMap.getSize( j ); + Position p1( pCur ); + p1[j]--; + if( p1[j] >= 0 ) + { + if( rMap[p1].iPath == 0 ) + { + iDirs[iCount] = j*2; + pDirs[iCount++] = p1; + } + else if( rMap[p1].iPath == iId && rMap[p1].iDist == iDist-1 ) + { + pBack = p1; + bFoundBack = true; + } + } + Position p2( pCur ); + p2[j]++; + if( p2[j] < iSize ) + { + if( rMap[p2].iPath == 0 ) + { + iDirs[iCount] = j*2+1; + pDirs[iCount++] = p2; + } + else if( rMap[p2].iPath == iId && rMap[p2].iDist == iDist-1 ) + { + pBack = p2; + bFoundBack = true; + } + } + } + + if( iCount > 0 ) + { + break; + } + else + { + if( bFoundBack ) + { + pCur = pBack; + iDist--; + } + else + { + delete[] pDirs; + delete[] iDirs; + return false; + } + } + } + + int iSel = rand()%iCount; + Cell &rCur = rMap[pCur]; + rCur.iWalls |= (1<