Generating a random "maze" -- 3d Array C++ - c++

so I'm working on a school assignement, as I'm learning C++. I'm not so much looking for code to be given to me as help understanding/coming up with the right algorithm for this problem.
I need to create a (5x5x5) 3d maze of 1's and 0's. Populate it randomly (except 0,0,0 being a 1 for start and 4,4,4 being a 1 at the finish.
Here's what I've done.
I made a cube object:
#include "cube.h"
Cube :: Cube(int cube_value)
{
cube_value = 0;
chk_up = false;
chk_down = false;
chk_left = false;
chk_right = false;
chk_front = false;
chk_back = false;
}
Cube :: ~Cube(void){}
in my maze managing class I initialize like this
PathFinder::PathFinder()
{
// initializing / sizing 5x5x5 Maze
Maze.resize(5);
for(int y = 0; y < 5 ; ++y)
{
Maze[y].resize(5);
for(int z = 0; z<5 ; ++z)
{
Maze[y][z].resize(5);
}
}
int at_x = 0;
int at_y = 0;
int at_z = 0;
}
The header for that class:
#include "PathfinderInterface.h"
#include "cube.h"
class PathFinder : public PathfinderInterface {
private:
int at_x;
int at_y;
int at_z;
public:
vector<vector<vector<Cube> > > Maze;
PathFinder();
virtual ~PathFinder();
string getMaze();
void createRandomMaze();
bool importMaze(string file_name);
vector<string> solveMaze();
};
So I'm trying to populate it and this is what I have, it might not make a ton of sense:
void PathFinder :: fillmaze()
{
Maze[0][0][0].cube_value = 1;
Maze[4][4][4].cube_value = 1;
int atx = 0 , aty = 0 , atz = 0;
while(atx<5 && aty < 5 && atz < 5)
{
if(atz == 5)
{
aty = aty + 1;
}
if(aty == 5)
{
atx = atx + 1;
atx = 0;
}
for(atz=0 ; atz<5 ; ++atz)
{
if((atx!= 0 && aty!=0 && atz!=0) || (atx!=4 && aty!=4 && atz!= 4) )
{
Maze[atx][aty][atz].cube_value = (rand() % 2);
}
}
}
}
I'm attempting to fill all the z axis and trace to the right on x, then move up one y and do the same, is this a good approach, or is there a better way of doing this? I'm just getting pretty confused.

void PathFinder :: fillmaze()
{
int atx = 0 , aty = 0 , atz = 0;
while(atz<=4)
{
if(atx == 5)
{
aty = aty + 1;
}
if(aty == 5)
{
aty = 0;
atz = atz + 1;
}
if(atz < 5)
{
for(atx=0 ; atx<5 ; ++atx)
{
Maze[atx][aty][atz].cube_value = (rand() % 2);
}
}
}
Maze[0][0][0].cube_value = 1;
Maze[4][4][4].cube_value = 1;
}
This worked! Now on to maze traversal! :/

Related

How to slow down generation of platform sprite/imageview in C++'s poScene CinderBlock

I'm trying implement a doodle jump video game. So far my program works well except the fact that platform are being generated rapidly rather than slowly being incremented as the player proceeds upwards. I'm using the cinder framework to implement it and using the poScene cinderblock to help me with the game flow and animation. The doodle character and each platform is a single jpg.
From my understanding, I think the platform is being generated every time update() is being called, which occurs at every frame. I tried using "std::chrono_duration_cast" to get time in ticks to cause a delay in the update function being called, but it doesn't seem to work.
I also tried calling the manipulatePlatform in Setup() but if I do that, the image of platform is not being generated.
using namespace cinder;
using cinder::app::KeyEvent;
namespace myapp {
using namespace po::scene;
using cinder::app::KeyEvent;
using po::scene::ImageView;
using po::scene::View;
MyApp::MyApp() {
state_ = GameState::kPlaying;
speed_ = 20;
}
void MyApp::setup() {
SoundSetUp(background_sound_,"BackgroundMusic.wav");
mViewController = ViewController::create();
my_scene = Scene::create(mViewController);
//setUpIntro();
}
void MyApp::DrawBackground() {
cinder::gl::Texture2dRef texture2D = cinder::gl::Texture::create(
cinder::loadImage(MyApp::loadAsset("background.jpg")));
cinder::gl::draw(texture2D, getWindowBounds());
}
void MyApp::SetUpCharacter() {
my_scene->getRootViewController()->getView()->addSubview(character);
}
void MyApp::SetUpPlatform() {
my_scene->getRootViewController()->getView()->addSubview(platform);
}
void MyApp::ManipulatePlatform() {
cinder::gl::Texture2dRef texture_platform = cinder::gl::Texture::create(
cinder::loadImage(MyApp::loadAsset("platform.jpg")));
platform = po::scene::ImageView::create(texture_platform);
my_scene->getRootViewController()->getView()->addSubview(platform);
point array[20];
for (int i = 0; i < 10; i++) {
array[i].x = cinder::Rand::randInt() % 400;
array[i].y = cinder::Rand::randInt() % 533;
}
if (y < h) {
for (int i = 0; i < 10; i++) {
y = h;
array[i].y = array[i].y - change_in_height;
if (array[i].y > 533) {
array[i].y = 0;
array[i].x = cinder::Rand::randInt() % 400;
}
}
}
auto end = std::chrono::steady_clock::now();
for (int i = 0; i < 10; i++) {
platform->setPosition(array[i].x, array[i].y);
}
}
void MyApp::SimulateGame() {
cinder::gl::Texture2dRef texture_character = cinder::gl::Texture::create(
cinder::loadImage(MyApp::loadAsset("doodle.jpg")));
character = po::scene::ImageView::create(texture_character);
my_scene->getRootViewController()->getView()->addSubview(character);
point array[20];
change_in_height = change_in_height + 0.2;
y = y + change_in_height;
if (y > 500) {
change_in_height = change_in_height - 10;
}
for (int i = 0; i < 10; i++) {
if ((x + 50 > array[i].x) && (x + 20 < array[i].x + 68)
&& (y + 70 > array[i].y) && (y + 70 < array[i].y + 14) && (change_in_height > 0)) {
change_in_height = -10;
}
}
character->setPosition(x, y);
}
void MyApp::update() {
auto start = std::chrono::steady_clock::now();
ManipulatePlatform();
SimulateGame();
auto end = std::chrono::steady_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::seconds>(end - start).count();
while (duration < 100) {
std::cout << duration++;
}
my_scene->update();
}
void MyApp::draw() {
my_scene->getRootViewController()->getView()->removeAllSubviews();
DrawBackground();
SetUpPlatform();
SetUpCharacter();
my_scene->draw();
}
void MyApp::keyDown(KeyEvent event) {
switch (event.getCode()) {
case KeyEvent::KEY_RIGHT:
x = x + 50;
break;
case KeyEvent::KEY_LEFT:
x = x - 50;
}
}
void MyApp::ResetGame() {
my_scene->getRootViewController()->getView()->removeAllSubviews();
}
void MyApp::SoundSetUp(cinder::audio::VoiceRef &audio_object, std::string file_path) {
cinder::audio::SourceFileRef sourceFile = cinder::audio::load(MyApp::loadAsset(file_path));
audio_object = cinder::audio::Voice::create(sourceFile);
audio_object->start();
}
void MyApp::setUpIntro() {
intro_background_doodle_jump = cinder::gl::Texture::create(
cinder::loadImage(MyApp::loadAsset("intro.jpg")));
intro_background_doodle_jump->setCleanBounds(cinder::Area(0, 0 , getWindowWidth(), getWindowHeight()));
}
}// namespace myapp

Error C2440: 'return' : cannot convert from 'int [2]' to 'int (&&)[2]'

I haven't programmed in a while, so my code might be a bit sloppy. The only thing the program does is create a 4x4 bool grid with only the top left value true. It then runs it with the checkAdjacentTiles, that should return the tiles touching it (the one to the right and the one underneath). I get an error instead. I have a feeling this has to do with my vector: std::vector<int[2]> checkAdjacentTiles(bool[4][4]);, since the int [2]. Thanks for the help!
#include <stdio.h>
#include <vector>
std::vector<int[2]> checkAdjacentTiles(bool[4][4]);
int main() {
bool grid[4][4];
grid[0][0] = 1;
std::vector<int[2]> temp = checkAdjacentTiles(grid);
for (int i = 0; i < (int)temp.size(); i++) {
printf("(%i, %i)\n", temp[i][0], temp[i][1]);
}
getchar();
return 0;
}
std::vector<int[2]> checkAdjacentTiles(bool checkGrid[4][4]) {
int relAdjacentSides[4][2] = { { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, -1 } };
std::vector<int[2]> adjacentSides;
for (int x = 0; x < 4; x++) {
for (int y = 0; y < 4; y++) {
for (int i = 0; i < 4; i++) {
if (x + relAdjacentSides[i][0] >= 0 && x + relAdjacentSides[i][0] < 4) {
if (y + relAdjacentSides[i][1] >= 0 && y + relAdjacentSides[i][1] < 4) {
if (!checkGrid[x + relAdjacentSides[i][0], y + relAdjacentSides[i][1]]) {
bool stop = 0;
for (int v = 0; v < (int)adjacentSides.size(); v++) {
if (adjacentSides[v][0] == x + relAdjacentSides[i][0] && adjacentSides[v][1] == y + relAdjacentSides[i][1]) {
stop = 1;
break;
}
}
if (!stop) {
adjacentSides.push_back({ x + relAdjacentSides[i][0], y + relAdjacentSides[i][1] });
}
}
}
}
}
}
}
return adjacentSides;
}
I can't use int[2] in a vector for some reason. I ended up using std::pair<int,int> instead and it works fine. Thanks jhnnslschnr.

Placing random numbers in a grid

I need to place numbers within a grid such that it doesn't collide with each other. This number placement should be random and can be horizontal or vertical. The numbers basically indicate the locations of the ships. So the points for the ships should be together and need to be random and should not collide.
I have tried it:
int main()
{
srand(time(NULL));
int Grid[64];
int battleShips;
bool battleShipFilled;
for(int i = 0; i < 64; i++)
Grid[i]=0;
for(int i = 1; i <= 5; i++)
{
battleShips = 1;
while(battleShips != 5)
{
int horizontal = rand()%2;
if(horizontal == 0)
{
battleShipFilled = false;
while(!battleShipFilled)
{
int row = rand()%8;
int column = rand()%8;
while(Grid[(row)*8+(column)] == 1)
{
row = rand()%8;
column = rand()%8;
}
int j = 0;
if(i == 1) j= (i+1);
else j= i;
for(int k = -j/2; k <= j/2; k++)
{
int numberOfCorrectLocation = 0;
while(numberOfCorrectLocation != j)
{
if(row+k> 0 && row+k<8)
{
if(Grid[(row+k)*8+(column)] == 1) break;
numberOfCorrectLocation++;
}
}
if(numberOfCorrectLocation !=i) break;
}
for(int k = -j/2; k <= j/2; k++)
Grid[(row+k)*8+(column)] = 1;
battleShipFilled = true;
}
battleShips++;
}
else
{
battleShipFilled = false;
while(!battleShipFilled)
{
int row = rand()%8;
int column = rand()%8;
while(Grid[(row)*8+(column)] == 1)
{
row = rand()%8;
column = rand()%8;
}
int j = 0;
if(i == 1) j= (i+1);
else j= i;
for(int k = -j/2; k <= j/2; k++)
{
int numberOfCorrectLocation = 0;
while(numberOfCorrectLocation != i)
{
if(row+k> 0 && row+k<8)
{
if(Grid[(row)*8+(column+k)] == 1) break;
numberOfCorrectLocation++;
}
}
if(numberOfCorrectLocation !=i) break;
}
for(int k = -j/2; k <= j/2; k++)
Grid[(row)*8+(column+k)] = 1;
battleShipFilled = true;
}
battleShips++;
}
}
}
}
But the code i have written is not able to generate the numbers randomly in the 8x8 grid.
Need some guidance on how to solve this. If there is any better way of doing it, please tell me...
How it should look:
What My code is doing:
Basically, I am placing 5 ships, each of different size on a grid. For each, I check whether I want to place it horizontally or vertically randomly. After that, I check whether the surrounding is filled up or not. If not, I place them there. Or I repeat the process.
Important Point: I need to use just while, for loops..
You are much better of using recursion for that problem. This will give your algorithm unwind possibility. What I mean is that you can deploy each ship and place next part at random end of the ship, then check the new placed ship part has adjacent tiles empty and progress to the next one. if it happens that its touches another ship it will due to recursive nature it will remove the placed tile and try on the other end. If the position of the ship is not valid it should place the ship in different place and start over.
I have used this solution in a word search game, where the board had to be populated with words to look for. Worked perfect.
This is a code from my word search game:
bool generate ( std::string word, BuzzLevel &level, CCPoint position, std::vector<CCPoint> &placed, CCSize lSize )
{
std::string cPiece;
if ( word.size() == 0 ) return true;
if ( !level.inBounds ( position ) ) return false;
cPiece += level.getPiece(position)->getLetter();
int l = cPiece.size();
if ( (cPiece != " ") && (word[0] != cPiece[0]) ) return false;
if ( pointInVec (position, placed) ) return false;
if ( position.x >= lSize.width || position.y >= lSize.height || position.x < 0 || position.y < 0 ) return false;
placed.push_back(position);
bool used[6];
for ( int t = 0; t < 6; t++ ) used[t] = false;
int adj;
while ( (adj = HexCoord::getRandomAdjacentUnique(used)) != -1 )
{
CCPoint nextPosition = HexCoord::getAdjacentGridPositionInDirection((eDirection) adj, position);
if ( generate ( word.substr(1, word.size()), level, nextPosition, placed, lSize ) ) return true;
}
placed.pop_back();
return false;
}
CCPoint getRandPoint ( CCSize size )
{
return CCPoint ( rand() % (int)size.width, rand() % (int)size.height);
}
void generateWholeLevel ( BuzzLevel &level,
blockInfo* info,
const CCSize &levelSize,
vector<CCLabelBMFont*> wordList
)
{
for ( vector<CCLabelBMFont*>::iterator iter = wordList.begin();
iter != wordList.end(); iter++ )
{
std::string cWord = (*iter)->getString();
// CCLog("Curront word %s", cWord.c_str() );
vector<CCPoint> wordPositions;
int iterations = 0;
while ( true )
{
iterations++;
//CCLog("iteration %i", iterations );
CCPoint cPoint = getRandPoint(levelSize);
if ( generate (cWord, level, cPoint, wordPositions, levelSize ) )
{
//Place pieces here
for ( int t = 0; t < cWord.size(); t++ )
{
level.getPiece(wordPositions[t])->addLetter(cWord[t]);
}
break;
}
if ( iterations > 1500 )
{
level.clear();
generateWholeLevel(level, info, levelSize, wordList);
return;
}
}
}
}
I might add that shaped used in the game was a honeycomb. Letter could wind in any direction, so the code above is way more complex then what you are looking for I guess, but will provide a starting point.
I will provide something more suitable when I get back home as I don't have enough time now.
I can see a potential infinite loop in your code
int j = 0;
if(i == 1) j= (i+1);
else j= i;
for(int k = -j/2; k <= j/2; k++)
{
int numberOfCorrectLocation = 0;
while(numberOfCorrectLocation != i)
{
if(row+k> 0 && row+k<8)
{
if(Grid[(row)*8+(column+k)] == 1) break;
numberOfCorrectLocation++;
}
}
if(numberOfCorrectLocation !=i) break;
}
Here, nothing prevents row from being 0, as it was assignd rand%8 earlier, and k can be assigned a negative value (since j can be positive). Once that happens nothing will end the while loop.
Also, I would recommend re-approaching this problem in a more object oriented way (or at the very least breaking up the code in main() into multiple, shorter functions). Personally I found the code a little difficult to follow.
A very quick and probably buggy example of how you could really clean your solution up and make it more flexible by using some OOP:
enum Orientation {
Horizontal,
Vertical
};
struct Ship {
Ship(unsigned l = 1, bool o = Horizontal) : length(l), orientation(o) {}
unsigned char length;
bool orientation;
};
class Grid {
public:
Grid(const unsigned w = 8, const unsigned h = 8) : _w(w), _h(h) {
grid.resize(w * h);
foreach (Ship * sp, grid) {
sp = nullptr;
}
}
bool addShip(Ship * s, unsigned x, unsigned y) {
if ((x <= _w) && (y <= _h)) { // if in valid range
if (s->orientation == Horizontal) {
if ((x + s->length) <= _w) { // if not too big
int p = 0; //check if occupied
for (int c1 = 0; c1 < s->length; ++c1) if (grid[y * _w + x + p++]) return false;
p = 0; // occupy if not
for (int c1 = 0; c1 < s->length; ++c1) grid[y * _w + x + p++] = s;
return true;
} else return false;
} else {
if ((y + s->length) <= _h) {
int p = 0; // check
for (int c1 = 0; c1 < s->length; ++c1) {
if (grid[y * _w + x + p]) return false;
p += _w;
}
p = 0; // occupy
for (int c1 = 0; c1 < s->length; ++c1) {
grid[y * _w + x + p] = s;
p += _w;
}
return true;
} else return false;
}
} else return false;
}
void drawGrid() {
for (int y = 0; y < _h; ++y) {
for (int x = 0; x < _w; ++x) {
if (grid.at(y * w + x)) cout << "|S";
else cout << "|_";
}
cout << "|" << endl;
}
cout << endl;
}
void hitXY(unsigned x, unsigned y) {
if ((x <= _w) && (y <= _h)) {
if (grid[y * _w + x]) cout << "You sunk my battleship" << endl;
else cout << "Nothing..." << endl;
}
}
private:
QVector<Ship *> grid;
unsigned _w, _h;
};
The basic idea is create a grid of arbitrary size and give it the ability to "load" ships of arbitrary length at arbitrary coordinates. You need to check if the size is not too much and if the tiles aren't already occupied, that's pretty much it, the other thing is orientation - if horizontal then increment is +1, if vertical increment is + width.
This gives flexibility to use the methods to quickly populate the grid with random data:
int main() {
Grid g(20, 20);
g.drawGrid();
unsigned shipCount = 20;
while (shipCount) {
Ship * s = new Ship(qrand() % 8 + 2, qrand() %2);
if (g.addShip(s, qrand() % 20, qrand() % 20)) --shipCount;
else delete s;
}
cout << endl;
g.drawGrid();
for (int i = 0; i < 20; ++i) g.hitXY(qrand() % 20, qrand() % 20);
}
Naturally, you can extend it further, make hit ships sink and disappear from the grid, make it possible to move ships around and flip their orientation. You can even use diagonal orientation. A lot of flexibility and potential to harness by refining an OOP based solution.
Obviously, you will put some limits in production code, as currently you can create grids of 0x0 and ships of length 0. It's just a quick example anyway. I am using Qt and therefore Qt containers, but its just the same with std containers.
I tried to rewrite your program in Java, it works as required. Feel free to ask anything that is not clearly coded. I didn't rechecked it so it may have errors of its own. It can be further optimized and cleaned but as it is past midnight around here, I would rather not do that at the moment :)
public static void main(String[] args) {
Random generator = new Random();
int Grid[][] = new int[8][8];
for (int battleShips = 0; battleShips < 5; battleShips++) {
boolean isHorizontal = generator.nextInt(2) == 0 ? true : false;
boolean battleShipFilled = false;
while (!battleShipFilled) {
// Select a random row and column for trial
int row = generator.nextInt(8);
int column = generator.nextInt(8);
while (Grid[row][column] == 1) {
row = generator.nextInt(8);
column = generator.nextInt(8);
}
int lengthOfBattleship = 0;
if (battleShips == 0) // Smallest ship should be of length 2
lengthOfBattleship = (battleShips + 2);
else // Other 4 ships has the length of 2, 3, 4 & 5
lengthOfBattleship = battleShips + 1;
int numberOfCorrectLocation = 0;
for (int k = 0; k < lengthOfBattleship; k++) {
if (isHorizontal && row + k > 0 && row + k < 8) {
if (Grid[row + k][column] == 1)
break;
} else if (!isHorizontal && column + k > 0 && column + k < 8) {
if (Grid[row][column + k] == 1)
break;
} else {
break;
}
numberOfCorrectLocation++;
}
if (numberOfCorrectLocation == lengthOfBattleship) {
for (int k = 0; k < lengthOfBattleship; k++) {
if (isHorizontal)
Grid[row + k][column] = 1;
else
Grid[row][column + k] = 1;
}
battleShipFilled = true;
}
}
}
}
Some important points.
As #Kindread said in an another answer, the code has an infinite loop condition which must be eliminated.
This algorithm will use too much resources to find a solution, it should be optimized.
Code duplications should be avoided as it will result in more maintenance cost (which might not be a problem for this specific case), and possible bugs.
Hope this answer helps...

C++ Not Counting white beands

I need some help. I'm writing a code in C++ that will ultimately take a random string passed in, and it will do a break at every point in the string, and it will count the number of colors to the right and left of the break (r, b, and w). Here's the catch, the w can be either r or b when it breaks or when the strong passes it ultimately making it a hybrid. My problem is when the break is implemented and there is a w immediately to the left or right I can't get the program to go find the fist b or r. Can anyone help me?
#include <stdio.h>
#include "P2Library.h"
void doubleNecklace(char neck[], char doubleNeck[], int size);
int findMaxBeads(char neck2[], int size);
#define SIZE 7
void main(void)
{
char necklace[SIZE];
char necklace2[2 * SIZE];
int brk;
int maxBeads;
int leftI, rightI, leftCount = 0, rightCount=0, totalCount, maxCount = 0;
char leftColor, rightColor;
initNecklace(necklace, SIZE);
doubleNecklace(necklace, necklace2, SIZE);
maxBeads = findMaxBeads(necklace2, SIZE * 2);
checkAnswer(necklace, SIZE, maxBeads);
printf("The max number of beads is %d\n", maxBeads);
}
int findMaxBeads(char neck2[], int size)
{
int brk;
int maxBeads;
int leftI, rightI, leftCount = 0, rightCount=0, totalCount, maxCount = 0;
char leftColor, rightColor;
for(brk = 0; brk < 2 * SIZE - 1; brk++)
{
leftCount = rightCount = 0;
rightI = brk;
rightColor = neck2[rightI];
if(rightI == 'w')
{
while(rightI == 'w')
{
rightI++;
}
rightColor = neck2[rightI];
}
rightI = brk;
while(neck2[rightI] == rightColor || neck2[rightI] == 'w')
{
rightCount++;
rightI++;
}
if(brk > 0)
{
leftI = brk - 1;
leftColor = neck2[leftI];
if(leftI == 'w')
{
while(leftI == 'w')
{
leftI--;
}
leftColor = neck2[leftI];
}
leftI = brk - 1;
while(leftI >= 0 && neck2[leftI] == leftColor || neck2[leftI] == 'w')
{
leftCount++;
leftI--;
}
}
totalCount = leftCount + rightCount;
if(totalCount > maxCount)
{
maxCount = totalCount;
}
}
return maxCount;
}
void doubleNecklace(char neck[], char doubleNeck[], int size)
{
int i;
for(i = 0; i < size; i++)
{
doubleNeck[i] = neck[i];
doubleNeck[i+size] = neck[i];
}
}
I didn't study the code in detail, but something is not symmetric: in the for loop, the "left" code has an if but the "right" code doesn't. Maybe you should remove that -1 in the for condition and add it as an if for the "right" code:
for(brk = 0; brk < 2 * SIZE; brk++)
{
leftCount = rightCount = 0;
if (brk < 2 * SIZE - 1)
{
rightI = brk;
rightColor = neck2[rightI];
//...
}
if(brk > 0)
{
leftI = brk - 1;
leftColor = neck2[leftI];
//...
}
//...
Just guessing, though... :-/
Maybe you should even change those < for <=.

How to calculate bit transitions using bitset < >

I am new to C++. I want to calculate the no of transitions from 0 to 0, 0 to 1, 1 to 0 and 1 to 1 in a 9 bit sequence. I have written the following code;
int main {
srand((unsigned)time(0));
unsigned int x;
for (int i=0:i<=512;i++) // loop-1
{
x=rand()%512;
bitset<9>bitseq(x);
for(int j=0;j<=bitseq.size();j++) // loop-2
{
bool a= bitseq.test(j);
bool b= bitseq.test(j+1)
if ((a==0)&(b==0)==0)
{
transition0_0 = transition0_0 + 1; // transition from 0 to 0
}
else if ((a==0)&(b==1)==0)
{
transition0_1 = transition0_1 + 1;
else if ((a==1)&(b==0)==0)
{
transition1_0 = transition1_0 + 1;
else
{
transition1_1 = transition1_1 + 1;
cout<<transition0_0<<" "<<transition0_1<<endl;
cout<<transition1_0<<" "<<transition1_1<<endl;
}
}
Somebody please guide me on the following
how to save the last bit value in loop-2 to check the transition from last bit of the last bitset output to the 1st bit of the next bitset output?
If this does not work, How I can save it in vector and use iterators to check the transitions?
First of all, the loop index j is running past the end of the bitset. Indices go from 0 to bitseq.size()-1 (inclusive). If you're going to test j and j+1 the largest value j can take is bitseq.size()-2.
Second, the ==0 part that appears in your ifs is strange, you should just use
if( (a==0)&&(b==0) )
Notice the use of two &&. While a single & works for this code, I think it's better to use the operator that correctly conveys your intentions.
And then to answer your question, you can keep a "last bit" variable that is initially set to a sentinel value (indicating you're seeing the first bitseq just now) and compare it to bitseq[0] before the start of loop 2. Here's a modified version of your code that should do what you ask.
int main {
srand((unsigned)time(0));
unsigned int x;
int transition0_0 = 0,
transition0_1 = 0,
transition1_0 = 0,
transition1_1 = 0;
int prev = -1;
for (int i=0:i<=512;i++) // loop-1
{
x=rand()%512;
bitset<9> bitseq(x);
if( prev != -1 ) // don't check this on the first iteration
{
bool cur = bitseq.test(0);
if( !prev && !cur )
++transition0_0;
else if( !prev && cur )
++transition0_1;
else if( prev && !cur )
++transition1_0;
else
++transition1_1;
}
for(int j=0;j+1<bitseq.size();j++) // loop-2
{
bool a= bitseq.test(j);
bool b= bitseq.test(j+1)
if ((a==0)&&(b==0))
{
transition0_0 = transition0_0 + 1; // transition from 0 to 0
}
else if ((a==0)&&(b==1))
{
transition0_1 = transition0_1 + 1;
}
else if ((a==1)&&(b==0))
{
transition1_0 = transition1_0 + 1;
}
else
{
++transition1_1 = transition1_1 + 1;
}
} // for-2
prev = bitseq.test(bitseq.size()-1); // update prev for the next iteration
cout<<transition0_0<<" "<<transition0_1<<endl;
cout<<transition1_0<<" "<<transition1_1<<endl;
} // for-1
} // main
Would something like this be better for you? Use an array of 4 ints where [0] = 0->0, [1] = 0->1, [2] = 1->0, [3] = 1->1.
int main {
int nTransition[] = { 0,0,0,0 };
bool a,b;
unsigned int x;
int j;
srand ((unsigned)time(0));
for (int i = 0: i < 512; i++) {
x = rand () % 512;
bitset<9> bitseq(x);
if (i == 0) {
a = bitseq.test (0);
j = 1;
} else
j = 0;
for (; j < bitseq.size (); j++) {
b = bitseq.test(j);
int nPos = (a) ? ((b) ? 3 : 2) : ((b) ? 1 : 0);
nTransition[nPos]++;
a = b;
}
}
}