diff options
author | Mike Buland <mike@xagasoft.com> | 2015-04-02 15:28:31 -0600 |
---|---|---|
committer | Mike Buland <mike@xagasoft.com> | 2015-04-02 15:28:31 -0600 |
commit | 518619603ab3c49b7fdfcf19c439c1a30668164f (patch) | |
tree | dda7774f51bde150db91dac14718cc78f7571039 | |
download | lost-518619603ab3c49b7fdfcf19c439c1a30668164f.tar.gz lost-518619603ab3c49b7fdfcf19c439c1a30668164f.tar.bz2 lost-518619603ab3c49b7fdfcf19c439c1a30668164f.tar.xz lost-518619603ab3c49b7fdfcf19c439c1a30668164f.zip |
Everything works, it could use more stuff.
-rw-r--r-- | .gitignore | 6 | ||||
-rw-r--r-- | build.sh | 3 | ||||
-rw-r--r-- | src/cell.cpp | 11 | ||||
-rw-r--r-- | src/cell.h | 14 | ||||
-rw-r--r-- | src/main.cpp | 95 | ||||
-rw-r--r-- | src/map.cpp | 140 | ||||
-rw-r--r-- | src/map.h | 28 | ||||
-rw-r--r-- | src/position.cpp | 85 | ||||
-rw-r--r-- | src/position.h | 24 | ||||
-rw-r--r-- | src/renderascii.cpp | 264 | ||||
-rw-r--r-- | src/renderascii.h | 18 | ||||
-rw-r--r-- | src/renderpng.cpp | 266 | ||||
-rw-r--r-- | src/renderpng.h | 18 | ||||
-rw-r--r-- | src/worm.cpp | 124 | ||||
-rw-r--r-- | src/worm.h | 23 |
15 files changed, 1119 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5b77fa2 --- /dev/null +++ b/.gitignore | |||
@@ -0,0 +1,6 @@ | |||
1 | *.png | ||
2 | *.exe | ||
3 | *.txt | ||
4 | /lost | ||
5 | .*.swp | ||
6 | *.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 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | 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 @@ | |||
1 | #include "cell.h" | ||
2 | |||
3 | #include <stdio.h> | ||
4 | |||
5 | Cell::Cell() : | ||
6 | iWalls( 0 ), | ||
7 | iDist( 0 ), | ||
8 | iPath( 0 ) | ||
9 | { | ||
10 | } | ||
11 | |||
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 @@ | |||
1 | #ifndef CELL_H | ||
2 | #define CELL_H | ||
3 | |||
4 | class Cell | ||
5 | { | ||
6 | public: | ||
7 | Cell(); | ||
8 | |||
9 | int iWalls; | ||
10 | int iDist; | ||
11 | int iPath; | ||
12 | }; | ||
13 | |||
14 | #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 @@ | |||
1 | #include <stdio.h> | ||
2 | |||
3 | #include "map.h" | ||
4 | #include "cell.h" | ||
5 | #include "position.h" | ||
6 | #include "worm.h" | ||
7 | #include "renderascii.h" | ||
8 | #include "renderpng.h" | ||
9 | |||
10 | #include <stdlib.h> | ||
11 | #include <time.h> | ||
12 | |||
13 | int main( int argc, char *argv[] ) | ||
14 | { | ||
15 | srand( time( NULL ) ); | ||
16 | |||
17 | if( argc <= 2 ) | ||
18 | { | ||
19 | printf( | ||
20 | "Specify dimensions as paramters, and at least two e.g.:\n" | ||
21 | " %s 10 10\n" | ||
22 | " %s 5 5 5\n" | ||
23 | " %s 10 5 8 3\n" | ||
24 | "\n", | ||
25 | argv[0], argv[0], argv[0] | ||
26 | ); | ||
27 | return 0; | ||
28 | } | ||
29 | |||
30 | Position p( argc-1 ); | ||
31 | bool bOk = false; | ||
32 | for( int j = 0; j < argc-1; j++ ) | ||
33 | { | ||
34 | int tmp = strtol( argv[j+1], NULL, 10 ); | ||
35 | if( tmp > 1 ) | ||
36 | { | ||
37 | bOk = true; | ||
38 | } | ||
39 | p[j] = tmp; | ||
40 | } | ||
41 | if( !bOk ) | ||
42 | { | ||
43 | printf("At least one dimension must be greater than 1.\n"); | ||
44 | return 0; | ||
45 | } | ||
46 | |||
47 | // Position p( 4, 4, 4, 4, 4 ); | ||
48 | // Position p( 3, 5, 5, 5 ); | ||
49 | Map m( p ); | ||
50 | for( int j = 0; j < p.getDims(); j++ ) | ||
51 | p[j]--; | ||
52 | |||
53 | int iCount = 2; | ||
54 | Worm **pWorm = new Worm*[iCount]; | ||
55 | pWorm[0] = new Worm( 1, Position( p.getDims() ), m ); | ||
56 | pWorm[1] = new Worm( 2, p, m ); | ||
57 | /* | ||
58 | Position t( p.getDims() ); | ||
59 | pWorm[0] = new Worm( 1, t, m ); | ||
60 | t[0] = p[0]; | ||
61 | pWorm[1] = new Worm( 2, t, m ); | ||
62 | */ | ||
63 | |||
64 | while( iCount > 0 ) | ||
65 | { | ||
66 | for( int j = 0; j < iCount; j++ ) | ||
67 | { | ||
68 | if( pWorm[j]->timestep() == false ) | ||
69 | { | ||
70 | delete pWorm[j]; | ||
71 | if( j < iCount-1 ) | ||
72 | { | ||
73 | pWorm[j] = pWorm[iCount-1]; | ||
74 | pWorm[iCount-1] = 0; | ||
75 | j--; | ||
76 | } | ||
77 | else | ||
78 | { | ||
79 | pWorm[j] = 0; | ||
80 | } | ||
81 | iCount--; | ||
82 | } | ||
83 | } | ||
84 | } | ||
85 | |||
86 | m.connect( 1, 2 ); | ||
87 | |||
88 | // RenderAscii r( m ); | ||
89 | RenderPng r( m ); | ||
90 | r.render(); | ||
91 | |||
92 | |||
93 | return 0; | ||
94 | } | ||
95 | |||
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 @@ | |||
1 | #include "map.h" | ||
2 | #include "cell.h" | ||
3 | #include "position.h" | ||
4 | |||
5 | #include <stdio.h> | ||
6 | #include <string.h> | ||
7 | #include <exception> | ||
8 | |||
9 | Map::Map( const Position &rpMax ) : | ||
10 | iDims( rpMax.getDims() ), | ||
11 | aiSize( 0 ), | ||
12 | acMap( 0 ) | ||
13 | { | ||
14 | int iTotal = 1; | ||
15 | aiSize = new int[iDims]; | ||
16 | for( int j = 0; j < iDims; j++ ) | ||
17 | { | ||
18 | aiSize[j] = rpMax[j]; | ||
19 | iTotal *= aiSize[j]; | ||
20 | } | ||
21 | acMap = new Cell[iTotal]; | ||
22 | } | ||
23 | |||
24 | Map::~Map() | ||
25 | { | ||
26 | delete[] aiSize; | ||
27 | delete[] acMap; | ||
28 | } | ||
29 | |||
30 | Cell &Map::operator[]( const Position &rpIdx ) const | ||
31 | { | ||
32 | return acMap[getIndex( rpIdx )]; | ||
33 | } | ||
34 | |||
35 | Cell &Map::operator[]( const Position &rpIdx ) | ||
36 | { | ||
37 | return acMap[getIndex( rpIdx )]; | ||
38 | } | ||
39 | |||
40 | int Map::getDims() const | ||
41 | { | ||
42 | return iDims; | ||
43 | } | ||
44 | |||
45 | int Map::getSize( int iDim ) const | ||
46 | { | ||
47 | return aiSize[iDim]; | ||
48 | } | ||
49 | |||
50 | int Map::getIndex( const Position &rpIdx ) const | ||
51 | { | ||
52 | if( !isInside( rpIdx ) ) | ||
53 | throw std::exception(); | ||
54 | |||
55 | int iIdx = 0; | ||
56 | int iScale = 1; | ||
57 | for( int j = 0; j < iDims; j++ ) | ||
58 | { | ||
59 | iIdx += rpIdx[j]*iScale; | ||
60 | iScale *= aiSize[j]; | ||
61 | } | ||
62 | return iIdx; | ||
63 | } | ||
64 | |||
65 | bool Map::isInside( const Position &rpIdx ) const | ||
66 | { | ||
67 | if( rpIdx.getDims() != iDims ) | ||
68 | throw std::exception(); | ||
69 | |||
70 | for( int j = 0; j < iDims; j++ ) | ||
71 | { | ||
72 | if( rpIdx[j] < 0 ) | ||
73 | return false; | ||
74 | if( rpIdx[j] >= aiSize[j] ) | ||
75 | return false; | ||
76 | } | ||
77 | |||
78 | return true; | ||
79 | } | ||
80 | |||
81 | int opposite( int iDir ); | ||
82 | |||
83 | void Map::connect( int iId1, int iId2 ) | ||
84 | { | ||
85 | Position p( iDims ); | ||
86 | |||
87 | Position pMax1, pMax2; | ||
88 | int iDistMax = 0; | ||
89 | int iDirMax = 0; | ||
90 | |||
91 | int iDim; | ||
92 | for(;;) | ||
93 | { | ||
94 | Cell &c = (*this)[p]; | ||
95 | if( c.iPath == iId1 || c.iPath == iId2 ) | ||
96 | { | ||
97 | // Could be the thing! | ||
98 | for( iDim = 0; iDim < iDims; iDim++ ) | ||
99 | { | ||
100 | Position t( p ); | ||
101 | t[iDim]--; | ||
102 | for( int iDir = 0; iDir < 2; iDir++ ) | ||
103 | { | ||
104 | // int w = (1<<(iDim*2+iDir)); | ||
105 | if( t[iDim] >= 0 && t[iDim] < aiSize[iDim] ) | ||
106 | { | ||
107 | Cell &c2 = (*this)[t]; | ||
108 | if( c.iPath != c2.iPath && | ||
109 | (c2.iPath == iId1 || c2.iPath == iId2) ) | ||
110 | { | ||
111 | int iDist = c.iDist+c2.iDist; | ||
112 | if( iDist > iDistMax ) | ||
113 | { | ||
114 | iDistMax = iDist; | ||
115 | pMax1 = p; | ||
116 | pMax2 = t; | ||
117 | iDirMax = iDim*2+iDir; | ||
118 | } | ||
119 | } | ||
120 | } | ||
121 | t[iDim] += 2; | ||
122 | } | ||
123 | } | ||
124 | } | ||
125 | |||
126 | for( iDim = 0; iDim < iDims; iDim++ ) | ||
127 | { | ||
128 | if( ++p[iDim] < aiSize[iDim] ) | ||
129 | break; | ||
130 | p[iDim] = 0; | ||
131 | } | ||
132 | if( iDim == iDims ) | ||
133 | break; | ||
134 | } | ||
135 | |||
136 | (*this)[pMax1].iWalls |= (1<<iDirMax); | ||
137 | (*this)[pMax2].iWalls |= (1<<opposite(iDirMax)); | ||
138 | // printf("iDistMax: %d, iDirMax: %d\n", iDistMax, iDirMax ); | ||
139 | } | ||
140 | |||
diff --git a/src/map.h b/src/map.h new file mode 100644 index 0000000..eda5fd8 --- /dev/null +++ b/src/map.h | |||
@@ -0,0 +1,28 @@ | |||
1 | #ifndef MAP_H | ||
2 | #define MAP_H | ||
3 | |||
4 | class Position; | ||
5 | class Cell; | ||
6 | |||
7 | class Map | ||
8 | { | ||
9 | public: | ||
10 | Map( const Position &rpMax ); | ||
11 | virtual ~Map(); | ||
12 | |||
13 | Cell &operator[]( const Position &rpIdx ) const; | ||
14 | Cell &operator[]( const Position &rpIdx ); | ||
15 | |||
16 | int getDims() const; | ||
17 | int getSize( int iDim ) const; | ||
18 | int getIndex( const Position &rpIdx ) const; | ||
19 | bool isInside( const Position &rpIdx ) const; | ||
20 | void connect( int iId1, int iId2 ); | ||
21 | |||
22 | private: | ||
23 | int iDims; | ||
24 | int *aiSize; | ||
25 | Cell *acMap; | ||
26 | }; | ||
27 | |||
28 | #endif | ||
diff --git a/src/position.cpp b/src/position.cpp new file mode 100644 index 0000000..6a9eb10 --- /dev/null +++ b/src/position.cpp | |||
@@ -0,0 +1,85 @@ | |||
1 | #include "position.h" | ||
2 | |||
3 | #include <string.h> | ||
4 | #include <stdarg.h> | ||
5 | #include <exception> | ||
6 | |||
7 | Position::Position() : | ||
8 | iDims( 0 ), | ||
9 | aiValues( 0 ) | ||
10 | { | ||
11 | } | ||
12 | |||
13 | Position::Position( int iDims ) : | ||
14 | iDims( iDims ), | ||
15 | aiValues( 0 ) | ||
16 | { | ||
17 | aiValues = new int[iDims]; | ||
18 | memset( aiValues, 0, sizeof(int)*iDims ); | ||
19 | } | ||
20 | |||
21 | Position::Position( int iDims, int iX, ...) : | ||
22 | iDims( iDims ), | ||
23 | aiValues( 0 ) | ||
24 | { | ||
25 | aiValues = new int[iDims]; | ||
26 | memset( aiValues, 0, sizeof(int)*iDims ); | ||
27 | |||
28 | aiValues[0] = iX; | ||
29 | va_list ap; | ||
30 | va_start( ap, iX ); | ||
31 | for( int j = 1; j < iDims; j++ ) | ||
32 | { | ||
33 | aiValues[j] = va_arg( ap, int ); | ||
34 | } | ||
35 | va_end( ap ); | ||
36 | } | ||
37 | |||
38 | Position::Position( const Position &rhs ) : | ||
39 | iDims( rhs.iDims ), | ||
40 | aiValues( 0 ) | ||
41 | { | ||
42 | aiValues = new int[iDims]; | ||
43 | memcpy( aiValues, rhs.aiValues, sizeof(int)*iDims ); | ||
44 | } | ||
45 | |||
46 | Position::~Position() | ||
47 | { | ||
48 | delete[] aiValues; | ||
49 | } | ||
50 | |||
51 | int Position::operator[]( int iIdx ) const | ||
52 | { | ||
53 | if( iIdx < 0 ) | ||
54 | throw std::exception(); | ||
55 | else if( iIdx >= iDims ) | ||
56 | throw std::exception(); | ||
57 | |||
58 | return aiValues[iIdx]; | ||
59 | } | ||
60 | |||
61 | int &Position::operator[]( int iIdx ) | ||
62 | { | ||
63 | if( iIdx < 0 ) | ||
64 | throw std::exception(); | ||
65 | else if( iIdx >= iDims ) | ||
66 | throw std::exception(); | ||
67 | |||
68 | return aiValues[iIdx]; | ||
69 | } | ||
70 | |||
71 | Position &Position::operator=( const Position &rhs ) | ||
72 | { | ||
73 | delete[] aiValues; | ||
74 | iDims = rhs.iDims; | ||
75 | aiValues = new int[iDims]; | ||
76 | memcpy( aiValues, rhs.aiValues, sizeof(int)*iDims ); | ||
77 | |||
78 | return *this; | ||
79 | } | ||
80 | |||
81 | int Position::getDims() const | ||
82 | { | ||
83 | return iDims; | ||
84 | } | ||
85 | |||
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 @@ | |||
1 | #ifndef POSITION_H | ||
2 | #define POSITION_H | ||
3 | |||
4 | class Position | ||
5 | { | ||
6 | public: | ||
7 | Position(); | ||
8 | Position( int iDims ); | ||
9 | Position( int iDims, int iX, ...); | ||
10 | Position( const Position &rhs ); | ||
11 | virtual ~Position(); | ||
12 | |||
13 | int operator[]( int iIdx ) const; | ||
14 | int &operator[]( int iIdx ); | ||
15 | Position &operator=( const Position &rhs ); | ||
16 | |||
17 | int getDims() const; | ||
18 | |||
19 | private: | ||
20 | int iDims; | ||
21 | int *aiValues; | ||
22 | }; | ||
23 | |||
24 | #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 @@ | |||
1 | #include "renderascii.h" | ||
2 | #include "position.h" | ||
3 | #include "map.h" | ||
4 | #include "cell.h" | ||
5 | |||
6 | #include <math.h> | ||
7 | #include <stdio.h> | ||
8 | #include <string.h> | ||
9 | |||
10 | RenderAscii::RenderAscii( Map &rMap ) : | ||
11 | rMap( rMap ) | ||
12 | { | ||
13 | } | ||
14 | |||
15 | RenderAscii::~RenderAscii() | ||
16 | { | ||
17 | } | ||
18 | |||
19 | void postProcess( char *buf, int w, int h ) | ||
20 | { | ||
21 | static const char *cJunct[] = { | ||
22 | "", // 0 blank | ||
23 | "\xe2\x94\x80", // 1 left | ||
24 | "\xe2\x94\x80", // 2 right | ||
25 | "\xe2\x94\x80", // 1 2 left right | ||
26 | "\xe2\x94\x82", // 4 up | ||
27 | "\xe2\x94\x98", // 1 4 left up | ||
28 | "\xe2\x94\x94", // 2 4 right up | ||
29 | "\xe2\x94\xb4", // 1 2 4 left right up | ||
30 | "\xe2\x94\x82", // 8 down | ||
31 | "\xe2\x94\x90", // 1 8 left down | ||
32 | "\xe2\x94\x8c", // 2 8 right down | ||
33 | "\xe2\x94\xac", // 1 2 8 left right down | ||
34 | "\xe2\x94\x82", // 4 8 up down | ||
35 | "\xe2\x94\xa4", // 1 4 8 left up down | ||
36 | "\xe2\x94\x9c", // 2 4 8 right up down | ||
37 | "\xE2\x94\xBC", // 1 2 4 8 left right up down | ||
38 | "" | ||
39 | }; | ||
40 | /* | ||
41 | // Double lines | ||
42 | ' ', // 0 blank | ||
43 | '\xcd', // 1 left | ||
44 | '\xcd', // 2 right | ||
45 | '\xcd', // 1 2 left right | ||
46 | '\xba', // 4 up | ||
47 | '\xbc', // 1 4 left up | ||
48 | '\xc8', // 2 4 right up | ||
49 | '\xca', // 1 2 4 left right up | ||
50 | '\xba', // 8 down | ||
51 | '\xbb', // 1 8 left down | ||
52 | '\xc9', // 2 8 right down | ||
53 | '\xcb', // 1 2 8 left right down | ||
54 | '\xba', // 4 8 up down | ||
55 | '\xb9', // 1 4 8 left up down | ||
56 | '\xcc', // 2 4 8 right up down | ||
57 | '\xce', // 1 2 4 8 left right up down | ||
58 | '\0' | ||
59 | */ | ||
60 | |||
61 | for( int y = 0; y < h; y++ ) | ||
62 | { | ||
63 | for( int x = 0; x < w; x++ ) | ||
64 | { | ||
65 | if( buf[x+y*w] == '+' ) | ||
66 | { | ||
67 | int iJunct = 0; | ||
68 | if( x > 0 && buf[(x-1)+y*w] == '-' ) | ||
69 | iJunct |= 1; | ||
70 | if( x < w-1 && buf[(x+1)+y*w] == '-' ) | ||
71 | iJunct |= 2; | ||
72 | if( y > 0 && buf[x+(y-1)*w] == '|' ) | ||
73 | iJunct |= 4; | ||
74 | if( y < h-1 && buf[x+(y+1)*w] == '|' ) | ||
75 | iJunct |= 8; | ||
76 | printf(cJunct[iJunct]); | ||
77 | } | ||
78 | else | ||
79 | { | ||
80 | switch( buf[x+y*w] ) | ||
81 | { | ||
82 | case '-': | ||
83 | printf("\xe2\x94\x80"); | ||
84 | break; | ||
85 | |||
86 | case '|': | ||
87 | printf("\xe2\x94\x82"); | ||
88 | break; | ||
89 | |||
90 | case '^': | ||
91 | printf("\xe2\x86\x91"); | ||
92 | break; | ||
93 | |||
94 | case 'v': | ||
95 | printf("\xe2\x86\x93"); | ||
96 | break; | ||
97 | |||
98 | default: | ||
99 | printf("%c", buf[x+y*w]); | ||
100 | break; | ||
101 | } | ||
102 | } | ||
103 | } | ||
104 | } | ||
105 | } | ||
106 | |||
107 | void RenderAscii::render() | ||
108 | { | ||
109 | static char cPassages[] = {"~~~~^v<>/*aAbBcCdDeE"}; | ||
110 | |||
111 | printf("\xef\xbb\xbf"); | ||
112 | |||
113 | int iDims = rMap.getDims(); | ||
114 | int iSize = 1; | ||
115 | if( iDims > 2 ) | ||
116 | iSize = (int)ceil(sqrt((rMap.getDims()-2)*2)); | ||
117 | |||
118 | int iBufWidth = ((iSize+1)*rMap.getSize( 0 )+2); | ||
119 | int iBufHeight = (iSize+1)*rMap.getSize( 1 )+1; | ||
120 | int iBufSize = iBufWidth*iBufHeight+1; | ||
121 | |||
122 | char *buf = new char[iBufSize]; | ||
123 | memset( buf, '\n', iBufSize ); | ||
124 | buf[iBufSize-1] = '\0'; | ||
125 | |||
126 | Position p( iDims ); | ||
127 | for(;;) | ||
128 | { | ||
129 | int x = p[0]*(iSize+1); | ||
130 | int y = p[1]*(iSize+1); | ||
131 | int iWalls = rMap[p].iWalls; | ||
132 | |||
133 | for( int iRow = 0; iRow < iSize+2; iRow++ ) | ||
134 | { | ||
135 | for( int iCol = 0; iCol < iSize+2; iCol++ ) | ||
136 | { | ||
137 | char &c = buf[x+iCol+(y+iRow)*iBufWidth]; | ||
138 | if( (iRow == 0 || iRow == iSize+1) && | ||
139 | (iCol == 0 || iCol == iSize+1) ) | ||
140 | c = '+'; | ||
141 | else if( iRow == 0 && (iWalls&(1<<2)) == 0 ) | ||
142 | c = '-'; | ||
143 | else if( iRow == iSize+1 && (iWalls&(1<<3)) == 0 ) | ||
144 | c = '-'; | ||
145 | else if( iCol == 0 && (iWalls&(1<<0)) == 0 ) | ||
146 | c = '|'; | ||
147 | else if( iCol == iSize+1 && (iWalls&(1<<1)) == 0 ) | ||
148 | c = '|'; | ||
149 | else | ||
150 | c = ' '; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | for( int j = 2; j < iDims; j++ ) | ||
155 | { | ||
156 | for( int side = 0; side < 2; side++ ) | ||
157 | { | ||
158 | int d = j*2+side; | ||
159 | if( iWalls&(1<<d) ) | ||
160 | { | ||
161 | int iSubX = (d-4)%iSize; | ||
162 | int iSubY = (d-4)/iSize; | ||
163 | char &c = buf[x+1+iSubX+(y+1+iSubY)*iBufWidth]; | ||
164 | c = cPassages[d]; | ||
165 | } | ||
166 | } | ||
167 | } | ||
168 | |||
169 | int iDim; | ||
170 | for( iDim = 0; iDim < iDims; iDim++ ) | ||
171 | { | ||
172 | if( ++p[iDim] < rMap.getSize( iDim ) ) | ||
173 | break; | ||
174 | p[iDim] = 0; | ||
175 | if( iDim == 1 ) | ||
176 | { | ||
177 | if( iDims > 2 ) | ||
178 | { | ||
179 | printf("Floor: (%d", rMap.getSize(2)-p[2]); | ||
180 | for( int j = 3; j < iDims; j++ ) | ||
181 | { | ||
182 | printf(", %d", rMap.getSize(j)-p[j] ); | ||
183 | } | ||
184 | printf(")\n"); | ||
185 | } | ||
186 | |||
187 | postProcess( buf, iBufWidth, iBufHeight ); | ||
188 | // printf(buf); | ||
189 | memset( buf, '\n', iBufSize ); | ||
190 | buf[iBufSize-1] = '\0'; | ||
191 | } | ||
192 | } | ||
193 | /* | ||
194 | printf("[%d", p[0]); | ||
195 | for( int j = 1; j < iDims; j++ ) | ||
196 | { | ||
197 | printf(", %d", p[j] ); | ||
198 | } | ||
199 | printf("]\n"); | ||
200 | */ | ||
201 | if( iDim == iDims ) | ||
202 | break; | ||
203 | } | ||
204 | // printf(buf); | ||
205 | |||
206 | delete[] buf; | ||
207 | } | ||
208 | /* | ||
209 | int iSizeX = rMap.getSize( 0 ); | ||
210 | int iSizeY = 1; | ||
211 | if( iDims >= 2 ) | ||
212 | iSizeY = rMap.getSize( 1 ); | ||
213 | |||
214 | for( int y = 0; y < iSizeY; y++ ) | ||
215 | { | ||
216 | for( int iRow = (y==0)?0:1; iRow < iSize+2; iRow++ ) | ||
217 | { | ||
218 | for( int x = 0; x < iSizeX; x++ ) | ||
219 | { | ||
220 | int iWalls = rMap[Position(2, x, y)].iWalls; | ||
221 | for( int iCol = (x==0)?0:1; iCol < iSize+2; iCol++ ) | ||
222 | { | ||
223 | if( (iRow == 0 || iRow == iSize+1 ) && | ||
224 | (iCol == 0 || iCol == iSize+1 )) | ||
225 | { | ||
226 | printf("+"); | ||
227 | } | ||
228 | else if( iRow == 0 ) | ||
229 | { | ||
230 | if( (iWalls&(1<<2)) == 0 ) | ||
231 | printf("-"); | ||
232 | else | ||
233 | printf(" "); | ||
234 | } | ||
235 | else if( iRow == iSize+1 ) | ||
236 | { | ||
237 | if( (iWalls&(1<<3)) == 0 ) | ||
238 | printf("-"); | ||
239 | else | ||
240 | printf(" "); | ||
241 | } | ||
242 | else if( iCol == 0 ) | ||
243 | { | ||
244 | if( (iWalls&(1<<0)) == 0 ) | ||
245 | printf("|"); | ||
246 | else | ||
247 | printf(" "); | ||
248 | } | ||
249 | else if( iCol == iSize+1 ) | ||
250 | { | ||
251 | if( (iWalls&(1<<1)) == 0 ) | ||
252 | printf("|"); | ||
253 | else | ||
254 | printf(" "); | ||
255 | } | ||
256 | else | ||
257 | printf(" "); | ||
258 | } | ||
259 | } | ||
260 | printf("\n"); | ||
261 | } | ||
262 | } | ||
263 | } | ||
264 | */ | ||
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 @@ | |||
1 | #ifndef RENDER_ASCII_H | ||
2 | #define RENDER_ASCII_H | ||
3 | |||
4 | class Map; | ||
5 | |||
6 | class RenderAscii | ||
7 | { | ||
8 | public: | ||
9 | RenderAscii( Map &rMap ); | ||
10 | virtual ~RenderAscii(); | ||
11 | |||
12 | void render(); | ||
13 | |||
14 | private: | ||
15 | Map &rMap; | ||
16 | }; | ||
17 | |||
18 | #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 @@ | |||
1 | #include "renderpng.h" | ||
2 | #include "position.h" | ||
3 | #include "map.h" | ||
4 | #include "cell.h" | ||
5 | |||
6 | #include <math.h> | ||
7 | #include <string.h> | ||
8 | #include <stdint.h> | ||
9 | #include <stdlib.h> | ||
10 | #include <png.h> | ||
11 | |||
12 | RenderPng::RenderPng( Map &rMap ) : | ||
13 | rMap( rMap ) | ||
14 | { | ||
15 | } | ||
16 | |||
17 | RenderPng::~RenderPng() | ||
18 | { | ||
19 | } | ||
20 | |||
21 | void RenderPng::render() | ||
22 | { | ||
23 | int iDims = rMap.getDims(); | ||
24 | int iSize = 1; | ||
25 | if( iDims > 2 ) | ||
26 | iSize = (int)ceil(sqrt((rMap.getDims()-2)*2)); | ||
27 | |||
28 | int iBufWidth = ((iSize+1)*rMap.getSize( 0 )+1)*5; | ||
29 | int iBufHeight = ((iSize+1)*rMap.getSize( 1 )+1)*5; | ||
30 | int iBufSize = iBufWidth*iBufHeight; | ||
31 | uint8_t *pBuf = new uint8_t[iBufSize]; | ||
32 | uint8_t **pRows = new uint8_t*[iBufHeight]; | ||
33 | for( int r = 0; r < iBufHeight; r++ ) | ||
34 | { | ||
35 | pRows[r] = pBuf+(iBufWidth*r); | ||
36 | } | ||
37 | memset( pBuf, 1, iBufSize ); | ||
38 | |||
39 | Position p( iDims ); | ||
40 | for(;;) | ||
41 | { | ||
42 | int x = p[0]*(iSize+1); | ||
43 | int y = p[1]*(iSize+1); | ||
44 | int iWalls = rMap[p].iWalls; | ||
45 | |||
46 | for( int iRow = 0; iRow < iSize+2; iRow++ ) | ||
47 | { | ||
48 | for( int iCol = 0; iCol < iSize+2; iCol++ ) | ||
49 | { | ||
50 | if( (iRow == 0 || iRow == iSize+1) && | ||
51 | (iCol == 0 || iCol == iSize+1) ) | ||
52 | { | ||
53 | pRows[(y+iRow)*5+2][(x+iCol)*5+2] = 0; | ||
54 | if( iRow == 0 && iCol == 0 ) | ||
55 | { | ||
56 | if( (iWalls&(1<<2)) == 0 ) | ||
57 | { | ||
58 | for( int i = 0; i < 3; i++ ) | ||
59 | pRows[(y+iRow)*5+2][(x+iCol)*5+i+3] = 0; | ||
60 | } | ||
61 | if( (iWalls&(1<<0)) == 0 ) | ||
62 | { | ||
63 | for( int i = 0; i < 3; i++ ) | ||
64 | pRows[(y+iRow)*5+i+3][(x+iCol)*5+2] = 0; | ||
65 | } | ||
66 | } | ||
67 | else if( iRow == 0 && iCol == iSize+1 ) | ||
68 | { | ||
69 | if( (iWalls&(1<<2)) == 0 ) | ||
70 | { | ||
71 | for( int i = 0; i < 3; i++ ) | ||
72 | pRows[(y+iRow)*5+2][(x+iCol)*5+i] = 0; | ||
73 | } | ||
74 | if( (iWalls&(1<<1)) == 0 ) | ||
75 | { | ||
76 | for( int i = 0; i < 3; i++ ) | ||
77 | pRows[(y+iRow)*5+i+3][(x+iCol)*5+2] = 0; | ||
78 | } | ||
79 | } | ||
80 | else if( iRow == iSize+1 && iCol == 0 ) | ||
81 | { | ||
82 | if( (iWalls&(1<<3)) == 0 ) | ||
83 | { | ||
84 | for( int i = 0; i < 3; i++ ) | ||
85 | pRows[(y+iRow)*5+2][(x+iCol)*5+i+3] = 0; | ||
86 | } | ||
87 | if( (iWalls&(1<<0)) == 0 ) | ||
88 | { | ||
89 | for( int i = 0; i < 3; i++ ) | ||
90 | pRows[(y+iRow)*5+i][(x+iCol)*5+2] = 0; | ||
91 | } | ||
92 | } | ||
93 | else if( iRow == iSize+1 && iCol == iSize+1 ) | ||
94 | { | ||
95 | if( (iWalls&(1<<3)) == 0 ) | ||
96 | { | ||
97 | for( int i = 0; i < 3; i++ ) | ||
98 | pRows[(y+iRow)*5+2][(x+iCol)*5+i] = 0; | ||
99 | } | ||
100 | if( (iWalls&(1<<1)) == 0 ) | ||
101 | { | ||
102 | for( int i = 0; i < 3; i++ ) | ||
103 | pRows[(y+iRow)*5+i][(x+iCol)*5+2] = 0; | ||
104 | } | ||
105 | } | ||
106 | } | ||
107 | else if( iRow == 0 && (iWalls&(1<<2)) == 0 ) | ||
108 | { | ||
109 | for( int i = 0; i < 5; i++ ) | ||
110 | { | ||
111 | pRows[(y+iRow)*5+2][(x+iCol)*5+i] = 0; | ||
112 | } | ||
113 | } | ||
114 | else if( iRow == iSize+1 && (iWalls&(1<<3)) == 0 ) | ||
115 | { | ||
116 | for( int i = 0; i < 5; i++ ) | ||
117 | { | ||
118 | pRows[(y+iRow)*5+2][(x+iCol)*5+i] = 0; | ||
119 | } | ||
120 | } | ||
121 | else if( iCol == 0 && (iWalls&(1<<0)) == 0 ) | ||
122 | { | ||
123 | for( int i = 0; i < 5; i++ ) | ||
124 | { | ||
125 | pRows[(y+iRow)*5+i][(x+iCol)*5+2] = 0; | ||
126 | } | ||
127 | } | ||
128 | else if( iCol == iSize+1 && (iWalls&(1<<1)) == 0 ) | ||
129 | { | ||
130 | for( int i = 0; i < 5; i++ ) | ||
131 | { | ||
132 | pRows[(y+iRow)*5+i][(x+iCol)*5+2] = 0; | ||
133 | } | ||
134 | } | ||
135 | } | ||
136 | } | ||
137 | |||
138 | for( int j = 2; j < iDims; j++ ) | ||
139 | { | ||
140 | for( int side = 0; side < 2; side++ ) | ||
141 | { | ||
142 | int d = j*2+side; | ||
143 | if( iWalls&(1<<d) ) | ||
144 | { | ||
145 | int iSubX = (x+1+((d-4)%iSize))*5; | ||
146 | int iSubY = (y+1+((d-4)/iSize))*5; | ||
147 | // | ||
148 | // char &c = buf[x+1+iSubX+(y+1+iSubY)*iBufWidth]; | ||
149 | // c = cPassages[d]; | ||
150 | switch( d ) | ||
151 | { | ||
152 | case 4: | ||
153 | pRows[iSubY+1][iSubX+2] = 0; | ||
154 | pRows[iSubY+2][iSubX+1] = 0; | ||
155 | pRows[iSubY+2][iSubX+3] = 0; | ||
156 | pRows[iSubY+3][iSubX+0] = 0; | ||
157 | pRows[iSubY+3][iSubX+4] = 0; | ||
158 | break; | ||
159 | |||
160 | case 5: | ||
161 | pRows[iSubY+3][iSubX+2] = 0; | ||
162 | pRows[iSubY+2][iSubX+1] = 0; | ||
163 | pRows[iSubY+2][iSubX+3] = 0; | ||
164 | pRows[iSubY+1][iSubX+0] = 0; | ||
165 | pRows[iSubY+1][iSubX+4] = 0; | ||
166 | break; | ||
167 | |||
168 | case 6: | ||
169 | pRows[iSubY+2][iSubX+1] = 0; | ||
170 | pRows[iSubY+1][iSubX+2] = 0; | ||
171 | pRows[iSubY+3][iSubX+2] = 0; | ||
172 | pRows[iSubY+0][iSubX+3] = 0; | ||
173 | pRows[iSubY+4][iSubX+3] = 0; | ||
174 | break; | ||
175 | |||
176 | case 7: | ||
177 | pRows[iSubY+2][iSubX+3] = 0; | ||
178 | pRows[iSubY+1][iSubX+2] = 0; | ||
179 | pRows[iSubY+3][iSubX+2] = 0; | ||
180 | pRows[iSubY+0][iSubX+1] = 0; | ||
181 | pRows[iSubY+4][iSubX+1] = 0; | ||
182 | break; | ||
183 | } | ||
184 | } | ||
185 | } | ||
186 | } | ||
187 | |||
188 | int iDim; | ||
189 | char fname[1024]; | ||
190 | for( iDim = 0; iDim < iDims; iDim++ ) | ||
191 | { | ||
192 | if( ++p[iDim] < rMap.getSize( iDim ) ) | ||
193 | break; | ||
194 | p[iDim] = 0; | ||
195 | if( iDim == 1 ) | ||
196 | { | ||
197 | strcpy(fname, "floor"); | ||
198 | if( iDims > 2 ) | ||
199 | { | ||
200 | char buf[1024]; | ||
201 | sprintf( buf, "-%d", rMap.getSize(2)-p[2] ); | ||
202 | strcat( fname, buf ); | ||
203 | for( int j = 3; j < iDims; j++ ) | ||
204 | { | ||
205 | sprintf( buf, "-%d", rMap.getSize(j)-p[j] ); | ||
206 | strcat( fname, buf ); | ||
207 | } | ||
208 | } | ||
209 | strcat( fname, ".png"); | ||
210 | printf("Output: %s\n", fname ); | ||
211 | |||
212 | png_structp png_ptr = png_create_write_struct( | ||
213 | PNG_LIBPNG_VER_STRING, NULL, NULL, NULL | ||
214 | ); | ||
215 | png_infop info_ptr = png_create_info_struct(png_ptr); | ||
216 | png_set_IHDR(png_ptr, info_ptr, iBufWidth, iBufHeight, | ||
217 | 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, | ||
218 | PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT | ||
219 | ); | ||
220 | png_color col[2]; | ||
221 | col[0].red = col[0].green = col[0].blue = 0; | ||
222 | col[1].red = col[1].green = col[1].blue = 255; | ||
223 | png_set_PLTE( png_ptr, info_ptr, col, 2); | ||
224 | |||
225 | png_set_rows( png_ptr, info_ptr, pRows ); | ||
226 | |||
227 | FILE *fp = fopen(fname, "wb"); | ||
228 | if( fp == NULL ) | ||
229 | { | ||
230 | printf("Error opening file!\n"); | ||
231 | exit( 1 ); | ||
232 | } | ||
233 | |||
234 | png_init_io( png_ptr, fp ); | ||
235 | png_write_png( png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL ); | ||
236 | png_destroy_write_struct( &png_ptr, &info_ptr ); | ||
237 | fclose( fp ); | ||
238 | |||
239 | memset( pBuf, 1, iBufSize ); | ||
240 | } | ||
241 | } | ||
242 | if( iDim == iDims ) | ||
243 | break; | ||
244 | /* | ||
245 | for( int j = 2; j < iDims; j++ ) | ||
246 | { | ||
247 | for( int side = 0; side < 2; side++ ) | ||
248 | { | ||
249 | int d = j*2+side; | ||
250 | if( iWalls&(1<<d) ) | ||
251 | { | ||
252 | int iSubX = (d-4)%iSize; | ||
253 | int iSubY = (d-4)/iSize; | ||
254 | char &c = buf[x+1+iSubX+(y+1+iSubY)*iBufWidth]; | ||
255 | c = cPassages[d]; | ||
256 | } | ||
257 | } | ||
258 | } | ||
259 | */ | ||
260 | } | ||
261 | // printf(buf); | ||
262 | |||
263 | delete[] pBuf; | ||
264 | delete[] pRows; | ||
265 | } | ||
266 | |||
diff --git a/src/renderpng.h b/src/renderpng.h new file mode 100644 index 0000000..eb8b724 --- /dev/null +++ b/src/renderpng.h | |||
@@ -0,0 +1,18 @@ | |||
1 | #ifndef RENDER_PNG_H | ||
2 | #define RENDER_PNG_H | ||
3 | |||
4 | class Map; | ||
5 | |||
6 | class RenderPng | ||
7 | { | ||
8 | public: | ||
9 | RenderPng( Map &rMap ); | ||
10 | virtual ~RenderPng(); | ||
11 | |||
12 | void render(); | ||
13 | |||
14 | private: | ||
15 | Map &rMap; | ||
16 | }; | ||
17 | |||
18 | #endif | ||
diff --git a/src/worm.cpp b/src/worm.cpp new file mode 100644 index 0000000..31be54d --- /dev/null +++ b/src/worm.cpp | |||
@@ -0,0 +1,124 @@ | |||
1 | #include "worm.h" | ||
2 | #include "map.h" | ||
3 | #include "cell.h" | ||
4 | |||
5 | #include <stdlib.h> | ||
6 | |||
7 | Worm::Worm( int iId, const Position &rpStart, Map &rMap ) : | ||
8 | iId( iId ), | ||
9 | pCur( rpStart ), | ||
10 | rMap( rMap ), | ||
11 | iDist( 1 ) | ||
12 | { | ||
13 | Cell &rCur = rMap[pCur]; | ||
14 | rCur.iDist = iDist; | ||
15 | rCur.iPath = iId; | ||
16 | |||
17 | int iCount = 0; | ||
18 | int *iDirs = new int[2]; | ||
19 | if( pCur[0] == 0 ) | ||
20 | iDirs[iCount++] = 1; | ||
21 | else if( pCur[0] == rMap.getSize(0)-1 ) | ||
22 | iDirs[iCount++] = 2; | ||
23 | if( pCur[1] == 0 ) | ||
24 | iDirs[iCount++] = 4; | ||
25 | else if( pCur[1] == rMap.getSize(1)-1 ) | ||
26 | iDirs[iCount++] = 8; | ||
27 | |||
28 | rCur.iWalls |= iDirs[rand()%iCount]; | ||
29 | delete[] iDirs; | ||
30 | } | ||
31 | |||
32 | Worm::~Worm() | ||
33 | { | ||
34 | } | ||
35 | |||
36 | int opposite( int iDir ) | ||
37 | { | ||
38 | if( iDir%2 == 1 ) | ||
39 | return iDir-1; | ||
40 | return iDir+1; | ||
41 | } | ||
42 | |||
43 | bool Worm::timestep() | ||
44 | { | ||
45 | int iDims = rMap.getDims(); | ||
46 | int iCount = 0; | ||
47 | Position *pDirs = new Position[iDims*2]; | ||
48 | int *iDirs = new int[iDims*2]; | ||
49 | |||
50 | for(;;) | ||
51 | { | ||
52 | iCount = 0; | ||
53 | bool bFoundBack = false; | ||
54 | Position pBack; | ||
55 | for( int j = 0; j < iDims; j++ ) | ||
56 | { | ||
57 | int iSize = rMap.getSize( j ); | ||
58 | Position p1( pCur ); | ||
59 | p1[j]--; | ||
60 | if( p1[j] >= 0 ) | ||
61 | { | ||
62 | if( rMap[p1].iPath == 0 ) | ||
63 | { | ||
64 | iDirs[iCount] = j*2; | ||
65 | pDirs[iCount++] = p1; | ||
66 | } | ||
67 | else if( rMap[p1].iPath == iId && rMap[p1].iDist == iDist-1 ) | ||
68 | { | ||
69 | pBack = p1; | ||
70 | bFoundBack = true; | ||
71 | } | ||
72 | } | ||
73 | Position p2( pCur ); | ||
74 | p2[j]++; | ||
75 | if( p2[j] < iSize ) | ||
76 | { | ||
77 | if( rMap[p2].iPath == 0 ) | ||
78 | { | ||
79 | iDirs[iCount] = j*2+1; | ||
80 | pDirs[iCount++] = p2; | ||
81 | } | ||
82 | else if( rMap[p2].iPath == iId && rMap[p2].iDist == iDist-1 ) | ||
83 | { | ||
84 | pBack = p2; | ||
85 | bFoundBack = true; | ||
86 | } | ||
87 | } | ||
88 | } | ||
89 | |||
90 | if( iCount > 0 ) | ||
91 | { | ||
92 | break; | ||
93 | } | ||
94 | else | ||
95 | { | ||
96 | if( bFoundBack ) | ||
97 | { | ||
98 | pCur = pBack; | ||
99 | iDist--; | ||
100 | } | ||
101 | else | ||
102 | { | ||
103 | delete[] pDirs; | ||
104 | delete[] iDirs; | ||
105 | return false; | ||
106 | } | ||
107 | } | ||
108 | } | ||
109 | |||
110 | int iSel = rand()%iCount; | ||
111 | Cell &rCur = rMap[pCur]; | ||
112 | rCur.iWalls |= (1<<iDirs[iSel]); | ||
113 | Cell &rNext = rMap[pDirs[iSel]]; | ||
114 | rNext.iWalls |= (1<<opposite(iDirs[iSel])); | ||
115 | rNext.iDist = ++iDist; | ||
116 | rNext.iPath = iId; | ||
117 | pCur = pDirs[iSel]; | ||
118 | |||
119 | delete[] pDirs; | ||
120 | delete[] iDirs; | ||
121 | |||
122 | return true; | ||
123 | } | ||
124 | |||
diff --git a/src/worm.h b/src/worm.h new file mode 100644 index 0000000..2c02e76 --- /dev/null +++ b/src/worm.h | |||
@@ -0,0 +1,23 @@ | |||
1 | #ifndef WORM_H | ||
2 | #define WORH_H | ||
3 | |||
4 | #include "position.h" | ||
5 | |||
6 | class Map; | ||
7 | |||
8 | class Worm | ||
9 | { | ||
10 | public: | ||
11 | Worm( int iId, const Position &rpStart, Map &rMap ); | ||
12 | virtual ~Worm(); | ||
13 | |||
14 | bool timestep(); | ||
15 | |||
16 | private: | ||
17 | int iId; | ||
18 | Position pCur; | ||
19 | Map &rMap; | ||
20 | int iDist; | ||
21 | }; | ||
22 | |||
23 | #endif | ||