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; }
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.
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"*/
> 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.
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 : )
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.
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.
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.
hmmmm...so a 'struct SPOT x' would be declared when you want to create some other type of structure containing SPOTS?
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...