simplification needed

Hi there, I am writing a piece of code that simulates a random walk in 2 dimensions (an object chooses whether to move up, down, left or right randomly). I would like the program to run the simulation for many objects at the same time. The way i have written it means that for every object i add the code becomes about 40 lines longer. Can anyone help with a method that would simplify the code so that i could have many objects but not pages and pages of code. Thanks in advance
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <ctime>
#include <cstdlib>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<fstream>

using namespace std;

double dist(int a, int b);

int main() {
int randxA=0, randyA=0, randxB=0, randyB=0; // random value of x and y, the first object of of type A and second object is of type B
int xA=0, xB=0; // x and y postition
int yA=0, yB=0;
int n,N,uA=0,dA=0,lA=0,rA=0,uB=0,dB=0,lB=0,rB=0;; 
double zA=dist(xA,yA);
double zB=dist(xB,yB);

ofstream out;
ofstream dis;
out.open ("rwalk.txt");



cout<< "How many steps would you like to take? " ;
cin >> n ;

cout<< "Step number" << setw(4) << "xA" << setw(4) << "yA" << "  Distance" << setw(4) << "xB" << setw(4) << "yB" << "  Distance" <<endl;
out << "Step number" << setw(4) << "xA" << setw(4) << "yA" << "  Distance" << setw(4) << "xB" << setw(4) << "yB" << "  Distance" << endl;
cout << setw(11) << 0 << setw(4) << randxA << " " << setw(4) << randyA << " " << setw(8) << 0 << setw(4) << randxB << " " << setw(4) << randyB << " " << setw(8) << 0 <<endl;



  srand(time(0));
  

  for (int i=1 ; i<=n ; i++){
 
         int ranA=rand() % 2; // chooses whether to move on x or y axis
         int ranB=rand() % 2;
		 
		 
// object A	   	    
    if (ranA==0){
  
        randxA = rand() % 2;
        randyA = 0;
	   
      if ( randxA == 0 ){
   
          randxA=randxA-1; // moves left
	      lA=lA+1;
		  
      }else if ( randxA==1){
	  
            rA=rA+1; // moves right
      }
      
    }else if (ranA==1){
  
         randyA = rand() % 2;
         randxA = 0;
 
       if ( randyA == 0){
   
           randyA=randyA-1;  // moves down
	       dA=dA+1;
		   
       }else if ( randyA==1){
	   
           uA=uA+1; // moves up
       }


// object B	      
	 if (ranB==0){
  
        randxB = rand() % 2;
        randyB = 0;
	   
      if ( randxB == 0 ){
   
          randxB=randxB-1;
	      lB=lB+1;
		  
      }else if ( randxB==1){
	  
            rB=rB+1;
      }
      
    }else if (ranB==1){
  
         randyB = rand() % 2;
         randxB = 0;
 
       if ( randyB == 0){
   
           randyB=randyB-1;
	       dB=dB+1;
		   
       }else if ( randyB==1){
	   
           uB=uB+1;
       }
  	 }
    }
   xA=xA+randxA;
   yA=yA+randyA;
   xB=xB+randxB;
   yB=yB+randyB;
   double zA=dist(xA,yA);
   double zB=dist(xB,yB);
   cout  << setw(11) << i << setw(4) << xA << " " << setw(4) << yA << " " << setw(8) << zA << setw(4) << xB << " " << setw(4) << yB << " " << setw(8) << zB << endl;
   out   << setw(11) << i << setw(4) << xA << " " << setw(4) << yA << " " << setw(8) << zA << setw(4) << xB << " " << setw(4) << yB << " " << setw(8) << zB << endl;
   
  }
 

 cout<< "------------------------------------------------------"<< endl;
 cout<< "    Final x" << " Final y" << " Distance" << endl;
 cout<< setw(11) << xA << " " << setw(7) << yA << " " << setw(8) << zA << xB << " " << setw(7) << yB << " " << setw(8) << zB << endl;
 cout<< uA << " " << dA << " " << lA << " " << rA << endl;
 cout<< "------------------------------------------------------"<< endl;
 

out.close();
}

double dist(int a, int b){

double c=sqrt(a*a + b*b);

return c;
}

Hi,

You could start by not naming your variables as per it's number. Instead use a container like std::vector and use functions so you don't duplicate your code.

cheers & hope all is well :+)
Another suggestion is to encapsulate the movement function in a class, then you can make objects of your class and just tell each object to move.

As per above, you could keep everything in a container, and use something like std::for_each to get them all moving, one after the other.

For all the objects to move "at the same time", you'll probably need to create as many threads as you have objects.
thanks for the help, so i have re written part of it as a function like theideasman suggested, however when i get nonsense values for the x and y position, can anyone advise where i went wrong?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <ctime>
#include <cstdlib>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<fstream>

using namespace std;

int stepX( int randx, int randy, int l, int r);
int stepY( int randx, int randy, int l, int r);

int main() {
int  randxA=0, randyA=0, randxB=0, randyB=0; // random value of x and y
                                          // the first object is of type
                                         // A and second object is of type B
int xA=0, xB=0; // x and y postition
int yA=0, yB=0;
int n,N,uA=0,dA=0,lA=0,rA=0,uB=0,dB=0,lB=0,rB=0; 
int z;
int xstep;
int ystep;


srand(time(0));

for (int i=1 ; i<=100 ; i++){

int ran= rand() %2;

if (ran==1){
xstep = stepX( randxA, randyA, lA, rA);
ystep=0;
}

else if (ran==1){
xstep=0;
ystep=stepY( randxA, randyA, dA, uA);
}

xA=xA + xstep;
yA=yA + xstep;
cout << setw(11) << i << " " << randxA << " "  << setw(4) << xA << " " << yA << endl;
}
}
int stepX( int randx, int randy, int l, int r){

  
  
        randx = rand() % 2;
        randy = 0;
	   
      if ( randx == 0 ){
   
          randx=randx-1; // moves left
	      l=l+1;
		  
      }else if ( randx==1){
	  
            r=r+1; // moves right
      }
}
int stepY( int randx, int randy, int d, int u){

  randx=0;
        randy = rand() % 2;
        
	   
      if ( randy == 0 ){
   
          randy=randy-1; // moves left
	      d=d+1;
		  
      }else if ( randy==1){
	  
            u=u+1; // moves right
      }
}

Hi,
I've tried an Object-oriented approach, my indentation and style is different from yours, but that's for my own sanity and familiarity, not because I consider one scheme better than another. However, using my scheme I quickly spotted that the braces in your deeply nested if-else hierarchy are mismatched. Maybe that's why you're getting nonsense values.

1. I defined a class Mover, which has responsibility for moving itself randomly.
2. I created a container (vector) of Movers
3. I ask all the Movers to move the required number of steps, displaying the results as we go along.
4. As you'll see I made certain assumptions about vague requirements, instead starting a back-and-forth you may not be interested in.
5. I don't claim this is perfect or even good, just see if it gives you any ideas for simplification.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// All in one .cpp file, no error checking, no input validation...

#include <ctime>
#include <cstdlib>
#include <cmath>
#include <string>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <vector>
#include <sstream>
#include <memory>

struct Position
{
	Position() : x(0), y(0) {} // all objects start at 0?
	int x;
	int y;
};

class Mover
{
public:
	Mover(const std::string &objName);
	virtual ~Mover() {};

	void Move();
	const Position &GetCurrentPosition() const;
	int GetStep() const;
	double Distance() const;
	void Display(std::ostream &os) const;
	static void DisplayHeader(std::ostream &os, int numObjects);

protected:
	const std::string name;
	Position currentPosition;
	int step;
	static bool seeded;

private:
	Mover(const Mover &);
	Mover &operator=(const Mover &);
};

bool Mover::seeded = false;

Mover::Mover(const std::string &objName) : name(objName), currentPosition(), step(0)
{
	// seed random number generator once
	if (!seeded)
	{
		srand(time(0));
		seeded = true;
	}
}

void Mover::Move()
{
	int direction = rand() % 2;
	if (0 == direction) // x axis
	{
		if (0 == rand() % 2) // move right
		{
			++currentPosition.x;
		}
		else // move left
		{
			--currentPosition.x;
		}
	}
	else // y axis
	{
		if (0 == rand() % 2) // move up
		{
			++currentPosition.y;
		}
		else // move down
		{
			--currentPosition.y;
		}
	}

	++step;
}

const Position &Mover::GetCurrentPosition() const
{
	return currentPosition;
}

int Mover::GetStep() const
{
	return step;
}

double Mover::Distance() const
{
	return sqrt
        (
		(currentPosition.x * currentPosition.x) +
		(currentPosition.y * currentPosition.y)
	);
}

void Mover::Display(std::ostream &os) const
{
	os << std::setw(8) << name << std::setw(4) << currentPosition.x << std::setw(4) << currentPosition.y << std::setw(12) << Distance();
}

void Mover::DisplayHeader(std::ostream &os, int numObjects)
{
	os << std::setw(8) << "Step";
	for (int i = 0; i < numObjects; ++i)
	{
		os << std::setw(8) << "name" << std::setw(4) << "x" << std::setw(4) << "y" << std::setw(12) << "  Distance";
	}

	os << std::endl;
}

int main()
{
	std::ofstream out("rwalk.txt");
	std::cout << "How many objects would like to walk? ";
	int num;
	std::cin >> num;

	std::cout<< "How many steps would they like to take? " ;
	int steps;
	std::cin >> steps;

	std::vector<std::shared_ptr<Mover>> movers;
	for (int i = 0; i < num; ++i)
	{
		std::stringstream oss;
		oss << "obj" << i;

		auto upMover = std::make_shared<Mover>(oss.str());
		movers.push_back(upMover);
	}

	Mover::DisplayHeader(out, num);
	Mover::DisplayHeader(std::cout, num);

	for (int i = 0; i < steps; ++i)
	{
		std::cout << std::setw(8)<< i + 1;
		out << std::setw(8) << i + 1;

		for (auto mv : movers)
		{
			mv->Move();
			mv->Display(std::cout);
			mv->Display(out);
		}

		std::cout << std::endl;
		out << std::endl;
	}

	out.close();
}
Thanks for the advice, i have since used theideasman suggestion and used vectors and now have the program running for a thousand objects with no nonsense values. Object orientation is something i am highly unfamiliar with (two hours in a seminar). I now have a fresh challenge that im unsure how to tackle and have created a thread entitled 'help creating function' if you fancy taking a peek.
Topic archived. No new replies allowed.