473,670 Members | 2,623 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Some working code for a change...

Some might remember that i, not so long ago, started a treath or two
about a weird 3d labyrinth. I now have a working code, that i want to
share, hear comments, advice, ect., but first let me explain what its
all about.

The whole labyrinth is a cubic in its self and it contains x^3 cubic
rooms.
The labyrinth is infinite/finite, it has no borders, but still have a
size.
fx. if the size of the labytrint is 2^3 and you find yourself at
coordinate 3,3,3 you're really finding your self at the coordinate
1,1,1.
Each room has 6 wall/possible doors, however, adjacent rooms shares a
wall, so we only need to keep track of three wall per room.
A wall can be set or unset, if unset, ofcourse there is nowall and your
free to move to the next room.
The grid pattern follow one simple room: "you must, at all time be able
to find a path from one room to another."
This tricky problem is solved by setting all walls in the labyrinth and
setting a start position at random, then picking a direction at random.
If the room in that direction have'nt been visited yet, brake down the
wall and move there and start over, else try again. If you cant move
any further, pop back to last position and start over from there. The
grid is ready when you are stuck at the start position.

The only question left should be: "what to use it for?"
Well, i can think of many options, but for a start lets just this of a
mouse in a labyrint ;-)

Last i would like to thank two people:
"Kai-Uwe Bux"
For helping me alot with the datastructure.
"someone i cant remember the name of"
For suplying the idea for the grid generation.

And ofcourse i want to thank everyone else for cutting a total n00b
some slag. ;-)

Now for the code:

@code start
#include <iostream>
#include <vector>
#include <bitset>
#include <ctime>
const unsigned short Size = 4; // 2^N
const unsigned short Log2 = 2; // N, log2(Size)
std::bitset<Siz e*Size*Size> YZ;
std::bitset<Siz e*Size*Size> XZ;
std::bitset<Siz e*Size*Size> XY;
std::bitset<Siz e*Size*Size> V;
struct Stack {
unsigned short z:Log2;
unsigned short y:Log2;
unsigned short x:Log2;
bool dir[6];
};
struct {
union {
struct {
unsigned short z:Log2;
unsigned short y:Log2;
unsigned short x:Log2;
};
unsigned long long id:Log2*3;
};
} pos;
short rand_int(short i) {
return rand() % i;
}
void new_grid() {
std::vector<Sta ck> stack(1);
bool loop = true;
YZ.set();
XZ.set();
XY.set();
V.set();
V.flip();
srand(time(0));
pos.x = rand_int(6);
pos.y = rand_int(6);
pos.z = rand_int(6);
V[pos.id] = 1;
stack.back().x = pos.x;
stack.back().y = pos.y;
stack.back().z = pos.z;
stack.resize(st ack.size()+1);
while (stack.size() > 0) {
for (int choice = rand_int(6), loop = true;
loop == true;
choice = rand_int(6)) {
stack.back().di r[choice] = 1;
if (choice == 0) {
pos.x++;
if (V[pos.id] == 1) pos.x--;
else {
loop = false;
pos.x--;
YZ[pos.id] = 0;
pos.x++;
}
}
else if (choice == 1) {
pos.y++;
if (V[pos.id] == 1) pos.y--;
else {
loop = false;
pos.y--;
XZ[pos.id] = 0;
pos.y++;
}
}
else if (choice == 2) {
pos.z++;
if (V[pos.id] == 1) pos.z--;
else {
loop = false;
pos.z--;
XY[pos.id] = 0;
pos.z++;
}
}
else if (choice == 3) {
pos.x--;
if (V[pos.id] == 1) pos.x++;
else {
loop = false;
YZ[pos.id] = 0;
}
}
else if (choice == 4) {
pos.y--;
if (V[pos.id] == 1) pos.y++;
else {
loop = false;
XZ[pos.id] = 0;
}
}
else if (choice == 5) {
pos.z--;
if (V[pos.id] == 1) pos.z++;
else {
loop = false;
XY[pos.id] = 0;
}
}
if (loop == true &&
stack.back().di r[0]+stack.back().d ir[1]+stack.back().d ir[2]+
stack.back().di r[3]+stack.back().d ir[4]+stack.back().d ir[5]
== 6) {
loop = false;
stack.pop_back( );
pos.x = stack.back().x;
pos.y = stack.back().y;
pos.z = stack.back().z;
}
else if (loop == false) {
V[pos.id] = 1;
stack.back().x = pos.x;
stack.back().y = pos.y;
stack.back().z = pos.z;
stack.resize(st ack.size()+1);
}
}
//// temp progress overview ///////////
/**/ system("cls"); /**/
/**/ std::cout << YZ << std::endl; /**/
/**/ std::cout << XZ << std::endl; /**/
/**/ std::cout << XY << std::endl; /**/
/**/ std::cout << V; /**/
///////////////////////////////////////
}
}

int main() {
while (0==0)
new_grid();
}
@code end

Now, this code is ofcouse far from finished, but this actually work,
that is progress and should be celebrated.

Now the most important things to discuss would be:
1) the somewhat inapropiate union.
2) the resize(size()+1 )
3) the Log2, Size
4) the last if loop witch doesnt look good at all ;-)
5) the grid generation code that is does indeed need some optimizing.
6) any other issue that you should find interesting.

NB.
This code does indeed need optimizing and altering but haven programed
for no longer than a month, theres still alot i dont know/understand,
so please give me some input.

Best
Zacariaz

Feb 17 '06 #1
19 2364

<fe**********@h otmail.com> wrote in message
news:11******** **************@ z14g2000cwz.goo glegroups.com.. .
: Some might remember that i, not so long ago, started a treath or two
: about a weird 3d labyrinth. I now have a working code, that i want to
: share, hear comments, advice, ect., but first let me explain what its
: all about.
:
: The whole labyrinth is a cubic in its self and it contains x^3 cubic
: rooms.
: The labyrinth is infinite/finite, it has no borders, but still have a
: size.
: fx. if the size of the labytrint is 2^3 and you find yourself at
: coordinate 3,3,3 you're really finding your self at the coordinate
: 1,1,1.
: Each room has 6 wall/possible doors, however, adjacent rooms shares a
: wall, so we only need to keep track of three wall per room.
: A wall can be set or unset, if unset, ofcourse there is nowall and your
: free to move to the next room.
: The grid pattern follow one simple room: "you must, at all time be able
: to find a path from one room to another."
: This tricky problem is solved by setting all walls in the labyrinth and
: setting a start position at random, then picking a direction at random.
: If the room in that direction have'nt been visited yet, brake down the
: wall and move there and start over, else try again. If you cant move
: any further, pop back to last position and start over from there. The
: grid is ready when you are stuck at the start position.
:
: The only question left should be: "what to use it for?"
: Well, i can think of many options, but for a start lets just this of a
: mouse in a labyrint ;-)
:
: Last i would like to thank two people:
: "Kai-Uwe Bux"
: For helping me alot with the datastructure.
: "someone i cant remember the name of"
: For suplying the idea for the grid generation.
:
: And ofcourse i want to thank everyone else for cutting a total n00b
: some slag. ;-)
:
: Now for the code:
:
: @code start
: #include <iostream>
: #include <vector>
: #include <bitset>
: #include <ctime>
: const unsigned short Size = 4; // 2^N
: const unsigned short Log2 = 2; // N, log2(Size)
: std::bitset<Siz e*Size*Size> YZ;
: std::bitset<Siz e*Size*Size> XZ;
: std::bitset<Siz e*Size*Size> XY;
: std::bitset<Siz e*Size*Size> V;
: struct Stack {
: unsigned short z:Log2;
: unsigned short y:Log2;
: unsigned short x:Log2;
: bool dir[6];
: };
: struct {
: union {
: struct {
NB: anonymous struct members are not a
standard/portable feature of C++

: unsigned short z:Log2;
: unsigned short y:Log2;
: unsigned short x:Log2;
: };
: unsigned long long id:Log2*3;
: };
You are indeed playing with fire here.
Furthermore, using bit-fields might be
a performance pessimization rather than
an optimization. Have you checked ?

: } pos;
: short rand_int(short i) {
: return rand() % i;
Using upper bits of the value returned by
rand() usually provides better 'randomness',
but this might not a big deal here...

: }
: void new_grid() {
: std::vector<Sta ck> stack(1);
: bool loop = true;
NB: in C++, it is seen as a best practice to
declare local variables just before use,
as late as possible.

: YZ.set();
: XZ.set();
: XY.set();
: V.set();
: V.flip();
NB: V.reset() is equivalent to set() + flip()

: srand(time(0));
: pos.x = rand_int(6);
: pos.y = rand_int(6);
: pos.z = rand_int(6);
'6' is not the range of values you want
for pos ! --> 'Size' instead

: V[pos.id] = 1;
If this works on your platform, it is by
pure chance.
It is much better to use direcly:
V[ pos.x + Size*(pos.y+Siz e*pos.z) ]
( possibly have an inline function
to write V[ makeIndex(x,y,z )] )
And you could get rid of the 'pos' variable
altogether (replace with:
unsigned short posx, posy, posz; )

: stack.back().x = pos.x;
: stack.back().y = pos.y;
: stack.back().z = pos.z;
: stack.resize(st ack.size()+1);
What you need to do is first create an
element of type 'Stack' (really a stack item),
and then call:
Stack item;
item.x = pos.x;
item.y = pos.y;
item.z = pos.z;
stack.push_back ( item );
Even better: add a constructor to struct Stack
that takes the x,y,z position as a parameter.

: while (stack.size() > 0) {
or: while( ! stack.empty() ) // cleaner IMO

: for (int choice = rand_int(6), loop = true;
: loop == true;
: choice = rand_int(6)) {
Get rid of this inner loop (see below).
Keep 'choice' as a first statement:
int choice = rand_int(6);
Also:
bool loop = true; // if needed...

: stack.back().di r[choice] = 1;
You should first check that dir[choice] is zero,
otherwise you can skip all the rest:
if( stack.back().di r[choice]!=0 ) continue;

Instead of the chain of if-s, you really
should use:
switch( choice ) {
case 0: ...
case 1: ...
etc.
}
: if (choice == 0) {
: pos.x++;
: if (V[pos.id] == 1) pos.x--;
: else {
: loop = false;
: pos.x--;
: YZ[pos.id] = 0;
: pos.x++;

: }
: }
: else if (choice == 1) {
: pos.y++;
: if (V[pos.id] == 1) pos.y--;
: else {
: loop = false;
: pos.y--;
: XZ[pos.id] = 0;
: pos.y++;
: }
: }
: else if (choice == 2) {
: pos.z++;
: if (V[pos.id] == 1) pos.z--;
: else {
: loop = false;
: pos.z--;
: XY[pos.id] = 0;
: pos.z++;
: }
: }
: else if (choice == 3) {
: pos.x--;
: if (V[pos.id] == 1) pos.x++;
: else {
: loop = false;
: YZ[pos.id] = 0;
: }
: }
: else if (choice == 4) {
: pos.y--;
: if (V[pos.id] == 1) pos.y++;
: else {
: loop = false;
: XZ[pos.id] = 0;
: }
: }
: else if (choice == 5) {
: pos.z--;
: if (V[pos.id] == 1) pos.z++;
: else {
: loop = false;
: XY[pos.id] = 0;
: }
: }
: if (loop == true &&
: stack.back().di r[0]+stack.back().d ir[1]+stack.back().d ir[2]+
: stack.back().di r[3]+stack.back().d ir[4]+stack.back().d ir[5]
: == 6) {
: loop = false;
: stack.pop_back( );
: pos.x = stack.back().x;
: pos.y = stack.back().y;
: pos.z = stack.back().z;
: }
: else if (loop == false) {
: V[pos.id] = 1;
: stack.back().x = pos.x;
: stack.back().y = pos.y;
: stack.back().z = pos.z;
: stack.resize(st ack.size()+1);
: }
if( ! loop ) {
V.set( makeInd[posx,posy,posz] );
stack.push_back ( StackItem(posx, posy,posz) )
{
else if( ... all directions are clear ... ) {
stack.pop_back( );
}
// no need for the additional inner loop,
// all happens through the stack

: }
: //// temp progress overview ///////////
: /**/ system("cls"); /**/
: /**/ std::cout << YZ << std::endl; /**/
: /**/ std::cout << XZ << std::endl; /**/
: /**/ std::cout << XY << std::endl; /**/
: /**/ std::cout << V; /**/
: ///////////////////////////////////////
: }
: }
:
: int main() {
: while (0==0)
: new_grid();
: }
: @code end
:
: Now, this code is ofcouse far from finished, but this actually work,
: that is progress and should be celebrated.
:
: Now the most important things to discuss would be:
: 1) the somewhat inapropiate union.
It's a no-no. Use a member function that returns an
index, or a separate index-making function.
The bitfields are an unnecessary pessimization.

: 2) the resize(size()+1 )
Use push_back, add a constructor for your stack element.

: 3) the Log2, Size
Log2 is unnecessary if you get rid of all the bitfields.

: 4) the last if loop witch doesnt look good at all ;-)
Get rid of it.
Also keep in mind that you can use continue; / break;

: 5) the grid generation code that is does indeed need some optimizing.
See notes in the code to make shallower 'mis-hits'.
Insead of a bool dir[6] array, you could use
some bit arithmetic:
unsigned char dirFlags;
First initialize it with 0 (all bits cleared).
Then:
bool dirWasVisited = 0!=( dirFlags&(1<<ch oice) );
To set as visited:
dirFlags |= (1<<choice);
To check if all was visited:
bool allVisited = ( dirFlags == (1<<6)-1 );

: 6) any other issue that you should find interesting.
In the worst case, you could recurce (i.e. add items
to the stack) as deeply as pow(Size,3), which could
be a performance problem, and might not be what you want.
There could be other approaches...

: NB.
: This code does indeed need optimizing and altering but haven programed
: for no longer than a month, theres still alot i dont know/understand,
: so please give me some input.
Not bad at all for someone who just got started ;)
I hope this helps,
Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
Feb 17 '06 #2

Ivan Vecerina skrev:
<fe**********@h otmail.com> wrote in message
news:11******** **************@ z14g2000cwz.goo glegroups.com.. .
: Some might remember that i, not so long ago, started a treath or two
: about a weird 3d labyrinth. I now have a working code, that i want to
: share, hear comments, advice, ect., but first let me explain what its
: all about.
:
: The whole labyrinth is a cubic in its self and it contains x^3 cubic
: rooms.
: The labyrinth is infinite/finite, it has no borders, but still have a
: size.
: fx. if the size of the labytrint is 2^3 and you find yourself at
: coordinate 3,3,3 you're really finding your self at the coordinate
: 1,1,1.
: Each room has 6 wall/possible doors, however, adjacent rooms shares a
: wall, so we only need to keep track of three wall per room.
: A wall can be set or unset, if unset, ofcourse there is nowall and your
: free to move to the next room.
: The grid pattern follow one simple room: "you must, at all time be able
: to find a path from one room to another."
: This tricky problem is solved by setting all walls in the labyrinth and
: setting a start position at random, then picking a direction at random.
: If the room in that direction have'nt been visited yet, brake down the
: wall and move there and start over, else try again. If you cant move
: any further, pop back to last position and start over from there. The
: grid is ready when you are stuck at the start position.
:
: The only question left should be: "what to use it for?"
: Well, i can think of many options, but for a start lets just this of a
: mouse in a labyrint ;-)
:
: Last i would like to thank two people:
: "Kai-Uwe Bux"
: For helping me alot with the datastructure.
: "someone i cant remember the name of"
: For suplying the idea for the grid generation.
:
: And ofcourse i want to thank everyone else for cutting a total n00b
: some slag. ;-)
:
: Now for the code:
:
: @code start
: #include <iostream>
: #include <vector>
: #include <bitset>
: #include <ctime>
: const unsigned short Size = 4; // 2^N
: const unsigned short Log2 = 2; // N, log2(Size)
: std::bitset<Siz e*Size*Size> YZ;
: std::bitset<Siz e*Size*Size> XZ;
: std::bitset<Siz e*Size*Size> XY;
: std::bitset<Siz e*Size*Size> V;
: struct Stack {
: unsigned short z:Log2;
: unsigned short y:Log2;
: unsigned short x:Log2;
: bool dir[6];
: };
: struct {
: union {
: struct {
NB: anonymous struct members are not a
standard/portable feature of C++
ok, have seen it used alot, so i didnt see this of it as a problem, it
does however have solution.

: unsigned short z:Log2;
: unsigned short y:Log2;
: unsigned short x:Log2;
: };
: unsigned long long id:Log2*3;
: };
You are indeed playing with fire here.
Furthermore, using bit-fields might be
a performance pessimization rather than
an optimization. Have you checked ?
In this case where the bitfield is 2, let me explain why i have done
it.
@code start
pos.x = 3;
pos.x++;
// pos x should contain the value 0 now.
@code end

I know its now the wises way to go around that problem, but i my
oppinion the easyest.
Otherwise i have to check the number everytime i want to increement or
decreement it.

: } pos;
: short rand_int(short i) {
: return rand() % i;
Using upper bits of the value returned by
rand() usually provides better 'randomness',
but this might not a big deal here...
i asure you this is not a problem.

: }
: void new_grid() {
: std::vector<Sta ck> stack(1);
: bool loop = true;
NB: in C++, it is seen as a best practice to
declare local variables just before use,
as late as possible.
Ok, you learn every day; ;-)

: YZ.set();
: XZ.set();
: XY.set();
: V.set();
: V.flip();
NB: V.reset() is equivalent to set() + flip()
ofcourse.

: srand(time(0));
: pos.x = rand_int(6);
: pos.y = rand_int(6);
: pos.z = rand_int(6);
'6' is not the range of values you want
for pos ! --> 'Size' instead
a little typo, thanks for noticing ;-)

: V[pos.id] = 1;
If this works on your platform, it is by
pure chance.
It is much better to use direcly:
V[ pos.x + Size*(pos.y+Siz e*pos.z) ]
( possibly have an inline function
to write V[ makeIndex(x,y,z )] )
And you could get rid of the 'pos' variable
altogether (replace with:
unsigned short posx, posy, posz; )
Ya, i allready know this, and ill change it when feel like it, however
i need a solution for bitfield problem before i can get rit of 'pos'
alltogether.

: stack.back().x = pos.x;
: stack.back().y = pos.y;
: stack.back().z = pos.z;
: stack.resize(st ack.size()+1);
What you need to do is first create an
element of type 'Stack' (really a stack item),
and then call:
Stack item;
item.x = pos.x;
item.y = pos.y;
item.z = pos.z;
stack.push_back ( item );
Even better: add a constructor to struct Stack
that takes the x,y,z position as a parameter.
Here im just confused, i have ofcourse hear the expression
"constructo r" but isnt it something to use in classes and how cant it
solve the problem?

: while (stack.size() > 0) {
or: while( ! stack.empty() ) // cleaner IMO
Indeed...
: for (int choice = rand_int(6), loop = true;
: loop == true;
: choice = rand_int(6)) {
Get rid of this inner loop (see below).
Keep 'choice' as a first statement:
int choice = rand_int(6);
Also:
bool loop = true; // if needed...
i have tryed, but i keep failing...
: stack.back().di r[choice] = 1;
You should first check that dir[choice] is zero,
otherwise you can skip all the rest:
if( stack.back().di r[choice]!=0 ) continue;
Im somewhat confused here...

Instead of the chain of if-s, you really
should use:
switch( choice ) {
case 0: ...
case 1: ...
etc.
}
allready done ;-)
: if (choice == 0) {
: pos.x++;
: if (V[pos.id] == 1) pos.x--;
: else {
: loop = false;
: pos.x--;
: YZ[pos.id] = 0;
: pos.x++;

: }
: }
: else if (choice == 1) {
: pos.y++;
: if (V[pos.id] == 1) pos.y--;
: else {
: loop = false;
: pos.y--;
: XZ[pos.id] = 0;
: pos.y++;
: }
: }
: else if (choice == 2) {
: pos.z++;
: if (V[pos.id] == 1) pos.z--;
: else {
: loop = false;
: pos.z--;
: XY[pos.id] = 0;
: pos.z++;
: }
: }
: else if (choice == 3) {
: pos.x--;
: if (V[pos.id] == 1) pos.x++;
: else {
: loop = false;
: YZ[pos.id] = 0;
: }
: }
: else if (choice == 4) {
: pos.y--;
: if (V[pos.id] == 1) pos.y++;
: else {
: loop = false;
: XZ[pos.id] = 0;
: }
: }
: else if (choice == 5) {
: pos.z--;
: if (V[pos.id] == 1) pos.z++;
: else {
: loop = false;
: XY[pos.id] = 0;
: }
: }
: if (loop == true &&
: stack.back().di r[0]+stack.back().d ir[1]+stack.back().d ir[2]+
: stack.back().di r[3]+stack.back().d ir[4]+stack.back().d ir[5]
: == 6) {
: loop = false;
: stack.pop_back( );
: pos.x = stack.back().x;
: pos.y = stack.back().y;
: pos.z = stack.back().z;
: }
: else if (loop == false) {
: V[pos.id] = 1;
: stack.back().x = pos.x;
: stack.back().y = pos.y;
: stack.back().z = pos.z;
: stack.resize(st ack.size()+1);
: }
if( ! loop ) {
V.set( makeInd[posx,posy,posz] );
stack.push_back ( StackItem(posx, posy,posz) )
{
else if( ... all directions are clear ... ) {
stack.pop_back( );
}
// no need for the additional inner loop,
// all happens through the stack

: }
: //// temp progress overview ///////////
: /**/ system("cls"); /**/
: /**/ std::cout << YZ << std::endl; /**/
: /**/ std::cout << XZ << std::endl; /**/
: /**/ std::cout << XY << std::endl; /**/
: /**/ std::cout << V; /**/
: ///////////////////////////////////////
: }
: }
:
: int main() {
: while (0==0)
: new_grid();
: }
: @code end
:
: Now, this code is ofcouse far from finished, but this actually work,
: that is progress and should be celebrated.
:
: Now the most important things to discuss would be:
: 1) the somewhat inapropiate union.
It's a no-no. Use a member function that returns an
index, or a separate index-making function.
The bitfields are an unnecessary pessimization.
Some stuff ecplained above...

: 2) the resize(size()+1 )
Use push_back, add a constructor for your stack element.
Did that, but i ended up with twice the lengt it is now, dont ask me
why, never the less it seemed like a bad idea at the time.

: 3) the Log2, Size
Log2 is unnecessary if you get rid of all the bitfields.
But until i find a solution for the ++/-- problem explained above...

: 4) the last if loop witch doesnt look good at all ;-)
Get rid of it.
Also keep in mind that you can use continue; / break;
Again pretty confused...

: 5) the grid generation code that is does indeed need some optimizing.
See notes in the code to make shallower 'mis-hits'.
Insead of a bool dir[6] array, you could use
some bit arithmetic:
unsigned char dirFlags;
First initialize it with 0 (all bits cleared).
Then:
bool dirWasVisited = 0!=( dirFlags&(1<<ch oice) );
To set as visited:
dirFlags |= (1<<choice);
To check if all was visited:
bool allVisited = ( dirFlags == (1<<6)-1 );
ya....

: 6) any other issue that you should find interesting.
In the worst case, you could recurce (i.e. add items
to the stack) as deeply as pow(Size,3), which could
be a performance problem, and might not be what you want.
There could be other approaches...
Im listening...

: NB.
: This code does indeed need optimizing and altering but haven programed
: for no longer than a month, theres still alot i dont know/understand,
: so please give me some input.
Not bad at all for someone who just got started ;)
While thank you ;-)

I hope this helps,
Ivan


This must have taken a great deal of time to go trough, so i just want
to say thank you ;-)

Best
Zacariaz

Feb 17 '06 #3
Code altered a bit.

@code start
#include <iostream>
#include <vector>
#include <bitset>
#include <ctime>
const unsigned short Size = 4; // 2^N
const unsigned short Log2 = 2; // N, log2(Size)
std::bitset<Siz e*Size*Size> YZ;
std::bitset<Siz e*Size*Size> XZ;
std::bitset<Siz e*Size*Size> XY;
std::bitset<Siz e*Size*Size> V;
struct Stack {
unsigned short z:Log2;
unsigned short y:Log2;
unsigned short x:Log2;
bool dir[6];
};
struct {
union {
struct {
unsigned short z:Log2;
unsigned short y:Log2;
unsigned short x:Log2;
};
unsigned long long id:Log2*3;
};
} pos;
short rand_int(short i) {
return rand() % i;
}
void new_grid() {
std::vector<Sta ck> stack(1);
bool loop = true;
YZ.set();
XZ.set();
XY.set();
V.reset();
srand(time(0));
pos.x = rand_int(Size);
pos.y = rand_int(Size);
pos.z = rand_int(Size);
V[pos.id] = 1;
stack.back().x = pos.x;
stack.back().y = pos.y;
stack.back().z = pos.z;
stack.resize(st ack.size()+1);
while (!stack.empty() ) {
for (int choice = rand_int(6), loop = true;
loop; choice = rand_int(6)) {
stack.back().di r[choice] = 1;
switch(choice) {
case 0:
pos.x++;
if (V[pos.id] == 1) pos.x--;
else {
loop = false;
pos.x--;
YZ[pos.id] = 0;
pos.x++;
}
break;
case 1:
pos.y++;
if (V[pos.id] == 1) pos.y--;
else {
loop = false;
pos.y--;
XZ[pos.id] = 0;
pos.y++;
}
break;
case 2:
pos.z++;
if (V[pos.id] == 1) pos.z--;
else {
loop = false;
pos.z--;
XY[pos.id] = 0;
pos.z++;
}
break;
case 3:
pos.x--;
if (V[pos.id] == 1) pos.x++;
else {
loop = false;
YZ[pos.id] = 0;
}
break;
case 4:
pos.y--;
if (V[pos.id] == 1) pos.y++;
else {
loop = false;
XZ[pos.id] = 0;
}
break;
case 5:
pos.z--;
if (V[pos.id] == 1) pos.z++;
else {
loop = false;
XY[pos.id] = 0;
}
break;
}
if (!loop) {
V[pos.id] = 1;
stack.back().x = pos.x;
stack.back().y = pos.y;
stack.back().z = pos.z;
stack.resize(st ack.size()+1);
}
else if (stack.back().d ir[0] == 1 && stack.back().di r[1] == 1 &&
stack.back().di r[2] == 1 && stack.back().di r[3] == 1 &&
stack.back().di r[4] == 1 && stack.back().di r[5] == 1) {
loop = false;
stack.pop_back( );
pos.x = stack.back().x;
pos.y = stack.back().y;
pos.z = stack.back().z;
}
}
//// temp progress overview ///////////
/**/ system("cls"); /**/
/**/ std::cout << YZ << std::endl; /**/
/**/ std::cout << XZ << std::endl; /**/
/**/ std::cout << XY << std::endl; /**/
/**/ std::cout << V; /**/
///////////////////////////////////////
}
}

int main() {
while (true)
new_grid();
}
@code end

Feb 17 '06 #4
<fe**********@h otmail.com> wrote in message
news:11******** **************@ g44g2000cwa.goo glegroups.com.. .
: In this case where the bitfield is 2, let me explain
: why i have done it.
: @code start
: pos.x = 3;
: pos.x++;
: // pos x should contain the value 0 now.

Right. But it is easier and more portable to write:
pos.x = (pos.x+1)%Size;
or:
pos.x = (pos.x==Size-1) ? 0 : pos.x+1;
Why would you require Size to be a power of 2 ?

: @code end
:
: I know its now the wises way to go around that problem, but i my
: oppinion the easyest.
: Otherwise i have to check the number everytime i want to increement or
: decreement it.
Not such a big deal, really.

: > : stack.back().x = pos.x;
: > : stack.back().y = pos.y;
: > : stack.back().z = pos.z;
: > : stack.resize(st ack.size()+1);
: > What you need to do is first create an
: > element of type 'Stack' (really a stack item),
: > and then call:
: > Stack item;
: > item.x = pos.x;
: > item.y = pos.y;
: > item.z = pos.z;
: > stack.push_back ( item );
: > Even better: add a constructor to struct Stack
: > that takes the x,y,z position as a parameter.
:
: Here im just confused, i have ofcourse hear the expression
: "constructo r" but isnt it something to use in classes and how cant it
: solve the problem?

struct StackItem {
unsigned short x,y,z;
unsigned char testedDirs;

StackItem( unsigned short ix, unsigned short iy, unsigned short iz )
: x(ix), y(iy), z(iz)
, testedDirs(0)
{ }
};

std::vector<Sta ckItem> stack;

stack.push_back ( StackItem(posx, posy,posz) );

: >
: > : while (stack.size() > 0) {
: > or: while( ! stack.empty() ) // cleaner IMO
:
: Indeed...
: >
: > : for (int choice = rand_int(6), loop = true;
: > : loop == true;
: > : choice = rand_int(6)) {
: > Get rid of this inner loop (see below).
: > Keep 'choice' as a first statement:
: > int choice = rand_int(6);
: > Also:
: > bool loop = true; // if needed...
:
: i have tryed, but i keep failing...
: >
: > : stack.back().di r[choice] = 1;
: > You should first check that dir[choice] is zero,
: > otherwise you can skip all the rest:
: > if( stack.back().di r[choice]!=0 ) continue;
:
: Im somewhat confused here...

By calling repeatedly picking a random direction,
you will be checking the same direction a few
times again and again. Since you are remembering
already which directions where visited, you
can test it directly.

: > : 4) the last if loop witch doesnt look good at all ;-)
: > Get rid of it.
: > Also keep in mind that you can use continue; / break;
:
: Again pretty confused...

Pseudocode:
stack.push_back ( start_pos );
for(;;) { // infinite loop, will exit with break
if( stack.back().al lDirectionsWere Visited() )
{
stack.pop_back( );
if( stack.empty() ) break; else continue;
}

// pick a neighbor and process it

if( need to further explore from neighbor )
{
stack.push_back ( neighbor_pos );
}
}

: >
: > : 5) the grid generation code that is does indeed need some
optimizing.
: > See notes in the code to make shallower 'mis-hits'.
: > Insead of a bool dir[6] array, you could use
: > some bit arithmetic:
: > unsigned char dirFlags;
: > First initialize it with 0 (all bits cleared).
: > Then:
: > bool dirWasVisited = 0!=( dirFlags&(1<<ch oice) );
: > To set as visited:
: > dirFlags |= (1<<choice);
: > To check if all was visited:
: > bool allVisited = ( dirFlags == (1<<6)-1 );
:
: ya....
:
: >
: > : 6) any other issue that you should find interesting.
: > In the worst case, you could recurce (i.e. add items
: > to the stack) as deeply as pow(Size,3), which could
: > be a performance problem, and might not be what you want.
: > There could be other approaches...
:
: Im listening...

It is also about choosing the 'branchingness' of your
labyrinth: instead of looking from the top of the stack,
you could more randomly pick a cell (on the stack) from
which to extend your visit. (wouldn't guarantee a better
worst-case memory usage, only better average mem use).
There could be other ways to represent the backtracking
info, but in fact, at this stage, you probably shouldn't
worry about this...
Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
Feb 17 '06 #5

Ivan Vecerina skrev:
<fe**********@h otmail.com> wrote in message
news:11******** **************@ g44g2000cwa.goo glegroups.com.. .
: In this case where the bitfield is 2, let me explain
: why i have done it.
: @code start
: pos.x = 3;
: pos.x++;
: // pos x should contain the value 0 now.

Right. But it is easier and more portable to write:
pos.x = (pos.x+1)%Size;
or:
pos.x = (pos.x==Size-1) ? 0 : pos.x+1;
Why would you require Size to be a power of 2 ?
wasnt aware of those options and the second one i simply doesnt
understand.
If im not using bitfields it does have to be the power of 2.
: @code end
:
: I know its now the wises way to go around that problem, but i my
: oppinion the easyest.
: Otherwise i have to check the number everytime i want to increement or
: decreement it.
Not such a big deal, really.
I know now ;-)
: > : stack.back().x = pos.x;
: > : stack.back().y = pos.y;
: > : stack.back().z = pos.z;
: > : stack.resize(st ack.size()+1);
: > What you need to do is first create an
: > element of type 'Stack' (really a stack item),
: > and then call:
: > Stack item;
: > item.x = pos.x;
: > item.y = pos.y;
: > item.z = pos.z;
: > stack.push_back ( item );
: > Even better: add a constructor to struct Stack
: > that takes the x,y,z position as a parameter.
:
: Here im just confused, i have ofcourse hear the expression
: "constructo r" but isnt it something to use in classes and how cant it
: solve the problem?

struct StackItem {
unsigned short x,y,z;
unsigned char testedDirs;

StackItem( unsigned short ix, unsigned short iy, unsigned short iz )
: x(ix), y(iy), z(iz)
, testedDirs(0)
{ }
};

std::vector<Sta ckItem> stack;

stack.push_back ( StackItem(posx, posy,posz) );
hmm, have to give this a thought...

: >
: > : while (stack.size() > 0) {
: > or: while( ! stack.empty() ) // cleaner IMO
:
: Indeed...
: >
: > : for (int choice = rand_int(6), loop = true;
: > : loop == true;
: > : choice = rand_int(6)) {
: > Get rid of this inner loop (see below).
: > Keep 'choice' as a first statement:
: > int choice = rand_int(6);
: > Also:
: > bool loop = true; // if needed...
:
: i have tryed, but i keep failing...
: >
: > : stack.back().di r[choice] = 1;
: > You should first check that dir[choice] is zero,
: > otherwise you can skip all the rest:
: > if( stack.back().di r[choice]!=0 ) continue;
:
: Im somewhat confused here...

By calling repeatedly picking a random direction,
you will be checking the same direction a few
times again and again. Since you are remembering
already which directions where visited, you
can test it directly.
Now i understand you.
Again i tryed, and came up with something should have worked, but it
didnt, have yet to come up with the right code.

: > : 4) the last if loop witch doesnt look good at all ;-)
: > Get rid of it.
: > Also keep in mind that you can use continue; / break;
:
: Again pretty confused...

Pseudocode:
stack.push_back ( start_pos );
for(;;) { // infinite loop, will exit with break
if( stack.back().al lDirectionsWere Visited() )
{
stack.pop_back( );
if( stack.empty() ) break; else continue;
}

// pick a neighbor and process it

if( need to further explore from neighbor )
{
stack.push_back ( neighbor_pos );
}
}

: >
: > : 5) the grid generation code that is does indeed need some
optimizing.
: > See notes in the code to make shallower 'mis-hits'.
: > Insead of a bool dir[6] array, you could use
: > some bit arithmetic:
: > unsigned char dirFlags;
: > First initialize it with 0 (all bits cleared).
: > Then:
: > bool dirWasVisited = 0!=( dirFlags&(1<<ch oice) );
: > To set as visited:
: > dirFlags |= (1<<choice);
: > To check if all was visited:
: > bool allVisited = ( dirFlags == (1<<6)-1 );
:
: ya....
:
: >
: > : 6) any other issue that you should find interesting.
: > In the worst case, you could recurce (i.e. add items
: > to the stack) as deeply as pow(Size,3), which could
: > be a performance problem, and might not be what you want.
: > There could be other approaches...
:
: Im listening...

It is also about choosing the 'branchingness' of your
labyrinth: instead of looking from the top of the stack,
you could more randomly pick a cell (on the stack) from
which to extend your visit. (wouldn't guarantee a better
worst-case memory usage, only better average mem use).
There could be other ways to represent the backtracking
info, but in fact, at this stage, you probably shouldn't
worry about this...

k then, havent got time for more comment right now, but thank again.

Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form


Feb 17 '06 #6
<fe**********@h otmail.com> wrote in message
news:11******** **************@ z14g2000cwz.goo glegroups.com.. .
:
: Ivan Vecerina skrev:
:
: > <fe**********@h otmail.com> wrote in message
: > news:11******** **************@ g44g2000cwa.goo glegroups.com.. .
: > : In this case where the bitfield is 2, let me explain
: > : why i have done it.
: > : @code start
: > : pos.x = 3;
: > : pos.x++;
: > : // pos x should contain the value 0 now.
: >
: > Right. But it is easier and more portable to write:
: > pos.x = (pos.x+1)%Size;
: > or:
: > pos.x = (pos.x==Size-1) ? 0 : pos.x+1;
: > Why would you require Size to be a power of 2 ?
:
: wasnt aware of those options and the second one i simply doesnt
: understand.
: If im not using bitfields it does have to be the power of 2.

With bitfields you have to.
With the above you can use any wrap-around size.

The ( x ? a : b ) expression is interpreted as follows:
- if x is true, then use the value a
- if x is false, then use the value b

So you can write, when incrementing:
newPos = (pos==Size-1) ? 0 : pos+1 ;
when decrementing:
newPos = (pos==0) ? Size-1 : pos-1 ;
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
Feb 17 '06 #7

Ivan Vecerina skrev:
<fe**********@h otmail.com> wrote in message
news:11******** **************@ z14g2000cwz.goo glegroups.com.. .
:
: Ivan Vecerina skrev:
:
: > <fe**********@h otmail.com> wrote in message
: > news:11******** **************@ g44g2000cwa.goo glegroups.com.. .
: > : In this case where the bitfield is 2, let me explain
: > : why i have done it.
: > : @code start
: > : pos.x = 3;
: > : pos.x++;
: > : // pos x should contain the value 0 now.
: >
: > Right. But it is easier and more portable to write:
: > pos.x = (pos.x+1)%Size;
: > or:
: > pos.x = (pos.x==Size-1) ? 0 : pos.x+1;
: > Why would you require Size to be a power of 2 ?
:
: wasnt aware of those options and the second one i simply doesnt
: understand.
: If im not using bitfields it does have to be the power of 2. sry, i meant to write doesnt
With bitfields you have to.
With the above you can use any wrap-around size.

The ( x ? a : b ) expression is interpreted as follows:
- if x is true, then use the value a
- if x is false, then use the value b

So you can write, when incrementing:
newPos = (pos==Size-1) ? 0 : pos+1 ;
when decrementing:
newPos = (pos==0) ? Size-1 : pos-1 ;
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form


Feb 17 '06 #8
I have tryed to do some class thingy, my first time, and it seems to
work, however im somewhat stuck, dont really know where to go from
here.
I guess ill figure it out sooner or later, but if anyone want to
help/comment, heres the code:

@code start
#include <iostream>
#include <bitset>
#include <vector>
class Grid {
private:
static const unsigned int Size = 3; // max 1625 (0xffffffff^(1/3))
std::bitset<Siz e*Size*Size> YZ;
std::bitset<Siz e*Size*Size> XZ;
std::bitset<Siz e*Size*Size> XY;
std::bitset<Siz e*Size*Size> V;
unsigned int x,y,z;
unsigned int Rand_int(unsign ed int i) {return rand() % i;}
void Inc_x() {x = (x==Size-1) ? 0 : x+1;}
void Inc_y() {y = (y==Size-1) ? 0 : y+1;}
void Inc_z() {z = (z==Size-1) ? 0 : z+1;}
void Dec_x() {x = (x==0) ? Size-1 : x-1;}
void Dec_y() {y = (y==0) ? Size-1 : y-1;}
void Dec_z() {z = (z==0) ? Size-1 : z-1;}
unsigned long Get_id() {return x*Size*Size+y*S ize+z;}
public:
void New();
};
void Grid::New() {
srand(time(0));
x = Rand_int(Size);
y = Rand_int(Size);
z = Rand_int(Size);
YZ.set();
XZ.set();
XY.set();
V.reset();
std::vector<uns igned char> stack;
unsigned char back_stack;
}
/////////////////////////////////////////////////
// I've desided that i can get by with eigth //
// bits only. 3 to keep track on where we came //
// from and 5 to keep track on the rooms we //
// have/havent investigated, its a tricky one, //
// but i think i cant be done. Somehow... //
/////////////////////////////////////////////////
@code end

Best reagards
Zacariaz

Feb 18 '06 #9
<fe**********@h otmail.com> wrote in message
news:11******** *************@g 43g2000cwa.goog legroups.com...
:I have tryed to do some class thingy, my first time, and it seems to
: work, however im somewhat stuck, dont really know where to go from
: here.
I think it's time for you to do some reading and studying.
If you're not ready to buy a dead-tree book, you can start with
some that are available online, such as "Thinking in C++" from
Bruce Eckel:
http://www.mindview.net/Books/TICPP/...ngInCPP2e.html

: I guess ill figure it out sooner or later, but if anyone want to
: help/comment, heres the code:
:
: @code start
: #include <iostream>
: #include <bitset>
: #include <vector>
: class Grid {
: private:
: static const unsigned int Size = 3; // max 1625 (0xffffffff^(1/3))
: std::bitset<Siz e*Size*Size> YZ;
: std::bitset<Siz e*Size*Size> XZ;
: std::bitset<Siz e*Size*Size> XY;
: std::bitset<Siz e*Size*Size> V;
: unsigned int x,y,z;
: unsigned int Rand_int(unsign ed int i) {return rand() % i;}
: void Inc_x() {x = (x==Size-1) ? 0 : x+1;}
: void Inc_y() {y = (y==Size-1) ? 0 : y+1;}
: void Inc_z() {z = (z==Size-1) ? 0 : z+1;}
: void Dec_x() {x = (x==0) ? Size-1 : x-1;}
: void Dec_y() {y = (y==0) ? Size-1 : y-1;}
: void Dec_z() {z = (z==0) ? Size-1 : z-1;}
: unsigned long Get_id() {return x*Size*Size+y*S ize+z;}
: public:
: void New();
NB: you actually want this to be a constructor:
Grid();
: };
: void Grid::New() {
: srand(time(0));
: x = Rand_int(Size);
: y = Rand_int(Size);
: z = Rand_int(Size);
: YZ.set();
: XZ.set();
: XY.set();
: V.reset();
: std::vector<uns igned char> stack;
: unsigned char back_stack;
: }
: /////////////////////////////////////////////////
: // I've desided that i can get by with eigth //
: // bits only. 3 to keep track on where we came //
: // from and 5 to keep track on the rooms we //
: // have/havent investigated, its a tricky one, //
: // but i think i cant be done. Somehow... //
: /////////////////////////////////////////////////
: @code end
Read chapter 4 and following in vol. 1 above.

First of all, each object/class needs to have a single
purpose/responsibility.
It probably makes sense to have one class that stores
the structure of your labyrinth.
A position in the labyrinth probably should be an
independent class/object. Because, for example, you
could have multiple entities moving through the same
labyrinth.
If it is simple, the labyrinth-generator does not
need to be an object, but could be a single function.
Enjoy the journey,
Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
Feb 18 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

53
5694
by: Cardman | last post by:
Greetings, I am trying to solve a problem that has been inflicting my self created Order Forms for a long time, where the problem is that as I cannot reproduce this error myself, then it is difficult to know what is going on. One of these Order Forms you can see here... http://www.cardman.co.uk/orderform.php3
193
9525
by: Michael B. | last post by:
I was just thinking about this, specifically wondering if there's any features that the C specification currently lacks, and which may be included in some future standardization. Of course, I speak only of features in the spirit of C; something like object-orientation, though a nice feature, does not belong in C. Something like being able to #define a #define would be very handy, though, e.g: #define DECLARE_FOO(bar) #define...
7
2223
by: ThunderMusic | last post by:
Hi, I have a CheckBoxList and I want to add some javascript code to each CheckBox created by this CheckBoxList. I tried iterating through all items of the list, all the controls, do a FindControl, et al. with no good result. I would use the Control.Attribute.Add("OnClick", "some javascript code") Does someone know a solution? Thanks
6
2340
by: TPJ | last post by:
Help me please, because I really don't get it. I think it's some stupid mistake I make, but I just can't find it. I have been thinking about it for three days so far and I still haven't found any solution. My code can be downloaded from here: http://www.tprimke.net/konto/PyObject-problem.tar.bz2. There are some scripts for GNU/Linux system (bash to be precise). All you need to know is that there are four classes. (Of course, you may...
4
2204
by: Ravi Ambros Wallau | last post by:
Hi: We developed a set of ASP.NET Web Applications that never runs in stand-alone mode, but always inside a portal (Rainbow Portal). All modules are copied on that portal. My question is: load time takes, sometimes, three or four of minutes in a medium-level machine (a PIII 1.5 Ghz), when the binary contents are changed, or if the time of last modification of the web.config file is changed. An application that runs in "stand-alone" mode...
4
3007
by: Martínez | last post by:
Hi, Here's a scaled down version of what I'm working with. It execututes correctly in IE, but FireFox fails to run it. The JavaScript Console reports the error "Error: myform.getElementsByTagName("TD") has no properties" Why isn't this working? If it's a syntax issue, is there an alternate method that works across both browsers? <html>
20
4257
by: mike | last post by:
I help manage a large web site, one that has over 600 html pages... It's a reference site for ham radio folks and as an example, one page indexes over 1.8 gb of on-line PDF documents. The site is structured as an upside-down tree, and (if I remember correctly) never more than 4 levels. The site basically grew (like the creeping black blob) ... all the pages were created in Notepad over the last
8
9666
by: grpramodkumar | last post by:
HI, function change(value,sub) { subcat = document.getElementById(sub); subcat.options.value = value; }
4
15420
by: Michael | last post by:
I have a repeater web control. Currently I want to change some row's color based on defined condition. Is there any code sample demonstrating how to accomplish it? Thanks.
0
8814
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8591
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8660
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
5683
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4209
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4390
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2799
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2041
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1792
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.