Logic question...

N

Nathan Mates

I can send you my current code if you are intersted. It is a challenge
to work with the arrays of units. They are not on my map they hold
their own values and then they draw themselvs. The challenge is that I
have to find units in the same space then to see if the other side has
units in that space. There is a posibility that several spaces have
both side in it and therefor elegible for combat.

As just about everyone has said multiple times, the code to store
who's where should be separated from your combat code. You said you
had problems when it was separate. Now you're having problems when
it's integrated. Once again, I recommend that it be separate, and
debugged. It's *much* easier to debug code when it's only trying to
do one thing (store who's where, in a map manager) versus multiple
things (combat & store who's where).

Nathan Mates
 
L

LR

I can send you my current code if you are intersted.

I'm sorry, but I don't have the time to read an entire program and see
what your problems are.

I suggest that you write the smallest possible program or even a snippet
that shows the problem and post it.
> It is a challenge
to work with the arrays of units.

What in particular is the challenge? Try to be as specific as you can.
>They are not on my map they hold
their own values and then they draw themselvs.

Relevance to above?

The challenge is that I
have to find units in the same space then to see if the other side has
units in that space.

Try parsing that, and rewriting it as code. Maybe that will solve your
problem. Maybe not the most efficient way, but right now I think you'd
be better served if you just got something to work.

> There is a posibility that several spaces have
both side in it and therefor elegible for combat.

Try parsing that too.

LR
 
J

JoeC

Nathan said:
As just about everyone has said multiple times, the code to store
who's where should be separated from your combat code. You said you
had problems when it was separate. Now you're having problems when
it's integrated. Once again, I recommend that it be separate, and
debugged. It's *much* easier to debug code when it's only trying to
do one thing (store who's where, in a map manager) versus multiple
things (combat & store who's where).

Nathan Mates

I have not gotten to work on my code yet. I am still thinking how I am
going to make the changes. I do find the discussion intersting and I
do learn things. Yes, I would be good to seperate the two activites.
I could make the part that sorts the pieces seperate functions. I
would like to know if there is a std::lib function that will copy units
that are in the same space. They have to be refrences because I want
the affects of the combat to be on the same units that engaged in
combat.

Right now my design is pretty poor and I am trying to come up with a
better way to do what I am doing. It will probibly take a while to
figure out how to re-design the program and solve my problem better. I
do have some ideas that involve a single class that takes the units
then does combat instead of a single function.
 
N

Nathan Mates

I have not gotten to work on my code yet. I am still thinking how I am
going to make the changes. I do find the discussion intersting and I
do learn things. Yes, I would be good to seperate the two activites.
I could make the part that sorts the pieces seperate functions. I
would like to know if there is a std::lib function that will copy units
that are in the same space. They have to be refrences because I want
the affects of the combat to be on the same units that engaged in
combat.

Just copy/return pointers instead-- have your map manager return a
std::list or (better yet) a std::vector of pointers to units. That's
pretty darn close to what a reference is anyhow, and it's more
flexible for what you're trying to do.

Nathan
 
J

JoeC

Nathan said:
Just copy/return pointers instead-- have your map manager return a
std::list or (better yet) a std::vector of pointers to units. That's
pretty darn close to what a reference is anyhow, and it's more
flexible for what you're trying to do.
" -R.A. Heinlein

My main point for this whole post is to get an opinion on what I wrote.
Yes it is not very good. But I am looking for a concept on how go
about making it better. Great seperate the sorting and combat into two
functions. That would be good but they have to be sorted before combat
can take place. I would like to get some advice on how to sort them.
Should I have a combat object that sorts and then does the combat.
Should I create a sort object then have that object loaded by the
combat routine. I had my first attempt that didn't work and now I am
trying to come up with a basic concept on how to do what I want to do.
I know it is best to break it all down to the simplest steps but I have
a proscess here. Sort, combat, results.

My problem is that I ham having trouble seperating out the steps. It
it not simple. 1. find units in the same space, 2. get the combat
factors, 3, resolve combat, 4. apply results to affected units.

Step one, I can either take the unit an put into a seperate function
or object or I can have some external thing that knows that unit[1] and
unit[3] have the same coords.

Step two. the function or objects simple takes the combat factors
because refrences to the units are in the function or object. From
another way the external thing has to know to get the information from
unit[1] and unit[3] and unit[2] from the other side.

Step three. I have created a table object that holds the tabe and
returns the result. Should that be part of an object, should it be
persistant or should it be reloaded each time combat takes place.

Step four. Resolving combat. How do the units konw that they are to
die or be dispersed. Basically they turn black and have no attack or
movement factors for the next turn. That shouldn't be too hard, I
still have to make changes so that the units can be affected as I had
planned.

Some of these problems are harder than others. I still have other
things to improve in the program and this is not my only problem it is
the only one that is completely not working.

Because my cable modem has a bad connection, I have not been able to
send out this message and I have been working on my program trying to
figure this out and it is realy racking my brain. I have been
comparing different ways to solve this problem.
 
N

Nathan Mates

My problem is that I ham having trouble seperating out the steps. It
it not simple. 1. find units in the same space, 2. get the combat
factors, 3, resolve combat, 4. apply results to affected units.

Your trying to explain things in more words is definitely helping.
Keep explaining things with more words-- like an outline-- until you
can see how to turn a sentence into a bit of code. That's how you go
about breaking down a big idea into small chunks that can be
programmed. And, for your steps, the best thing to do is the simplest
thing. If you've got complicated implementations, you're more likely
to introduce bugs.

Step one, I can either take the unit an put into a seperate function
or object or I can have some external thing that knows that unit[1] and
unit[3] have the same coords.

As I've said *MANY* times before, use a map manager. It does
something like this:

class Entity; // base class for all objects managed by MapManager; classes derive from this
typedef std::list<Entity*> EntityList;

class MapManager
{
public:
void Clear(void); // clears the map
void AddEntity(Entity* pObj); // pObj is queried as to where it is
void RemoveEntity(Entity* pObj); // object moves are just a remove/add

void GetObjectsAt(int x, int y, EntityList& objs);

private:
// Implementation here. Just store pointers!
// For example, you could do a 2D array of EntityLists.
}

WRITE THIS CODE. Do not do step 2 until you complete this. DO NOT
TRY AND SOLVE EVERYTHING NOW. Get *something* working. You're diluting
your focus and confusing the issues by trying to think about
everything at once.

Step two. the function or objects simple takes the combat factors
because refrences to the units are in the function or object. From
another way the external thing has to know to get the information from
unit[1] and unit[3] and unit[2] from the other side.

I can't understand the above. I don't think you understand this
step fully, either. If you have an EntityList, like above, you can
simply ask each object various bits of info -- call a function on
them. Problem solved.

Step three. I have created a table object that holds the tabe and
returns the result. Should that be part of an object, should it be
persistant or should it be reloaded each time combat takes place.

Focusing on return types means you're completely missing the big
picture. This is a game design question that you've gotten mixed up
with programming. If the results of combat are applied right away (as
in most games), then call a function on that object right away and let
it update its state. Or if the results are applied at the end of a
turn, just store the pending changes in each object (Entity).

Step four. Resolving combat. How do the units konw that they are to
die or be dispersed. Basically they turn black and have no attack or
movement factors for the next turn. That shouldn't be too hard, I
still have to make changes so that the units can be affected as I had
planned.

How does something know? Simple. You tell it. If you have a pointer
to an Entity, then you call a function on it,
e.g. pObj->DamageAlloc(50). Or something else. If you go with code
like the above, where you've got a list of pointers to objects, it's
trivial to start passing messages (i.e. calling functions) to those
objects. For each object, if its health goes under zero when damage
is allocated, set a flag on it that it's dead. Then any calls to use
that entity that turn can just check that flag.

Nathan Mates
 
L

LR

JoeC wrote:


Great seperate the sorting and combat into two
functions. That would be good but they have to be sorted before combat
can take place. I would like to get some advice on how to sort them.

Please look into std::sort.


I know it is best to break it all down to the simplest steps but I have
a proscess here. Sort, combat, results.

My problem is that I ham having trouble seperating out the steps. It
it not simple. 1. find units in the same space,

That's not quite the same thing as sort.

Perhaps you should look into std::map, or maybe std::multimap.

Just as a thought experiment, not the way to write your code, think
about something like std::map<Location, std::set<UnitIndicies> >.

But sort might not be so bad as a first run through.

Maybe an easy way would be to make a
std::vector< std::pair<UnitLocation, UnitIndex> >
and sort it. That will bunch up all the Units that are in the same
location next to each other in the vector.

Do they fight when they're at the same location, or at adjacent locations?

2. get the combat
factors, 3, resolve combat, 4. apply results to affected units.

Once you figure out how to decide where your "Units" are, these may seem
simpler. Try to complete item 1 first.

LR
 
M

Miss Elaine Eos

My game is very simple, as simple as I can make it. I could get rid of
terrain but all I want to do is move pieces on a board and if they are
in the same space have them fight. I have done several map games and
each one has its problems. This worked great until I wanted to have
the units fight.

Ok, let's look at this much of the problem.

You have a "units" structure, right? And each unit has a "I'm at
location X/Y" variable, right? So maybe (I'll use java, because it's
easy to read and I've been playing in it, lately) you have something
like:

public class Unit
{
int type; // 1=soldier, 2=tank, etc.
int xPos; // which column on board
int zPos; // which row on board.
// (Call it Z in case we ever go 3d :)
int defenseStat;
int attackStat
...etc.
}

Now, when you want to see if anyone else is in this unit's square, you
do:

// assume the presence of "thisUnit", a unit object
// assume "thisUnitIndex" is thisUnit's index in
// the array of all units, "unitArray"
for (int ii = 0 ; ii < unitArray.length ; ++ii)
{
if (ii == thisUnitIndex) continue; // don't compare to me!
otherUnit = unitArray [ii];
if ((otherUnit.xPos == thisUnit.xPos)
&& (otherUNit.yPos == thisUnit.yPos) )
{
// we share a square!
resolveCombat (thisUnit, otherUnit);
}
}

This is pretty basic stuff, though -- if you're having trouble at this
level, then you probably want to put the game on the back-burner for a
while and learn some programming fundamentals.

....Or maybe we're just all not understanding what it is you're asking.
 
J

JoeC

Nathan said:
My problem is that I ham having trouble seperating out the steps. It
it not simple. 1. find units in the same space, 2. get the combat
factors, 3, resolve combat, 4. apply results to affected units.

Your trying to explain things in more words is definitely helping.
Keep explaining things with more words-- like an outline-- until you
can see how to turn a sentence into a bit of code. That's how you go
about breaking down a big idea into small chunks that can be
programmed. And, for your steps, the best thing to do is the simplest
thing. If you've got complicated implementations, you're more likely
to introduce bugs.

Step one, I can either take the unit an put into a seperate function
or object or I can have some external thing that knows that unit[1] and
unit[3] have the same coords.

As I've said *MANY* times before, use a map manager. It does
something like this:

class Entity; // base class for all objects managed by MapManager; classes derive from this
typedef std::list<Entity*> EntityList;

class MapManager
{
public:
void Clear(void); // clears the map
void AddEntity(Entity* pObj); // pObj is queried as to where it is
void RemoveEntity(Entity* pObj); // object moves are just a remove/add

void GetObjectsAt(int x, int y, EntityList& objs);

private:
// Implementation here. Just store pointers!
// For example, you could do a 2D array of EntityLists.


I have to do some studying to be able to understand how to make a map
manager work. I feel bad but it confuses me. I will have to do some
studying and try to learn how this works. I know how to use a map and
other standatd containers and I once wrote a simple linked list but I
never realy worked with it much farther. I worte a program simmiliar
to this but it was pretty buggy:

class board{

player * play;
static const int size = 30;
map<char, coord> keys;
space spaces[size][size];
coord n;
coord s;
coord e;
coord w;

ifstream& cfill(ifstream&, char&); /*Reads map from file */
void fill();
coord find();
void seeing(int, int);

public:
board();
void setPlayer(player*, int, int);
graphic& display(int, int);
int sze(){return size;}
void move(char);
};

class space{
char gchar;
graphic *gr;
graphic *grDefault;
graphic *cgr;
player * play;
bool seen;

public:
space();
~space();
void graphicIn(char g);
graphic& graphicOut();
void playIn(player*);
bool isPlay();
void see(){seen = true;}
bool been(){return seen;}
void playOut();
bool canMove();
bool winspace();
};

Again I have not found good resource that clearly explain these
programming techinques. If I have seen them, I have not been able to
apply the lessons to my programs. Although I write these games, I also
spend time writing small demo programs to learn how to do things.
These projects how me where my knolwege is lacking and what to study
and learn. After I get this game to work, I am going to do some
studying and see what I can learn. I generally don't use pointers
because I am not realy skilled with manipulating them.

For now before reading this post:

class cfight{

struct cHolder{
int x;
int y;
vector<int>atu; // stores attacking units
vector<int>dtu; //stores defending units
};

vector<cHolder>holder; //holds units in same space and the coords

public:
cfight();
void readAt(vector<unit>&);
void readDt(vector<unit>&);
};

#include<vector>

#include "cfight.h"

using namespace std;

cfight::cfight(){

}

void cfight::readAt(vector<unit>& at){
/*Takes the vector of the attacking units and puts them in the hold
vector. If there are units in the same space their indexes are
grouped
together. If not a new element is added to the hold vector */

int num = 0;
bool done = false;

if(holder.size() == 0){
cHolder h;
h.x = at[0].getXloc();
h.y = at[0].getYloc();
h.atu.push_back(num);
holder.push_back(h);
}
for(int un = 1; un != at.size (); un++){
do{
if(at[un].getXloc() == holder[num].x &&
at[un].getYloc() == holder[num].y){
holder[num].atu.push_back(num);
done = true;
} else {num++;}
if(num > holder.size()){done = true;}

}while(!done);

}


}

void cfight::readDt(vector<unit>& dt){
/* Takes the vector of defending units then compares them with the
attacking
units if they are in the same space then they are grouped in same
hold
vector element if not they are ignored */

for(int un = 0; un != dt.size(); un++){
for(int num = 0; num != holder.size(); num++){
if(dt[un].getXloc() == holder[num].x &&
dt[un].getYloc() == holder[num].y){
holder[num].dtu.push_back(num);
}
}
}
}
 
J

JoeC

Nathan said:
My problem is that I ham having trouble seperating out the steps. It
it not simple. 1. find units in the same space, 2. get the combat
factors, 3, resolve combat, 4. apply results to affected units.

Your trying to explain things in more words is definitely helping.
Keep explaining things with more words-- like an outline-- until you
can see how to turn a sentence into a bit of code. That's how you go
about breaking down a big idea into small chunks that can be
programmed. And, for your steps, the best thing to do is the simplest
thing. If you've got complicated implementations, you're more likely
to introduce bugs.

Step one, I can either take the unit an put into a seperate function
or object or I can have some external thing that knows that unit[1] and
unit[3] have the same coords.

As I've said *MANY* times before, use a map manager. It does
something like this:

class Entity; // base class for all objects managed by MapManager; classes derive from this
typedef std::list<Entity*> EntityList;

class MapManager
{
public:
void Clear(void); // clears the map
void AddEntity(Entity* pObj); // pObj is queried as to where it is
void RemoveEntity(Entity* pObj); // object moves are just a remove/add

void GetObjectsAt(int x, int y, EntityList& objs);

private:
// Implementation here. Just store pointers!
// For example, you could do a 2D array of EntityLists.


I have to do some studying to be able to understand how to make a map
manager work. I feel bad but it confuses me. I will have to do some
studying and try to learn how this works. I know how to use a map and
other standatd containers and I once wrote a simple linked list but I
never realy worked with it much farther. I worte a program simmiliar
to this but it was pretty buggy:

class board{

player * play;
static const int size = 30;
map<char, coord> keys;
space spaces[size][size];
coord n;
coord s;
coord e;
coord w;

ifstream& cfill(ifstream&, char&); /*Reads map from file */
void fill();
coord find();
void seeing(int, int);

public:
board();
void setPlayer(player*, int, int);
graphic& display(int, int);
int sze(){return size;}
void move(char);
};

class space{
char gchar;
graphic *gr;
graphic *grDefault;
graphic *cgr;
player * play;
bool seen;

public:
space();
~space();
void graphicIn(char g);
graphic& graphicOut();
void playIn(player*);
bool isPlay();
void see(){seen = true;}
bool been(){return seen;}
void playOut();
bool canMove();
bool winspace();
};

Again I have not found good resource that clearly explain these
programming techinques. If I have seen them, I have not been able to
apply the lessons to my programs. Although I write these games, I also
spend time writing small demo programs to learn how to do things.
These projects how me where my knolwege is lacking and what to study
and learn. After I get this game to work, I am going to do some
studying and see what I can learn. I generally don't use pointers
because I am not realy skilled with manipulating them.

For now before reading this post:

class cfight{

struct cHolder{
int x;
int y;
vector<int>atu; // stores attacking units
vector<int>dtu; //stores defending units
};

vector<cHolder>holder; //holds units in same space and the coords

public:
cfight();
void readAt(vector<unit>&);
void readDt(vector<unit>&);
};

#include<vector>

#include "cfight.h"

using namespace std;

cfight::cfight(){

}

void cfight::readAt(vector<unit>& at){
/*Takes the vector of the attacking units and puts them in the hold
vector. If there are units in the same space their indexes are
grouped
together. If not a new element is added to the hold vector */

int num = 0;
bool done = false;

if(holder.size() == 0){
cHolder h;
h.x = at[0].getXloc();
h.y = at[0].getYloc();
h.atu.push_back(num);
holder.push_back(h);
}
for(int un = 1; un != at.size (); un++){
do{
if(at[un].getXloc() == holder[num].x &&
at[un].getYloc() == holder[num].y){
holder[num].atu.push_back(num);
done = true;
} else {num++;}
if(num > holder.size()){done = true;}

}while(!done);

}


}

void cfight::readDt(vector<unit>& dt){
/* Takes the vector of defending units then compares them with the
attacking
units if they are in the same space then they are grouped in same
hold
vector element if not they are ignored */

for(int un = 0; un != dt.size(); un++){
for(int num = 0; num != holder.size(); num++){
if(dt[un].getXloc() == holder[num].x &&
dt[un].getYloc() == holder[num].y){
holder[num].dtu.push_back(num);
}
}
}
}
 
N

Nathan Mates

I have to do some studying to be able to understand how to make a map
manager work. I feel bad but it confuses me. I will have to do some
studying and try to learn how this works. I know how to use a map and
other standatd containers and I once wrote a simple linked list but I
never realy worked with it much farther. I worte a program simmiliar
to this but it was pretty buggy:

Why write a linked list? std::list<Object*> is a linked list, and
is fully debugged already. Use what you've got for free.

Nathan Mates
 
J

JoeC

Nathan said:
Why write a linked list? std::list<Object*> is a linked list, and
is fully debugged already. Use what you've got for free.

Nathan Mates
I took some of your advice and did my best to create a map manager and
so far it is working great. It is much easier and less buggy than
anything I could come up with. It was a challenge trying to
conceptualize the object. I didn't use pointers or anything and
creating the map was a challenge but so far the object does everything
I want it to do.

class mapmgt{
int xlen; //map size (max 100)
int ylen;

struct hold{
vector<unit>at; //holds the attackers
vector<unit>dt; //holds the defenders
};
table t; //combat results table
hold h[100][100]; //allows for a map max 100x100.

public:
mapmgt();
mapmgt(int, int); //creates a map size of x and y

void atIn(unit&); //reads in units
void dtIn(unit&);
void fight();
void clear(); //clears the map at the end of the turn

};

mapmgt::mapmgt(int x, int y){
xlen = x;
ylen = y;
if(x > 199 || y > 99){
MessageBox(NULL, "The map is too big, edit the program!", "Error!",
MB_OK);
}
}

void mapmgt::atIn(unit& u){
int x = u.getXloc();
int y = u.getYloc();
h[x][y].at.push_back(u);

}

void mapmgt::fight(){
for(int lp1 = 0; lp1 != ylen; lp1++){
for(int lp2 = 0; lp2 != xlen; lp2++){
if(h[lp2][lp1].at.size() > 0 && h[lp2][lp1].dt.size() > 0){
MessageBox(NULL, "There is fighting!", "simulation!", MB_OK);
}
}
}

}
 
N

Nathan Mates

I took some of your advice and did my best to create a map manager
and so far it is working great. It is much easier and less buggy
than anything I could come up with. It was a challenge trying to
conceptualize the object. I didn't use pointers or anything and
creating the map was a challenge but so far the object does
everything I want it to do.

Why didn't you want to use pointers? You're using C++, and
therefore pointers are to be used when it makes sense. And, it does
here. Trying to use references here means that you're creating lots of
*copies* of the units, so what you get back may not be what you
expect. Pointers won't do accidental copies. Your fear of pointers is
a pretty good possibility for why the effects of combat aren't
applied, as per your posting today.

For example:
struct hold{
vector<unit>at; //holds the attackers
vector<unit>dt; //holds the defenders
};

void mapmgt::atIn(unit& u){
int x = u.getXloc();
int y = u.getYloc();
h[x][y].at.push_back(u);

Once again, use pointers in here. Otherwise, you'll copy the unit.

In C/C++, passing pointers is a good way to say "you can access
this, but you don't own it." Your map manager probably shouldn't own
all the units on the board, and it can't the way you wrote it above,
duplicating units. You have to either have the map manager own the
units, or use pointers. Pointers is the MUCH simpler solution. Don't
be afraid to use pointers. They're a skill you'll need to master for
C/C++.

Nathan Mates
 
J

JoeC

Nathan said:
I took some of your advice and did my best to create a map manager
and so far it is working great. It is much easier and less buggy
than anything I could come up with. It was a challenge trying to
conceptualize the object. I didn't use pointers or anything and
creating the map was a challenge but so far the object does
everything I want it to do.

Why didn't you want to use pointers? You're using C++, and
therefore pointers are to be used when it makes sense. And, it does
here. Trying to use references here means that you're creating lots of
*copies* of the units, so what you get back may not be what you
expect. Pointers won't do accidental copies. Your fear of pointers is
a pretty good possibility for why the effects of combat aren't
applied, as per your posting today.

For example:
struct hold{
vector<unit>at; //holds the attackers
vector<unit>dt; //holds the defenders
};

void mapmgt::atIn(unit& u){
int x = u.getXloc();
int y = u.getYloc();
h[x][y].at.push_back(u);

Once again, use pointers in here. Otherwise, you'll copy the unit.

In C/C++, passing pointers is a good way to say "you can access
this, but you don't own it." Your map manager probably shouldn't own
all the units on the board, and it can't the way you wrote it above,
duplicating units. You have to either have the map manager own the
units, or use pointers. Pointers is the MUCH simpler solution. Don't
be afraid to use pointers. They're a skill you'll need to master for
C/C++.
I know that this is basic c++ stuff but if I do,

void mapmgt::atIn(unit& u){
int x = u.getXloc();
int y = u.getYloc();
h[y][x].at.push_back(u);
}

for(int lp = 0; lp < rteam.size(); lp++){
m.atIn(rteam[lp]);}
How do I read that as a pointer?
void mapmgt::atIn(unit * u)? Doent the Unit have to be apointer before
I can send it:
for(int lp = 0; lp < rteam.size(); lp++){
unit * prteam[lp];
m.atIn(prteam);}

I just don't work with pointers very much because when I do they tend
to lead to problems. I always thought the refrence thing was a good a
a pointer and much safer.
 
G

Gerry Quinn

Why didn't you want to use pointers? You're using C++, and
therefore pointers are to be used when it makes sense. And, it does
here. Trying to use references here means that you're creating lots of
*copies* of the units, so what you get back may not be what you
expect. Pointers won't do accidental copies. Your fear of pointers is
a pretty good possibility for why the effects of combat aren't
applied, as per your posting today.

His problem is not really to do with the use of pointers or references;
it is to do with making copies. He could make a copy in just the same
way if he used pointers where he currently used references. The
problem is that when given the reference, he is storing what is
referred to.

Now there is unfortunately a catch - you are basically stuck with
pointers in this case because you can't make a vector of references in
C++, so a vector of pointers is the correct solution. It is an
annoyance with C++ that references have certain limitations that mean
you sometimes have to revert to pointers.

All in all, though, it makes good sense to use reference syntax where
practical, and leave pointers for when they are needed (or, in rare
cases, where they make things clearer).

- Gerry Quinn

For example:
struct hold{
vector<unit>at; //holds the attackers
vector<unit>dt; //holds the defenders
};

void mapmgt::atIn(unit& u){
int x = u.getXloc();
int y = u.getYloc();
h[x][y].at.push_back(u);

Once again, use pointers in here. Otherwise, you'll copy the unit.

In C/C++, passing pointers is a good way to say "you can access
this, but you don't own it." Your map manager probably shouldn't own
all the units on the board, and it can't the way you wrote it above,
duplicating units. You have to either have the map manager own the
units, or use pointers. Pointers is the MUCH simpler solution. Don't
be afraid to use pointers. They're a skill you'll need to master for
C/C++.

Nathan Mates
--
<*> Nathan Mates - personal webpage http://www.visi.com/~nathan/
# Programmer at Pandemic Studios -- http://www.pandemicstudios.com/
# NOT speaking for Pandemic Studios. "Care not what the neighbors
# think. What are the facts, and to how many decimal places?" -R.A. Heinlein
 
J

JoeC

Gerry said:
His problem is not really to do with the use of pointers or references;
it is to do with making copies. He could make a copy in just the same
way if he used pointers where he currently used references. The
problem is that when given the reference, he is storing what is
referred to.

Now there is unfortunately a catch - you are basically stuck with
pointers in this case because you can't make a vector of references in
C++, so a vector of pointers is the correct solution. It is an
annoyance with C++ that references have certain limitations that mean
you sometimes have to revert to pointers.

All in all, though, it makes good sense to use reference syntax where
practical, and leave pointers for when they are needed (or, in rare
cases, where they make things clearer).

- Gerry Quinn
I went an used pointers. I thought refrences would work because I was
sending refrences to the function but that didn't work. Normally I
send refrences to objects to functions and the functions modify the
object but I have not stored those refrences in vectors or other
containers.

for(int lp = 0; lp < rteam.size(); lp++){
unit * pu = &rteam[lp];
m.atIn(pu);} //reads in the attracking units to map panager
 
N

Nathan Mates

I just don't work with pointers very much because when I do they
tend to lead to problems. I always thought the refrence thing was a
good a a pointer and much safer.

I'm going to put this bluntly: if you want to program C/C++
professionally, then you better be proficient in using pointers. Even
if you've botched things in the past or swallowed the line that
references are "as good," you're going to have to learn how to use
pointers. Memory management is a required skill for C/C++ programmers,
and the only way to effectively do that in the core language is with
pointers.

A reference is *not* equal to a pointer. There's a whole LOT of
ways they're different. The most obvious one is that references must
be initialized when defined, so that they point to valid data. A
pointer has no such restriction. As has already been pointed out, you
can't make a STL vector of references. Further, to allocate any
memory, you MUST account for the possibility that a memory allocation
failed. And that violates the #1 rule of references, that they point
to something valid.

Getting back to your code, the above raises a serious issue you're
going to need to sit down and think about for a while. Specifically,
memory management. Your map can have a fixed maximum size, that's not
serious and can be designed around. However, what goes *on* your map
isn't fixed. Assuming you have 'class Unit { ... };' for the things
placed on the map, the Units don't magically just appear in
memory. You *MUST* think through these questions:

1) When is a Unit created? By what function?
2) Who "owns" that memory?
3) When/how is that memory released?

So far, I guess you're doing something like this:

void DoSomething(void)
{
Unit unit1
DoSomethingElse(unit1);
}

In this function, 'unit1' is created, for free, on the stack. [If
you don't know what that is, please sit down with C++ reference
manuals and
tutorials. http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html is
one good free reference, available for download at
http://www.planetpdf.com/developer/article.asp?ContentID=6634 among
other places] However, at the end of DoSomething() [i.e., when it goes
out of scope], unit1 is gone. Destroyed.

In order to properly create arbitrary numbers of units on your map,
you need to create them with the new operator. That doesn't allocate
on the stack, and instead gives you a pointer you can use. That
pointer should be passed to the MapManager instead, as I've
recommended from the beginning.
I know that this is basic c++ stuff but if I do,
void mapmgt::atIn(unit& u){
int x = u.getXloc();
int y = u.getYloc();
h[y][x].at.push_back(u);
}

Complete style nitpick: if you want anyone else to read your code,
then do NOT abbreviate this much. It makes your code a LOT less
readable. Write your header as follows:

void mapmgt::atIn(unit* u)

or, better yet

void MapManager::AddAttacker(Unit* u)


for(int lp = 0; lp < rteam.size(); lp++){
m.atIn(rteam[lp]);}
How do I read that as a pointer?

You've omitted all the definitions of these variables, and due to
overabbreviation, it's nearly impossible to figure out what these
variables are, and what you're trying to achieve here. Your map
manager should probably be a singleton, and a pointer retrieved. For
example

class MapManager
{
// ...
public:
static MapManager* Get(void);
//...
private:
static MapManager* s_Instance;
}

MapManager* MapManager::Get(void)
{
if(s_Instance = NULL)
s_Instance = new MapManager;

_ASSERTE(s_Instance); // Or some other form of error management
return s_Instance;
}

Then, in other code:

void SomeFunc(...)
{
MapManager* pMapManager = MapManager::Get();

Unit pAttacker1 = new Unit;
pAttacker1.SetPosition(5,5);
pMapManager->AddAttacker(pAttacker1);
}

Nathan Mates
 
J

JoeC

Nathan said:
I just don't work with pointers very much because when I do they
tend to lead to problems. I always thought the refrence thing was a
good a a pointer and much safer.

I'm going to put this bluntly: if you want to program C/C++
professionally, then you better be proficient in using pointers. Even
if you've botched things in the past or swallowed the line that
references are "as good," you're going to have to learn how to use
pointers. Memory management is a required skill for C/C++ programmers,
and the only way to effectively do that in the core language is with
pointers.

A reference is *not* equal to a pointer. There's a whole LOT of
ways they're different. The most obvious one is that references must
be initialized when defined, so that they point to valid data. A
pointer has no such restriction. As has already been pointed out, you
can't make a STL vector of references. Further, to allocate any
memory, you MUST account for the possibility that a memory allocation
failed. And that violates the #1 rule of references, that they point
to something valid.

Getting back to your code, the above raises a serious issue you're
going to need to sit down and think about for a while. Specifically,
memory management. Your map can have a fixed maximum size, that's not
serious and can be designed around. However, what goes *on* your map
isn't fixed. Assuming you have 'class Unit { ... };' for the things
placed on the map, the Units don't magically just appear in
memory. You *MUST* think through these questions:

1) When is a Unit created? By what function?
2) Who "owns" that memory?
3) When/how is that memory released?

So far, I guess you're doing something like this:

void DoSomething(void)
{
Unit unit1
DoSomethingElse(unit1);
}

In this function, 'unit1' is created, for free, on the stack. [If
you don't know what that is, please sit down with C++ reference
manuals and
tutorials. http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html is
one good free reference, available for download at
http://www.planetpdf.com/developer/article.asp?ContentID=6634 among
other places] However, at the end of DoSomething() [i.e., when it goes
out of scope], unit1 is gone. Destroyed.

In order to properly create arbitrary numbers of units on your map,
you need to create them with the new operator. That doesn't allocate
on the stack, and instead gives you a pointer you can use. That
pointer should be passed to the MapManager instead, as I've
recommended from the beginning.
I know that this is basic c++ stuff but if I do,
void mapmgt::atIn(unit& u){
int x = u.getXloc();
int y = u.getYloc();
h[y][x].at.push_back(u);
}

Complete style nitpick: if you want anyone else to read your code,
then do NOT abbreviate this much. It makes your code a LOT less
readable. Write your header as follows:

void mapmgt::atIn(unit* u)

or, better yet

void MapManager::AddAttacker(Unit* u)


for(int lp = 0; lp < rteam.size(); lp++){
m.atIn(rteam[lp]);}
How do I read that as a pointer?

You've omitted all the definitions of these variables, and due to
overabbreviation, it's nearly impossible to figure out what these
variables are, and what you're trying to achieve here. Your map
manager should probably be a singleton, and a pointer retrieved. For
example

class MapManager
{
// ...
public:
static MapManager* Get(void);
//...
private:
static MapManager* s_Instance;
}

MapManager* MapManager::Get(void)
{
if(s_Instance = NULL)
s_Instance = new MapManager;

_ASSERTE(s_Instance); // Or some other form of error management
return s_Instance;
}

Then, in other code:

void SomeFunc(...)
{
MapManager* pMapManager = MapManager::Get();

Unit pAttacker1 = new Unit;
pAttacker1.SetPosition(5,5);
pMapManager->AddAttacker(pAttacker1);
}

Nathan Mates


The criticizm is good. I know I have a great deal of work to do and I
often create smaller programs to learn how to do things. It is still
fun to create programs that do things and I am proud of the projects
that I complete. The purpose of these projects to have fun but also to
learn where I need to improve my skills. I am trying to do better in
my descriptions and commenting, I realize those are important.

I have made changes in my program based on the advice I have recieve
and it runs much better. I do read books on programming and some are
better than others and many times it seems that I get bad advice or
improperly implement the concepts. To learn I need to write programs
and make my mistakes. I got the program to run but there is much room
for improvment. The key to good programming is that it can be easily
expanded and this program is not designed that well as ti could be to
where it can easily be expanded. Often times, the advice I get and
ideas that come from writing I have to totally rewrite the program to
implement those changes or it is much easier. I have done that several
times as my knowlege has grown.

I have been on the lookout for good books that teach me these more
advanced methods of programming. I have only been doing this for a few
years and I am completly self taught. The best refrence I have is
Accelerated C++. I realize that book has limits and is very dificult
to fully grasp. I constantly re-read that book to keep getting the
knowlege out.
 
J

JoeC

In this function, 'unit1' is created, for free, on the stack. [If
you don't know what that is, please sit down with C++ reference
manuals and
tutorials. http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html is
one good free reference, available for download at
http://www.planetpdf.com/developer/article.asp?ContentID=6634 among
other places] However, at the end of DoSomething() [i.e., when it goes
out of scope], unit1 is gone. Destroyed.

This book has been recommended to me when I get the chance I am
planning to buy it. I need good resources to explain memory managment
and how best to use it. My skills are limited. I have the C++
programming language but often times I don't find the book useful and
often confusing. Mostly, I see the examples are too limited or I have
missed the parts that are useful.
 
N

Nathan Mates

In this function, 'unit1' is created, for free, on the stack. [If
you don't know what that is, please sit down with C++ reference
manuals and
tutorials. http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html is
one good free reference, available for download at
http://www.planetpdf.com/developer/article.asp?ContentID=6634 among
other places] However, at the end of DoSomething() [i.e., when it goes
out of scope], unit1 is gone. Destroyed.
This book has been recommended to me when I get the chance I am
planning to buy it.

As noted above, it's available for free (and legally, not pirated)
at the links above. Purchasing it is a great way to show support for
the author, but you can legally enjoy it now.

Nathan Mates
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top