Structure, syntax question

Alright, so i'm in the midst of programming my most ambitious program to date to force me to learn code organization and bringing it all together. Anyway, I'm imagining a game where you can move around area to area, moving through story mode which will be quite simple as i imagine it right now. I'm eager for feedback on anything and everything that you can critic give advise on so far in my project as far as syntax, logic. Thank you so much in advance for your time to help a ambitious coder.

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
#include <iostream>
#include <windows.h>
#include <fstream>
#include <stdlib.h>
#include <time.h>

struct Create_Map {
       const static int height = 8;
       const static int width = 8;
       std::string map[height][width];
       
       Create_Map::Create_Map(std::string map_file);
       
       void display();
       void showDescription();//INCOMPLETE &  UNTESTED
};

struct Player {

       std::string username;
       int xCoord, yCoord;
       std::string currentLocation, lastLocation;
       
       Player::Player(std::string map[][8]);
       void setLocation(std::string map[][8]);
       void goNorth(std::string map[][8]);
       void goSouth(std::string map[][8]);
       void goEast(std::string map[][8]);
       void goWest(std::string map[][8]);      
};

int main() // -------- MAIN ---------
{
    SetConsoleTitle("Dungeon - by (Name will go here)");
    struct Create_Map home("HOME_VILLAGE.txt");
    struct Player hero(home.map);

system("PAUSE"); 
return 0;
}

/////BEGIN STRUCT FUNCTIONS


Create_Map::Create_Map(std::string map_file){
std::ifstream getMap(map_file.c_str());
if (getMap.is_open()){
   for ( int x = 0; x < height; x++ ){
       for ( int y = 0; y < width; y++){
           getMap >> map[x][y];}
           }
       }
       getMap.close();                               
}

void Create_Map::display(){
     for ( int x = 0; x < height; x++ ){
         for ( int y = 0; y < width; y++ ){
             std::cout << map[x][y] << " ";}
             std::cout << std::endl;}
}//END MAP STRUCTURE

Player::Player(std::string map[][8]){
xCoord = 1;
yCoord = 1;
setLocation(map);
}
void Player::setLocation(std::string map[][8]){
     lastLocation = currentLocation;
     currentLocation = map[xCoord][yCoord];     
}

void Player::goNorth(std::string map[][8]){
     if (map[xCoord - 1][yCoord] != "WALL") {xCoord--;}
     else { std::cout << "There is something blocking the way." << std::endl; }
}

void Player::goSouth(std::string map[][8]){
     if (map[xCoord + 1][yCoord] != "WALL") {xCoord++;}
     else { std::cout << "There is something blocking the way." << std::endl; }
}

void Player::goEast(std::string map[][8]){
     if (map[xCoord][yCoord + 1] != "WALL") {yCoord++;}
     else { std::cout << "There is something blocking the way." << std::endl; }     
}

void Player::goWest(std::string map[][8]){
     if (map[xCoord][yCoord - 1] != "WALL") {yCoord--;}
     else { std::cout << "There is something blocking the way." << std::endl; }
}
I would make player and map classes.
You may refer to this for classes: http://en.cppreference.com/w/cpp/language/classes

I would prototype the class and data structure definitions (if there is anything to be prototyped) in a header, and define them in a seperate .cpp file. (instead of inlineing them, like you're currently doing)

I would also use vectors instead of arrays (because it vectors can be resized as needed).

I would also, instead of using strings, use single characters to define the map. You can use preprocessor directives to make it easier to write the code. This will decrease the amount of memory you use to store a map, and allow you to expand it without worry. Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#define WALL char(1)
#define ROAD char(2)
//and so on

//then you can just do:
vector<vector<char> > map;
switch(vector[x][y])
{
    case WALL:
    {
    }
    break;
    //etc...
}


Other than that, it looks like you have done good work with the over-all design of it.
Last edited on
Thank you so much for your input, I don't have many good outlets so anytime I get advice I appreciate it! Can I ask a noob question? What are preprocessor directives and how would I incorporate that?

Thanks for your time again!

Just realized your example was right there lol. I'm familiar with vectors but not proficient, and as far as preprocessor directives I've never messed with them.
Last edited on
If you need a good reference, try www.cppreference.com

Preprocessor directives are instructions for the compiler. You can define keywords that are replaced by their definition.

Example:

1
2
3
4
#define std::string VARIABLE_TYPE

//... somwhere in code:
VARIABLE_TYPE myvar; //in this case, it declares a string 


What this does is allow you to do two things:

1. You can use preprocessor directive to "abstract" somthing, like character codes; i.e. #define char(1) TERMINATION . Instead of remembering that char(1) is a termination byte, you can simply name it.

2. You can use it to define somthing used VERY OFTEN throughout all of the code, but that you might want to change later on. For example: You may want all files that the program saves to have a file extension. If you want to change the extension, all you have to do is change 1 definition!

preprocessor directives are also good for other things, but for the purposes you need them, this is good enough for now.

Here is an example of what I use preprocessor definitions for. On Linux, multi-byte characters are returned for key presses. Here are some special keys I use often:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* non-control keys (keys != 27):*/
#define BACKSPACE_KEY 127
#define ENTER_KEY 10

/* Control characters (int(char) == 27), as represented by a vector of multiple return codes: */
#define LEFT_KEY std::vector<int>({27, 91, 68})
#define RIGHT KEY std::vector<int>({27, 91, 67})
#define UP_KEY std::vector<int>({27, 91, 65})
#define DOWN_KEY std::vector<int>({27, 91, 66})
#define HOME_KEY std::vector<int>({27, 79, 72})
#define END_KEY std::vector<int>({27, 79, 70})
#define PGUP_KEY std::vector<int>({27, 91, 53, 126})
#define PGDOWN_KEY std::vector<int>({27, 91, 54, 126})
#define DELETE_KEY std::vector<int>({27, 91, 51, 126}) 


Instead of remembering that the delete key returns {27, 91, 51, 126} every time, I can simply use DELETE_KEY instead. But, what if I want to compile this program on windows?? All the keys will be different!!! This makes it easy to port my program to windows, or mac, if I want. With this, I also only have to change the values here, instead of at every place I use them.
Last edited on
CodeGoggles:

No, they are instructions to the compiler... It really doesn't matter what part: they tell the cimpiler what to compile, and allow the user to create aliases.
Preprocessor directives are instructions for the compiler.


@IWishIKnew Preprocessor directives are instructions for the preprocessor the compiler comes later in the build process.
Last edited on
CodeGoggles:
There is no such thing as a "preprocessor". Mabey you could provide a source.
There is no such thing as a "preprocessor". Mabey you could provide a source.


http://en.wikipedia.org/wiki/Preprocessor

This is the definition of the compiler

http://en.wikipedia.org/wiki/Compiler
No, they are instructions to the compiler... It really doesn't matter what part: they tell the cimpiler what to compile, and allow the user to create aliases.


The term compiling can refer to the build process (but more correctly the build process). Calling the build process compiling is misleading. The compiler is the actual program that churns out machine code.
Last edited on
One should avoid using preprocessor directives in C++. There are less error prone (and more debugger friendly) methods for accomplishing these things. Most of the above examples can be replaced with simple constants/typedefs/using directives.
Cire said:
One should avoid using preprocessor directives in C++. There are less error prone (and more debugger friendly) methods for accomplishing these things


Could you elaborate on what kind of errors can occure with preprocessor directives, and why other methods are better?
I realize that there are multiple ways of doing everything in programming and that no ONE way is truly the BEST way, but there are certainly ways to make things easier and more understandable, I think that is the most difficult part of programming, is knowing in what instance to use different tools...

Thanks for all the responses though. I can see why pre-processor directives could be useful.
Topic archived. No new replies allowed.