i have a program that generates a grid of 20x20 using a 2d array, it then populates it by randomly generating 2 numbers as co-ordinates, and then filling it with either an 'x' or an 'o' it has a maximum of 5 x's and 100 o's.

What i need it to do now, and the bit i'm stuck on is how to get it to randomly choose a square and move the contents up, down, left or right

``````#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>

using namespace std;

int main()
{
time_t now;
time(&now);
srand(now);
rand();
int nextStep;
int direction;
char lifeBoard;
//Creates the initial grid
for(int col=0; col<19; col++)
{
for(int row=0; row<19; row++)
{
lifeBoard[row][col]='.';
cout<<lifeBoard[row][col];
}
cout<<endl;
}
//Populates the grid with x's
for(int i=0;i<5;i++)
{
lifeBoard[rand()%19][rand()%19] = 'x';
}
//Populates the grid with o's
for(int i=0;i<100;i++)
{
lifeBoard[rand()%19][rand()%19] = 'o';
}
//Re-Draws the grid with the new charaters
for(int col=0; col<19; col++)
{
for(int row=0; row<19; row++)
{
cout<<lifeBoard[row][col];
}
cout<<endl;
}
direction = rand()%3;
//Moves the item up
if(direction=0)
{
lifeBoard[rand()%19][rand()%19]=row-1;
}
//Moves the item down
if(direction=1)
{
lifeBoard[rand()%19][rand()%19]=row+1;
}
system("Pause");
return 0;
}``````

thats what i got so far...
I am grateful of any help i get

## All 17 Replies

for(int col=0; col<19; col++)
{
for(int row=0; row<19; row++)

the above essentially is a 19 by 19 grid with cols and rows ranging from 0-18. Below likewise only uses numbers from 0-18.

lifeBoard[rand()%19][rand()%19] = 'x';

And this only uses numbers 0-2.

direction = rand()%3;

The following uses the assignment operator, not the coparison operator called equals.

if(direction=0)

There are other locations of the same problems that I didn't copy that need to be cleaned up, too.

To move a value up, do this:

board[x + 1][y] = board[x][y];

The same type of manipulations can be used to go down by one or right or left by one. However, the new location needs to be valid, so be careful around the edges of the board to not overwrite the array.

Also, you need to decide what to do with the value at board[x][y], once you have "moved" it. Does it remain unchanged so you've effectively added one more of whatever board[x][y] was and decreased by one whatever board[x + 1][y] was? or what.

I dont quite understand what you mean in this paragraph?

f
Also, you need to decide what to do with the value at board[x][y], once you have "moved" it. Does it remain unchanged so you've effectively added one more of whatever board[x][y] was and decreased by one whatever board[x + 1][y] was? or what.

Let's say board[r][c] starts out with 'o' and board[r + 1][c] starts out with 'x' and that before the move there are 4 x's and 96 o's and 100 ,'s on the board. copying board[r][c] to board[r + 1][c] to represent the move means there is one less x and one more o on the board than there was before the move. But if you swap the two cells then the number of x's and o's stays stable. And if you erase board[r][c] after the move then the number of x's goes down, but the number of o's does not. And so on.

Doing the copying without swapping or erasure and keeping track of the number of x's and o's on the board after say 100 or 1000 or 10000 random moves could potentially mimic how populations might act over the course of time subject to random activity. One would expect the number of x's to die out before the number of o's, but over time the number of ,'s should kill off both the x's and o's since there would be 3 times as many ,'s on the board than x's and o's combined to start out with.

This code will not do what you want:

``````//Populates the grid with x's
for(int i=0;i<5;i++)
{
lifeBoard[rand()%19][rand()%19] = 'x';
}
//Populates the grid with o's
for(int i=0;i<100;i++)
{
lifeBoard[rand()%19][rand()%19] = 'o';
}``````

What if during the population of the o's you overwrite an x?

i've got a series of conditions that governs how the x's and o's live...

The o's behave accordingly

• Move. Every time step, randomly try to move up, down, left or right. If the neighbouring cell in the selected direction is occupied or would move the greenfly off the grid, then the greenfly stays in the current cell.

• Breed. If a greenfly survives for three time steps, then at the end of the time step (that is, after moving) the greenfly will breed. This is simulated by creating a new greenfly in an adjacent (up, down, left or right) cell that is empty. If there are no empty cells available, then no breeding occurs. Once an offspring is produced a greenfly cannot produce an offspring until three more time steps have elapsed.

The x's behave this way

• Move. Every time step, if there is an adjacent greenfly (up, down, left or right), then the ladybird will move to that cell and eat the greenfly. Otherwise, the ladybird moves according to the same rules as the greenfly. Note that a ladybird cannot eat other ladybirds.

• Breed. If a ladybird survives for eight time steps, then at the end of the time step it will spawn off another ladybird in the same manner as the greenfly.

• Starve. If a ladybird has not eaten a greenfly within the last three time steps, then at the end of the third time step it will starve and die. The ladybird should then be removed from the grid of cells.

Yes, this is a uni assignment, i'm not asking for people to do it for me just help me, and point me in the right direction...

>>What if during the population of the o's you overwrite an x?

I assumed that possibility was covered by this statement in the original post:

>>a maximum of 5 x's and 100 o's.

which I interpretted to mean there could be 3 x's to start or 95 o's to start, but no more than 5 or 100 respectively. I didn't interpret that to mean there will be exactly 5 x's and exactly 100 o's.

>>I've got a series of conditions that governs how the x's and o's live

And it's a lot more complicated than the scenarios I reviewed earlier.

Presumably:
1) commas represent open spaces and
2) o's can only move where there is a comma,
3) x's can't move where another x is, but will overwrite o's and commas.
3) all x's and o's move at the same time, but each in a random direction
4) upon starvation a ladybird will be replaced with a comma
5) breeding adds either an o or an x if there is an adjacent open space
6) a simple, valid move removes an x or an o from a given cell, places a comma in the cell it moved from, and overwrites whatever is in the cell it moves to with the x or the o.
7) there may be between zero and 400 or either the commas, x's or 0's at any given time.
8) the only way an o is removed is if it is overwritten by an x
9) an x will be removed if it hasn't overwritten an o in three moves
10) each x and o needs to be able to keep track of how many moves it has survived to know whether it can breed or if it needs to die.
11) each x or o can try to move in just one random direction, each move, not all 4 directions depending on availability and optimum strength of move, though that could be argued either way.
12) some overarching architeture needs to be established. The board could be a simple 2 dimensional char array. Each time span could be accomplished by evaluating each cell to determine what value the char is and processing the move according to a set of rules as established for each char type. Ladybirds and greenflies could be classes so that each object can keep track of the information needed, such as last meal, breed this move, etc. Some thought needs to be given here. Give it a shot and post with your concerns.

Thanks, Will look over what i have so for, and start trying to make classes!

Anybody got any sites that can help me with classes, i'm a bit unsure on them?

Getting somewhere slowly,

First problem encoutered... How would i go about populating the grid using classes, will i have to do it in the same way or in a different way?

if its any use this is my current ladybird class

``````#include <iostream>

using namespace std;

{
private:
int lastMeal, breedCount;

public:
//Objects related to feeding
void setLastMeal()
{
lastMeal = 0;
}
void lastMealPlus()
{
lastMeal = lastMeal+1;
}
int showLastMeal()
{
return lastMeal;
}
//Objects related to breeding
void setBreedCount()
{
breedCount = 8;
}
void breedCountMinus()
{
breedCount = breedCount-1;
}
int showBreedCount()
{
return breedCount;
}
};``````

>>What if during the population of the o's you overwrite an x?

I assumed that possibility was covered by this statement in the original post:

>>a maximum of 5 x's and 100 o's.

which I interpretted to mean there could be 3 x's to start or 95 o's to start, but no more than 5 or 100 respectively. I didn't interpret that to mean there will be exactly 5 x's and exactly 100 o's.

You may assume that, but the program doesn't.
You will always get 100 o's but anywhere from 0 to 5 x's.

If you want 1-5 x's, you should choose a random value and place that many x's.
Then, if you then want 80-100, choose your random value and place that many o's but make sure you don't overwrite your x's

Declare a class called Cell with each Cell object having three parameters: a row number, a column number and a char (or enum type) which will represent whether Cell is open or occupied by a ladybird or a greenfly.

Add parameters for row and column numbers to the ladybird class with appropriate methods as needed.

Declare a 2d array of type Cell to represent the board. To display the board just print jsut the char value of each Cell using a loop. Set the default value of the Cells of the board to comma at the start of each simulation/game.

Declare an array of 400 ladybirds or a vector of ladybirds or a list of ladybirds. You can use a static array of ladybirds because you know at most you will have 400 of them. If you use a static array however, I would also keep track of the how many ladybirds are actually in the array.

To populate the board with 5 ladybirds use a loop. Inside the loop randomly select an empty Cell. Once you have a random empty cell then assign the value of x to the Cell's char value and assign the row number and column number to the ladybird object. Note: you may need to randomly generate row and column numbers more than once for each ladybird if for some reason you are unlucky enough to get the same numbers for row and column time after time after time. If you want to be sure that you don't overwrite existing ladybirds then be sure the Cell's value is empty before assigning it the value of x.

To populate the board with 100 greenflys, use a similar process.

If you want to have exactly 5 ladybirds and 100 greenflys when starting each program then be sure the Cell's char value is a comma before assigning it an x or an o. If you don't care if you overwrite already existing ladybirds and or existing greenflys (in which case you may have somewhere between 0-5 ladybirds and 1-100 greenflies----yea, it would be really unlikely to get the same row and column numbers one hundred times in a row using a random number generator, but it is possible, no matter how unlikely it is) then you don't need to check to see if the cell is empty first.

Inside the main class, i've got it drawing a grid using this code

``````#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>

using namespace std;

int main()
{
time_t now;
time(&now);
srand(now);
rand();
char lifeBoard;
int lastMeal;

//Sets the items that require counting to their default values
xcontroller.setLastMeal();
xcontroller.setBreedCount();
//Creates the initial grid with just .'s
for(int col=0; col<20; col++)
{
for(int row=0; row<20; row++)
{
lifeBoard[row][col]='.';
cout<<lifeBoard[row][col];
}
cout<<endl;
}
}``````

is this what you mean?

Declare a class called Cell with each Cell object having three parameters: a row number, a column number and a char (or enum type) which will represent whether Cell is open or occupied by a ladybird or a greenfly.

Add parameters for row and column numbers to the ladybird class with appropriate methods as needed

Little bit unsure of this bit? Do you you mean create a class with variables or something you explain, sorry if i'm a pain...

meant to say

can you explain, i'm still new to c++

Made some progress, not sure if its right, but i populated the grid using this code, is it right?

``````#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>

using namespace std;

int main()
{
time_t now;
time(&now);
srand(now);
rand();
char lifeBoard;
int lastMeal,direction;

//Sets the items that require counting to their default values
xcontroller.setLastMeal();
xcontroller.setBreedCount();
//Creates the initial grid with just .'s
for(int col=0; col<20; col++)
{
for(int row=0; row<20; row++)
{
lifeBoard[row][col]='.';
cout<<lifeBoard[row][col];
}
cout<<endl;
}
cout << "" << endl;
//Populating the grid
for(int i=0;i<100;i++)
{
lifeBoard[rand()%20][rand()%20];
if(lifeBoard[rand()%20][rand()%20]='.')
{
lifeBoard[rand()%20][rand()%20] = 'o';
}
else
{
i=0;
}
}
for(int i=0;i<5;i++)
{
lifeBoard[rand()%20][rand()%20];
if(lifeBoard[rand()%20][rand()%20]='.')
{
lifeBoard[rand()%20][rand()%20] = 'x';
}
else
{
i=0;
}
}

for(int col=0; col<20; col++)
{
for(int row=0; row<20; row++)
{
cout<<lifeBoard[row][col];
}
cout<<endl;
}
cout << "" << endl;
}``````

Another question

Is it possible to go through my 2D array and just pick out all the x's example

``````for each x in my array
{
randomly generate a number between 1 - 4
if number = 1
{
run moveup code
}
if number = 2
{
run movedown code
}
if number = 3
{
run moveleft code
}
if number = 4
{
run moveleft code
}
}
``````

I've been on vacation. If you are still working on your project
and haven't progressed beyond the last post, here's a little
gift that I think answers all the questions you've posted so far.
Note that none of the following code has been tested so use at your
own risk.

``````struct Cell
{
int row;
int col;
char value;
friend ostream & ostream<<(ostream & os, const Cell & rhs)
{os << rhs.value;  return os;}
};

{
int row;
int col;
int lastMeal;
int nextBreed;
LadyBird() : lastMeal(0), nextBreed(3){};
friend ostream & ostream<<(ostream & os, const LadyBird & rhs)
{
os << rhs.row << ' ' << rhs.col;
return os;
}
};

struct greenBug
{//dodah};

struct Game
{
const MAXSIZE = 20;
const MAXBIRDS = 5;
char board[MAXSIZE][MAXSIZE];
Game()
{
for(int i = 0; i < MAXSIZE; ++i)
for(int j = 0; j < MAXSIZE; ++j)
board[i][j] = ',';
}

void populateBoard
{
int row, col;
bool looking;
//populate board with LadyBirds
for(int i = 0; i < MAXBIRDS; ++i)
{
looking = true;
while(looking)
{
row = rand % MAXSIZE;
col = rand % MAXSIZE;
if(board[row][col] == ',')
{
board[row][col] == 'x';
l.row = row;
l.col = col;
lb.push_back(l);
looking = false;
}
}
}

//populate board with greenBugs
}

{
vector<LadyBird>::iterator start = lb.begin();
vector<LadyBird>::iterator stop = lb.end();
for( ; start != stop; ++start)
cout << *start << endl;
}

{
int move, lastR, lastC, nextR, nextC;
bool moved;
vector<LadyBird>::iterator current = lb.begin();
vector<LadyBird>::iterator stop = lb.end();
for( ; current != stop; ++current)
{
lastR = current->row;
lastC = current->col;
moved = false;

//each LadyBird gets a single shot at moving
move = rand % 4;

switch(move)
{
case 0://check next cell to right
nextR = current->row + 1;
nextC = current->col;
if(nextR < MAXSIZE)
{
if(board[nextR][nextC] != 'x')
{
moved = true;
if(board[nextR][nextC] == ',')
current->lastMeal += 1;
else
current->lastMeal = 1;
board[nextR][nextC] = 'x';
current->row = r;
}
}
break;
case 1://check cell below current cell
//etc
}

if(moved)
board[lastR][lastC] = ',';
else
current->lastMeal += 1;

if(current->lastMeal == 8)
{
if(moved)
board[nextR][nextC].value = ',';
else
board[current->row][current->col].value = ',';

lb.erase(current);
}

//logic regarding possible breeding probably goes here
}
}

friend ostream & ostream<<(ostream & os, const Board & rhs)
{
for(int i = 0; i < MAXSIZE; ++i)
{
for(int j = 0; j < MAXSIZE; ++J)
os << rhs.board[i][j] << '';
cout << endl;
}
return os;
}
};``````
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, learning, and sharing knowledge.