summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <mike@xagasoft.com>2015-04-02 15:28:31 -0600
committerMike Buland <mike@xagasoft.com>2015-04-02 15:28:31 -0600
commit518619603ab3c49b7fdfcf19c439c1a30668164f (patch)
treedda7774f51bde150db91dac14718cc78f7571039
downloadlost-518619603ab3c49b7fdfcf19c439c1a30668164f.tar.gz
lost-518619603ab3c49b7fdfcf19c439c1a30668164f.tar.bz2
lost-518619603ab3c49b7fdfcf19c439c1a30668164f.tar.xz
lost-518619603ab3c49b7fdfcf19c439c1a30668164f.zip
Everything works, it could use more stuff.
-rw-r--r--.gitignore6
-rw-r--r--build.sh3
-rw-r--r--src/cell.cpp11
-rw-r--r--src/cell.h14
-rw-r--r--src/main.cpp95
-rw-r--r--src/map.cpp140
-rw-r--r--src/map.h28
-rw-r--r--src/position.cpp85
-rw-r--r--src/position.h24
-rw-r--r--src/renderascii.cpp264
-rw-r--r--src/renderascii.h18
-rw-r--r--src/renderpng.cpp266
-rw-r--r--src/renderpng.h18
-rw-r--r--src/worm.cpp124
-rw-r--r--src/worm.h23
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
3exec 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
5Cell::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
4class Cell
5{
6public:
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
13int 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
9Map::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
24Map::~Map()
25{
26 delete[] aiSize;
27 delete[] acMap;
28}
29
30Cell &Map::operator[]( const Position &rpIdx ) const
31{
32 return acMap[getIndex( rpIdx )];
33}
34
35Cell &Map::operator[]( const Position &rpIdx )
36{
37 return acMap[getIndex( rpIdx )];
38}
39
40int Map::getDims() const
41{
42 return iDims;
43}
44
45int Map::getSize( int iDim ) const
46{
47 return aiSize[iDim];
48}
49
50int 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
65bool 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
81int opposite( int iDir );
82
83void 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
4class Position;
5class Cell;
6
7class Map
8{
9public:
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
22private:
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
7Position::Position() :
8 iDims( 0 ),
9 aiValues( 0 )
10{
11}
12
13Position::Position( int iDims ) :
14 iDims( iDims ),
15 aiValues( 0 )
16{
17 aiValues = new int[iDims];
18 memset( aiValues, 0, sizeof(int)*iDims );
19}
20
21Position::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
38Position::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
46Position::~Position()
47{
48 delete[] aiValues;
49}
50
51int 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
61int &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
71Position &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
81int 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
4class Position
5{
6public:
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
19private:
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
10RenderAscii::RenderAscii( Map &rMap ) :
11 rMap( rMap )
12{
13}
14
15RenderAscii::~RenderAscii()
16{
17}
18
19void 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
107void 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
4class Map;
5
6class RenderAscii
7{
8public:
9 RenderAscii( Map &rMap );
10 virtual ~RenderAscii();
11
12 void render();
13
14private:
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
12RenderPng::RenderPng( Map &rMap ) :
13 rMap( rMap )
14{
15}
16
17RenderPng::~RenderPng()
18{
19}
20
21void 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
4class Map;
5
6class RenderPng
7{
8public:
9 RenderPng( Map &rMap );
10 virtual ~RenderPng();
11
12 void render();
13
14private:
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
7Worm::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
32Worm::~Worm()
33{
34}
35
36int opposite( int iDir )
37{
38 if( iDir%2 == 1 )
39 return iDir-1;
40 return iDir+1;
41}
42
43bool 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
6class Map;
7
8class Worm
9{
10public:
11 Worm( int iId, const Position &rpStart, Map &rMap );
12 virtual ~Worm();
13
14 bool timestep();
15
16private:
17 int iId;
18 Position pCur;
19 Map &rMap;
20 int iDist;
21};
22
23#endif