troubles with multiple structs in a class, please help

Discussion in 'C++' started by lapetitedingue, Feb 24, 2009.

  1. lapetitedingue

    lapetitedingue New Member

    Joined:
    Feb 24, 2009
    Messages:
    7
    Likes Received:
    0
    Trophy Points:
    0
    I am creating a program that involves a simple agent navigating a grid world to discover food. I am having trouble creating a unique class for the agent (which contains data members that represent its perception of the world. The agent class contains a structure called SENSE which will contain the 2d vector (I had found out how to create the grid using the vector and not a simple array so stuck with the vector for now) which represents the agent's 5x7 current view of the world. The SPOT structure represents each spot in the grid. I would like to store the 2d vector as a data member in the SENSE structure but right now it doesn't like me. Eventually I will add a map class (within the agent) which will update with information derrived as the agent navigates the world.
    The agent's only objective is to find a single piece of food stored in the world. The agent can only sense the direction of the food relative to its on orientation in the world- this is represented by the 'gradient' member which stores either 'f', 'b', 'l', or 'r' for directions: forward, back, left, or right. These are also the key characters for the agent's navigation commands. Other sensory data members updated each time a move is made are; char onGround (stores what is underneath the agent), bool blocked()(stores whether there is a wall blocking the spot or not), char agent(later on there will be multiple agents in the world which help the first find the food, this member will store the agent's id if there is an agent on the spot), bool onCheese ( true if the agent is on the same coordinate as the food), and inventory is a stack of items the agent has picked up(useful for more involved navigation with keys to doors and the like).
    The world itself is already implemented in java and the main.cpp connects to it's server via socket(all of which is implemented in a "connection.cpp" file) .
    Right now I am still having trouble integrating the agent class with the main program. Is there a glaring error that is making my updateSenses function not able to read the data members? -these are the main errors that my compiler is giving me. I have attached a snapshot of my x-code compile errors. Thanks for your help!
    Code:
    /*
     *  agent.h
     */
    #ifndef AGENT_H
    #define AGENT_H
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <stack>
    using namespace std;
    
    #define COLS	5
    #define ROWs	7
    
    struct SPOT
    {
    	char obj; // contains object on the SPOT
    	char agent; // agent id if there is an agent on the SPOT
    	bool blocked;
    	
    	//refer to neighboring SPOTs on map maybe will make a map class when I can figure  out how to make member functions read these
    	SPOT* north;
    	SPOT* south;
    	SPOT* east;
    	SPOT* west;
    };
    
    
    struct SENSE : public SPOT
    {
    	char gradient; 		
    	bool onCheese;
    	char inventory;
    	char onGround;
    	
    };
     
    class agent: public SENSE
    {
    public:
    
    	/**utility functions**/
    	string role() const { return myRole; }
    	char id() const {return myId; }
    	char energy() const { return myEnergy; }
    
    	
    	string myRole;
    	char myId;
    	char myEnergy;
    	
    	struct SENSE : public SPOT
    	{
    		char gradient; 		
    		bool onCheese;
    		char inventory;
    		char onGround;		
    		SPOT* me;
    		SPOT* myLeft;
    		SPOT* myRight;
    		SPOT* myBack;
    		SPOT* myFront;
    		  //function updateSenses is having trouble reading this
    		vector<vector<SPOT> > map();
    	};
    	
    void updateSenses (string Message) 
    	{
    		myId = Message.at(0); 
    		gradient = Message.at(2);
    		stack<char> inventory;
    		char gd[35]; 
    	 
    		string message("");
    		
    		stack<char> s;
    		int endlines = 0;
    		int it = 0;
    		/* get input */
    		for (int i = 1; i < Message.size(); i++)	
    		{
    			if ( Message.at(i) == '\n') { endlines++; }
    			if ( Message.at(i) == '"' && !s.empty())  { s.pop(); }
    			
    			 if ( Message.at(i) == '"' && s.empty() ) 
    				{ 
    					s.push( Message.at(i)); 
    					if( endlines == 2 && Message.at(i+1) != '(' && Message.at(i+1) != ')') { inventory.push( Message.at(i+1) );}
    					
    					/* what do we see? */
    					if( endlines == 3 && Message.at(i+1) != '(' && Message.at(i+1) != ')' ) //fill grid array up with data
    					{
    							{
    								gd[it] = (Message.at(i+1));
    								it++;
    							}
    					}	
    				}
    			/* what's on the ground? */
    			if ( endlines == 4 && Message.at(i+1) != '(' ) 
    					{
    						if (Message.at(i+1) == ')') onGround = ' ';
    						else onGround = Message.at(i+1); 
    					}
    		}
    	vector< vector<SPOT> > view (5, vector<SPOT> (7)); 
    		int i = 0;
    		while (i < it)
    		{
    			for ( int k = 0; k < 5; k++ )
    			{
    				for (int j = 0; j < 7; ++j)
    				{
    					if (gd[i] == " ") { view[k][j].blocked = false;  }//if empty space, SPOT is not blocked
    					if (gd[i]== "0") // if this is me
    					{
    						me = view[k][j];
    						myRight = view[k][j+1];
    						myLeft = view[k][j-1];
    						myFront = view[k-1][j];
    						myBack = view[k+1][j];
    					}
    					//north, south.. etc implemented in larger grid
    					i++;
    				}
    			}
    		}
    //cout grid
    	  for ( int i = 0; i < 5; i++ ) 
    		{
    			for ( int j = 0; j < 7; j++ )
    			cout << '|' << view[i][j]. <<'|';
    			cout<<'\n';
    		}
    	}
    	
    //string chooseWisely()
    //{
    //		/*** this will contain all the if/else statements
    //}
    
    };
    #endif /*"agent.h"*/
    
    /** Main **/
    
    using namespace std;
    
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <stack>
    #include <iomanip>
    
    #include "connection.cpp"
    #include "agent.h"
    
    
    
    int main( ) 
    {
    	/* to connect to the environment of Maeden, connect to the Madenport server 
    	by creating an intance of the socket class and sending your role.  
    	Socket constructer returns the agent's id.						*/
    	int sock;
    	string role = "base\n";
    	sock = connect(role);	
    	string Message = Receive(sock);
    	agent mouse();
    	mouse.updateSenses(Message);
    	
    
    	Send("r\n", sock);
    	Receive(sock);
    
    	
    	return 0;
    }
    
    
    
    
     
    Last edited by a moderator: Feb 25, 2009
  2. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    I haven't tried compiling it but looking over the code there seems to be some confusion over SENSE and SPOT, and possibly there are ambiguities that prevent successful compilation. For example, if agent mouse() were successful, what would mouse::gradient refer to; would it be in the embedded SENSE structure or would it be in the SENSE structure that agent is derived from? You wouldn't even be able to resolve the ambiguity with mouse::SENSE::gradient since that is still ambiguous.

    Why does agent need to derive from SENSE? How is it a type of SENSE?

    In struct SPOT, do north, south etc need to be SPOT* or struct SPOT *? Is SPOT defined somewhere else? If so then perhaps struct SPOT should be called something else to avoid confusion. If not then probably the lack of definition of SPOT (struct SPOT is not the same) is the cause of the problem.
     
  3. lapetitedingue

    lapetitedingue New Member

    Joined:
    Feb 24, 2009
    Messages:
    7
    Likes Received:
    0
    Trophy Points:
    0
    whoa! I'm sorry about that ambiguous doubling up of structs..(athough this may look just as bad to you as it still doesn't compile) I moved the structs back into the class- I would like SENSES to be a part of the agent, whose members are updated everytime it makes a move, and the SPOTS to represent the distinct coordinates of the grid world (and anything that may be ontop). Here is my revised agent class:
    Code:
    /*
     *  agent.h
     *
     */
    #ifndef AGENT_H
    #define AGENT_H
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <stack>
    using namespace std;
    
    class agent
    {
    public:
    
    struct SENSE
    {
    char gradient; 		
    bool onCheese;
    char inventory;
    char onGround;
    	
    		struct SPOT //the coordinates of visual grid of the agent (and later of the map) will be made up of 
    	{
    		char obj; // contains object on the SPOT
    		char helperId; // agent id of a helper agent if there is one on the SPOT
    		bool blocked;
    	
    	//these will be extra functionality for a larger map which will be updated as the agent continues to explore the world
    /*	SPOT* north;
    	SPOT* south;
    	SPOT* east;
    	SPOT* west;*/
    	};
    	
    SPOT* me;
    SPOT* myLeft;
    SPOT* myRight;
    SPOT* myBack;
    SPOT* myFront;
      //function updateSenses is having trouble reading this
    vector<vector<SPOT> > map();
    };
    
    	/**utility functions**/
    	string role() const { return myRole; }
    	char id() const {return myId; }
    	char energy() const { return myEnergy; }
    
    	
    	string myRole;
    	char myId;
    	char myEnergy;
    	
    
    
    
    	
    void updateSenses (string Message) 
    	{
    		myId = Message.at(0); 
    		gradient = Message.at(2);
    		stack<char> inventory;
    		char gd[35]; 
    	 
    		string message("");
    		
    		stack<char> s;
    		int endlines = 0;
    		int it = 0;
    		/* get input */
    		for (int i = 1; i < Message.size(); i++)	
    		{
    			if ( Message.at(i) == '\n') { endlines++; }
    			if ( Message.at(i) == '"' && !s.empty())  { s.pop(); }
    			
    			 if ( Message.at(i) == '"' && s.empty() ) 
    				{ 
    					s.push( Message.at(i)); 
    					if( endlines == 2 && Message.at(i+1) != '(' && Message.at(i+1) != ')') { inventory.push( Message.at(i+1) );}
    					
    					/* what do we see? */
    					if( endlines == 3 && Message.at(i+1) != '(' && Message.at(i+1) != ')' ) //fill grid array up with data
    					{
    							{
    								gd[it] = (Message.at(i+1));
    								it++;
    							}
    					}	
    				}
    			/* what's on the ground? */
    			if ( endlines == 4 && Message.at(i+1) != '(' ) 
    					{
    						if (Message.at(i+1) == ')') onGround = ' ';
    						else onGround = Message.at(i+1); 
    					}
    		}
    	vector< vector<SPOT> > view (5, vector<SPOT> (7)); 
    		int i = 0;
    		while (i < it)
    		{
    			for ( int k = 0; k < 5; k++ )
    			{
    				for (int j = 0; j < 7; ++j)
    				{
    					if (gd[i] == " ") { view[k][j].blocked = false;  }//if empty space, SPOT is not blocked
    					if (gd[i]== "0") // if this is me
    					{
    						me = view[k][j];
    						myRight = view[k][j+1];
    						myLeft = view[k][j-1];
    						myFront = view[k-1][j];
    						myBack = view[k+1][j];
    					}
    					//north, south.. etc implemented in larger grid
    					i++;
    				}
    			}
    		}
    //cout grid
    	  for ( int i = 0; i < 5; i++ ) 
    		{
    			for ( int j = 0; j < 7; j++ )
    			cout << '|' << view[i][j]. <<'|';
    			cout<<'\n';
    		}
    	}
    	
    //string chooseWisely()
    //{
    //		/*** this will contain all the if/else statements
    //}
    
    };
    #endif /*"agent.h"*/
    
     
  4. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    > SPOT* me;

    What is SPOT? Where is it defined? (Note that SPOT and struct SPOT are not the same thing.)

    One of the differences between "class X" and "struct X" is that "class X" allows you to define objects as just "X an_x;", you don't need "class", but "struct X" requires structures to be defined as "struct X an_x;", you can't do "X an_x;" as you can with classes.
     
  5. lapetitedingue

    lapetitedingue New Member

    Joined:
    Feb 24, 2009
    Messages:
    7
    Likes Received:
    0
    Trophy Points:
    0
    Thank you SOOOO much xpi0t0s! That was exactly the advice I needed. You would be surprised at how many people told me there was no difference between classes and structs...you just made my morning
    : )
     
  6. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    Another difference between struct and class is that by default class members are private but struct members are public. struct and class are definitely not interchangeable keywords.
     
    shabbir likes this.
  7. asadullah.ansari

    asadullah.ansari TechCake

    Joined:
    Jan 9, 2008
    Messages:
    356
    Likes Received:
    14
    Trophy Points:
    0
    Occupation:
    Developer
    Location:
    NOIDA
    As xpiotos said correct...

    1. For a kind of information, struct in C and struct in C++ are totally different( in C struct has no concept of public, private etc and cann't defined any function inside struct) . This is just a kind of information.
    2. This reason is already given by xpi0t0s but for more clearity see this also. In C++, there are lot of differences b/w class and struct
    Example:
    Code:
    struct SPOT
         {
             // members
         };     
       struct SPOT x ;
    Here struct SPOT is a user defined data type and x is variable/object of that type.

    Code:
    class SPOT
    {
            /// members
    };
    
    SPOT x;
    in this case SPOT will be a user defined data type and x will be variable/object of SPOT type.

    3. Other diff is explained by xpi0t0s.
     
  8. asadullah.ansari

    asadullah.ansari TechCake

    Joined:
    Jan 9, 2008
    Messages:
    356
    Likes Received:
    14
    Trophy Points:
    0
    Occupation:
    Developer
    Location:
    NOIDA
    As xpiotos said correct...

    1. For a kind of information, struct in C and struct in C++ are totally different( in C struct has no concept of public, private etc and cann't defined any function inside struct) . This is just a kind of information.
    2. This reason is already given by xpi0t0s but for more clearity see this also. In C++, there are lot of differences b/w class and struct
    Example:
    Code:
    struct SPOT
         {
             // members
         };     
       struct SPOT x ;
    Here struct SPOT is a user defined data type and x is variable/object of that type.

    Code:
    class SPOT
    {
            /// members
    };
    
    SPOT x;
    in this case SPOT will be a user defined data type and x will be variable/object of SPOT type.

    3. Other diff is explained by xpi0t0s.
     
  9. lapetitedingue

    lapetitedingue New Member

    Joined:
    Feb 24, 2009
    Messages:
    7
    Likes Received:
    0
    Trophy Points:
    0
    hmmmm...so a 'struct SPOT x' would be declared when you want to create some other type of structure containing SPOTS?
     
  10. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    Not necessarily. The word after "struct" is the name of the struct, so struct foo { ... }; defines a structure called foo. You can declare variables of type struct foo, for example struct foo bar;

    If it's just a single variable of a particular struct and you don't need to refer to that struct anywhere else then you don't need the name, e.g. struct { ... } baz; then you can refer to the parts of baz with baz.member1, baz.member2 etc, but you can't create another struct of the same type as baz.

    If you want to use similar syntax to class then you can typedef a structure, in one of two ways:
    typedef struct { ... } quux; defines a new type quux which means that struct
    then:
    quux some_obj; defines some_obj as that structure, or

    struct gronk { ... } ;
    typedef struct gronk gronk; // OK because the two gronks are in different namespaces
    then:
    gronk a_gronk;

    I'm not sure what the benefits of either are. If you define struct gronk then typedef it, then you can use a struct gronk either directly or in other typedefs. Depending on the design of the program it may make sense to have multiple "struct gronks" with different names. On the other hand quux is a structure you can't reuse anywhere.

    Examples aren't too easy to think of. Global variables are one possible use of an unnamed structure, e.g.
    struct {
    int global1;
    int global2;
    } Global_vars;

    which is still global, but then it's obvious when you refer to Global_vars.global1 what it is and where it comes from, so makes the whole global variables nightmare slightly less difficult to deal with.

    I'll see if I can think of an example for the other type tomorrow, basically you need multiple structures with the same attribute names and types...
     
  11. lapetitedingue

    lapetitedingue New Member

    Joined:
    Feb 24, 2009
    Messages:
    7
    Likes Received:
    0
    Trophy Points:
    0
    Thanks xpi0t0s, that makes sense.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice