Probelm with Arrays, Pointers, or Loop/ Function Calls, Im not sure which

Warning: Noob post.

Messing around with a few concepts learned in this website's tutorial and I cant wrap my mind around why I cannot rename one element of an array to which I am pointing. The code structure is a do-while loop in main that sets two rand shorts, then calls two functions. The first fills a pointer pointing to a char array, the second prints it out how I want it to.
Here's where I think the problem is, the first function:
1
2
3
4
5
6
7
8
9
10
void FillMap () {
	
	for (n=0; n<(x * c); n++) {
			a[n] = '.';
		}
	for (n= (x-1); n!=x; n++) {
		a[n] = '@';
	}

}


But, the issue created here could be in my main ():
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int main () {
	
	

	do {
	
	srand (time (NULL));
	x = rand () % 10 + 4;
	c = rand () % 8 + 6;

	a = new char [x*c];

		FillMap ();
	
		PrintMap ();
	
	std::cout << std::endl;
	std::cin >> end;

	} while (end == false);

	return 0;
}


The specific issue I'm having is that I want PrintMap () to print out the array that's being pointed to, but with an '@' that can be moved around. Right now, I cant even get the '@' symbol to appear in the array, and I don't know why. Right now, I just want it to print out a '@' at the array's rand element.

For those of you who enjoyed NetHack, yes this C++ beginner is testing concepts on this a model of this game.

I would love advice on how to do this an easier way, but for the purpose of mastering basic concepts, I am much more interested in why my primitive solution isn't working, so responses to either end would be appreciated.
Not to sure how exactly you want your fill map to work but as you want to display to a map - you'll need to use a 2d array instead of your char[]. You would more need to use something like "char* map[ySize][xSize];"

And then fill it like
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
for(int x = 0; x < 24; ++x)
{
	for(int y = 0; y < 78; ++y)
	{
		map[x][y] = " ";
	}
}

map[playerClass.x][playerClass.y] = "@";

for(int x = 0; x < 24; ++x)
{
	for(int y = 0; y < 78; ++y)
	{
		std::cout << map[x][y];
	}
	std::cout << std::endl;
}


Hope that gives you some idea :) If not let me know and I'll make you a basic one you can build from
I did that at first, but not with classes (if I read line 9 correctly?), and an error that I couldn't fix popped up. Instead, I used a single dimensional array, because the tutorial suggests multi-dimensional arrays are for fanciful thinking, and are barely different than a single dimensional array the size of two integers multiplied. So I took my two random shorts and multiplied them. This prints a map successfully, exactly how I want it, with a random height and random width, filled inside with '.' and bordered by '|', '_', and '-', it just doesnt seem to be able to transfer the information for a change to one element- the '@'.

One thing I'm confused about in your example is why you have constant integers 24 and 78 in your for loops. Are they arbitrary, or do they mean something I can't see?

Regardless, here's the entirety of what I have going now, if it helps:
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
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

short x, n, f, c, t;
char * a;
bool end (false);
void FillMap () {
	
	for (n=0; n<(x * c); n++) {
			a[n] = '.';
		}
	for (n= (x-1); n!=x; n++) { /* this is the line whose info doesnt seem to transfer*/
		a[n] = '@';
	}

}
void PrintMap () {

	
	for (n=0; n<(x+2); n++) {
		std::cout << "_";
	}
	for (f=0; f<c; f++){
	std::cout << std::endl << "|";

	for (n=0; n<x ; n++) {
		std::cout << a[n]; 
	}
	std::cout << "|" ;
	}
	std::cout << std::endl;
	for (n=0; n< (x+2); n++) {
		std::cout  << "-";
	}
}
int main () {
	
	

	do {
	
	srand (time (NULL));
	x = rand () % 10 + 4;
	c = rand () % 8 + 6;

	a = new char [x*c];

		FillMap ();
	
		PrintMap ();
	
	std::cout << std::endl;
	std::cin >> end;

	} while (end == false);

	return 0;
}
	

If I'm not understanding your concept, then I would appreciate a brief example. Just don't forget that I'm a self taught noob of less than a week, with only minor experience in visual BASIC as a kid :)
how many @'s are you expecting to fill in with that line?

n = x - 1; n != x; n++ ?

You are making n one less than x, then adding 1 to it... your loops executes only 1 time.

~psault
The program does what it is programmed to do:
When I run it, for a value of x=5 and c=10
this is what it displays


_______
|....@|
|....@|
|....@|
|....@|
|....@|
|....@|
|....@|
|....@|
|....@|
|....@|
-------


I do agree with psault - a loop that is only ever going to loop once - isn't really much of a loop.
Last edited on
I think you have the basic approach wrong for what you want to do.
If I understand corrctly you want to draw a map with an @, then have the @ move?
EG
1
2
3
4
_______
|....@|
|.....|
|.....|


1
2
3
4
_______
|.....|
|....@|
|.....|


1
2
3
4
_______
|.....|
|...@.|
|.....|


I would create the map in the array (you might as well make it 2D, it makes the code more obvious), then add the @.
To Move the @ put a . in the array where it was, then put an @ at the new position.
This way you are only updating the minimum information required to do the move.
As an additonal point, you have the srand call inside the loop - it should be called just once before the loop starts.
The reason for this is that time(NULL) is at 1 second precision, so all calls to srand(time(NULL)) within the same second will initialise to the same point.
See
1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{
   int a,b;
   //srand(time(NULL));   //Run once like this then uncomment this line
   for (i=0; i < 1000; i++)
   {
      srand(time(NULL));   // Run once like this, then comment this line
      a = rand () % 10 + 4;
      b = rand () % 8 + 6;
      count << a << "\t" << b << endl;
   }
   return 0;
}

to demonstate the difference.
Does it make any difference if you make your = '@'; turn into ="@";?
@ psault:
I tried an IF statement, which had no effect, so I ran a one time loop instead, which had the exact effect that guestgaulkan printed up for us.

@ Faldrax:
That is exactly the goal.
Im going to try and work my way through your idea and see if it changes anything, but I feel like its something I've already tried. Who knows, a second time around might fix things. I think what you're saying is have the pointer a point to the value '@' and then move it around in the array based on char input? Now, will i need extra code to erase the elements of the array that a pointed to before the last input? (as you can tell, im still wrapping y head around arrays and pointers before i try moving onto classes, the next lesson in the tutorial)
The srand and rand shorts were inside the loop for previous tests on printing several different sizes of maps. I just forgot to change it back.
Are you planning on trying to get the '@' moving around a little bit A.I like?
If you use a 2D array then all you need is to hold two pairs of info
1
2
int Old_x, Old_y;
int New_x, New_y;


the to move you just do
1
2
3
4
5
6
Old_x = New_x;
Old_y = New_y;
FindNewPosition(New_x,New_y);   //Function to calculate new values
Map[Old_x][Old_y] = '.';        //Set the old postion to a dot
Map[New_x][New_y] = '@';        //Set the new position to a @
DrawMap(Map);                   //Draw the new map 
Topic archived. No new replies allowed.