Dungeon Program With Questions

Pages: 12
Hi all, was wondering if someone would critique my code?

Questions:

Is there a way to combine the ternary ? operator with the conditional statement so I dont have to write it twice?

1
2
3
4
5
6
7
8
      if(GameBoard[PlayerRow][PlayerColm] == Trap || GameBoard[PlayerRow][PlayerColm] == Mob)
    {
        //Lose
        cout << "You were killed by a ";//a smooth criminal
        c = (GameBoard[PlayerRow][PlayerColm] == Trap) ? "Trap" : "Monster";
        cout << c;
        return false;
    }


Without duplicating code, the easiest way to create more monsters is through a monster class? Where I could add monster1.move monster2.move into my while loop?

Is there a way to get rid of the newline character without a second getchar? Or a way to input upon keypress rather than enter? (unfortunately using g++ so I dont have conio for getch available.

Is the way I verify user input in MovePlayer acceptable? What could I do to make this function better? (I dislike how I have it repeating "Hit head etc") I attempted to write a function but it only removed a few lines and probably made the program draw more resources.

Thank You In advance.
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253

#include <iostream>
#include <stdio.h>
#include <stdlib.h>//rand srand getchar()
#include <time.h>//time NUZLL for rand
#include <string>//used in 1 line..
using namespace std;

const int ROWS = 4;
const int COLM = 10;
const char DEFAULT = '.';
const char Trap = 'T';
const char Treasure = 'X';
const char Mob = 'M';
const char Player = 'P';

//Function to fill gameboard with default
void InitializeBoard(char GameBoard[][COLM]);
//function to randomly place traps, pass to check function (posx posy symbol)
void PlaceGameObjects(char GameBoard[][COLM], int TrapCount, int &PlayerRow, int &MobRow, int &MobColm);
//print gameboard
void PrintBoard(char GameBoard[][COLM]);

void MovePlayer(char GameBoard[][COLM], int &PlayerRow, int &PlayerColm);//Pass by reference so that we dont have to call func twice
//Check if character moved into tile that will end game.
void MoveMob(char GameBoard[][COLM], int &MobRow, int &MobColm);

bool CheckGameState(char GameBoard[][COLM], int PlayerRow, int PlayerColm);

int main()
{
    srand(time(NULL));//Seed random 
    char GameBoard[ROWS][COLM];
    int TrapCount = 3;
    int PlayerRow, PlayerColm;
    int MobRow, MobColm;
    PlayerRow = 0;//none of these are used until initialized.. worth having?
    PlayerColm = 0;
    MobRow = 0;
    MobColm = 0;
    InitializeBoard(GameBoard);
    
    PlaceGameObjects(GameBoard, TrapCount, PlayerRow, MobRow, MobColm);
    
    GameBoard[PlayerRow][PlayerColm] = Player; //character on first column.
    
    //cout << string( 100, '\n' );//clear screen forces it to start at the bottom of the console from the getgo
    
    do
    {
        PrintBoard(GameBoard);
        
        MovePlayer(GameBoard,PlayerRow,PlayerColm);
        
        MoveMob(GameBoard,MobRow, MobColm);
        
        //cout << string( 100, '\n' );//clear screen
        
    }while(CheckGameState(GameBoard, PlayerRow, PlayerColm) == true);
    
    return 0;
}

//Function to fill gameboard with default
void InitializeBoard(char GameBoard[][COLM])
{
    for(int i = 0; i < ROWS; i++)
    {
        for(int j = 0; j < COLM; j++)
        {
            GameBoard[i][j] = DEFAULT;
        }
    }
    
}

//function to randomly place traps, pass to check function (posx posy symbol)
void PlaceGameObjects(char GameBoard[][COLM], int TrapCount, int &PlayerRow, int &MobRow, int &MobColm)
{
    //Traps will not spawn on starting row of character or treasure
    int RandomRow, RandomColm;
    for(int i = 0; i < TrapCount; i++)
    {
        RandomRow = rand() % ROWS;
        RandomColm = rand() % COLM;
        //check if gameboard position not default - if not taken then fill position
        if(RandomColm == 0 || RandomColm == 9 || GameBoard[RandomRow][RandomColm] != DEFAULT)//Prevent traps from appearing on column Character and Treasure spawns
        {
            //!= DEFAULT prevents Traps from being on top of each other.
            i--;
            continue;//Skips Below and loops
        }
        GameBoard[RandomRow][RandomColm] = Trap;
    }
    
    //place monster
    bool IsMobPlaced = false;
    while(IsMobPlaced == false)
    {
        RandomRow = RandomRow = rand() % ROWS;//out of if statement so we dont need another random above while loop
        RandomColm = RandomColm = rand() % COLM;
        
        if(GameBoard[RandomRow][RandomColm] == Trap || RandomColm == 0 || RandomColm == 9)
        {
            //Want it to random again, so we loop and dont set mob placed so it stays false
        }
        else
        {
            GameBoard[RandomRow][RandomColm] = Mob;
            MobRow = RandomRow;
            MobColm = RandomColm;
            IsMobPlaced = true;
        }
        
    }
    //No way for player or treasure to overlap anything so i do not run a check for them.
    RandomRow = rand() % ROWS;
    
    GameBoard[RandomRow][COLM-1] = Treasure;//Treasure on last column
    
    RandomRow = rand() % ROWS;
    
    PlayerRow = RandomRow;//Passes random row for Player to start on, Not assigned here since used and modified in main
}

//print gameboard
void PrintBoard(char GameBoard[][COLM])
{

    for(int i = 0; i < ROWS; i++)
    {
        for(int j = 0; j < COLM; j++)
        {
            cout << GameBoard[i][j];
        }
        cout << endl;
    }
    
}
void MovePlayer(char GameBoard[][COLM], int &PlayerRow, int &PlayerColm)//Pass by reference so that we dont have to call func twice
{
    GameBoard[PlayerRow][PlayerColm] = DEFAULT; //Clears current position on board
    char UserInput;
    UserInput = getchar();
    switch(UserInput)
    {
        case 'w':
        PlayerRow--;//Character position Y - 1 Starts at 0 goes upwards as we go down so negative moves up
        if(PlayerRow < 0)
        {
            cout << "You hit a wall \n";
            PlayerRow++;
        }
        break;
            
        case 'a':
        PlayerColm--;
        if(PlayerColm < 0)
        {
            PlayerColm--;
            cout << "You hit a wall \n";
        }
        break;
            
        case 's':
        PlayerRow++;
        if(PlayerRow > 3)
        {
            cout << "You hit a wall \n";
            PlayerRow--;
        }
        break;
            
        case 'd':
        PlayerColm++;
        if(PlayerColm > 9)
        {
            PlayerColm--;
            cout << "You hit a wall \n";
        }
        break;
    }
    UserInput = getchar();//Grabs newline character so we dont double loop
    GameBoard[PlayerRow][PlayerColm] = Player;//sets new position
}

void MoveMob(char GameBoard[][COLM], int &MobRow, int &MobColm)
{
    GameBoard[MobRow][MobColm] = DEFAULT;//Clears current position on board
    int RandomNum;
    RandomNum = rand() % 4 + 1;
    switch(RandomNum)
    {
        case 1:
        MobRow--;//Character position Y - 1 Starts at 0 goes upwards as we go down so negative moves up
        if(MobRow < 0 || GameBoard[MobRow][MobColm] == Trap)
        {
            MobRow++;
        }
        break;
            
        case 2:
        MobColm--;
        if(MobColm < 0 || GameBoard[MobRow][MobColm] == Trap)
        {
            MobColm--;
        }
        break;
            
        case 3:
        MobRow++;
        if(MobRow > 3 || GameBoard[MobRow][MobColm] == Trap)
        {
            MobRow--;
        }
        break;
            
        case 4:
        MobColm++;
        if(MobColm > 9 || GameBoard[MobRow][MobColm] == Trap)
        {
            MobColm--;
        }
        break;
    }
        GameBoard[MobRow][MobColm] = Mob;//set new mob position
    
}

//Check if character moved into tile that will end game.
bool CheckGameState(char GameBoard[][COLM], int PlayerRow, int PlayerColm)
{
    string c;
    if(GameBoard[PlayerRow][PlayerColm] == Trap || GameBoard[PlayerRow][PlayerColm] == Mob)
    {
        //Lose
        cout << "You were killed by a ";//a smooth criminal
        c = (GameBoard[PlayerRow][PlayerColm] == Trap) ? "Trap" : "Monster";
        cout << c;
        return false;
    }
    else if(GameBoard[PlayerRow][PlayerColm] == Treasure)
    {
        //Win
        cout << "You reached the treasure! You Win! \n";
        return false;
    }
    else
    {
        //continue playing
        return true;
    }
}



Before worrying about a monster class, I'd make a Game class. All of your functions belongs as members of a Game class;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Game
{   char board[ROWS][COLM];

public:
    //Function to fill gameboard with default
    void InitializeBoard ();    
    //function to randomly place traps, pass to check function (posx posy symbol)
    void PlaceGameObjects (int TrapCount, int &PlayerRow, int &MobRow, int &MobColm);
    //print gameboard
    void PrintBoard ();
    //Pass by reference so that we dont have to call func twice
    void MovePlayer(int &PlayerRow, int &PlayerColm);
    //Check if character moved into tile that will end game.
    void MoveMob (int &MobRow, int &MobColm);   
    bool CheckGameState (int PlayerRow, int PlayerColm);
};

First of all, I want to congratulate you on your outstanding comments. They explain why the code is doing what it's doing. That's the most important thing, and it's something that the code usually can't tell you.

You use 9 and 4 all over the code where you mean ROWS and COLM-1. You should be able to change ROWS and/or COLM and have the program work without error.

Lines 100 & 101: Redundant assignments to RandomRow and RandomColm respectively.
Lines 192-225. Don't use magic numbers like 4 and 9, especially since you have constants (ROW AND COLM) that are what you want. Personally, I think this is clearer:
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
    // Remember previous values
    int oldColm(MobColm);
    int oldRow(MobRow);

    switch (RandomNum) {
    case 1:
        MobRow--;  
        break;
    case 2:
        MobColm--;
        break;
    case 3:
        MobRow++;
        break;
    case 4:
        MobColm++;
        break;
    }
    if (MobColm < 0 || MobColm >= COLM ||
        MobRow < 0 || MobRow >= ROW ||
        GameBoard[MobRow][MobColm] == Trap) {

        MobRow = oldRow;
        MobColm = oldColm;
    }


Lines 84-92: Again, it may be personal preference, but I think this is clearer. There's an outer loop to place the traps, and an inner loop to select where to place each one.
1
2
3
4
5
6
7
8
9
10
    for (int i = 0; i < TrapCount; i++) {
        //check if gameboard position not default - if not taken then fill position
        //Prevent traps from appearing on column Character and Treasure spawns
        do {
            RandomRow = rand() % ROWS;
            RandomColm = rand() % COLM;
        } while (RandomColm == 0 || RandomColm == 9 || GameBoard[RandomRow][RandomColm] != DEFAULT);

        GameBoard[RandomRow][RandomColm] = Trap;
    }

Actually, if would be even better if you restricted RandomColm to values between 1 and 8 right from the start. If you think about it, you can do that with the math.

Lines 97-113: A similar loop as above would be clearer.

As for a monster class, I think you need an Actor class because the player is also an actor. Actors have a symbol to display on the board, a position, and restrictions on where they can go on the board initially. There may be other properties too.
I got a "Content too long" and my post went poof. Ouch. Heres a much condensed version. >:(
I guess code segments are the way to go. Noted!

@AbstractionAnon
Wouldnt the game class be the same as above just with calling the members? I understand you're supposed to put things that work together/similar in a class. It just doesnt seem that much better here.
Could you elaborate on the benefit of it a bit more?

@dhayden
Thanks :) Comments+ Good naming helps. Never understood my classmates aversion to these.

I changed a lot. Woops Magic Numbers. 84-92 Brain wanted to use continue idk why. Great examples. I didnt change my switch statements yet, but will.(short version of original lol)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    for(int i = 0; i < TrapCount; i++)
    {
        do
        {
            RandomRow = rand() % (ROWS - 1);
            RandomColm = rand() % (COLM - 2) + 1;//prevent traps from appearing on column where the character and treasure appear 0 & column -1
        }while(GameBoard[RandomRow][RandomColm] != DEFAULT);
        //check if gameboard position not default - if not taken then fill position
        GameBoard[RandomRow][RandomColm] = Trap;
    }
    //place monster
    do
    {
        RandomRow = rand() % (ROWS - 1);//out of if statement so we dont need another random above while loop
        RandomColm = rand() % (COLM - 2) + 1;            
        
    }while(GameBoard[RandomRow][RandomColm] == Trap); //If its selected a trap -> Loop
    
    GameBoard[RandomRow][RandomColm] = Mob;
    MobRow = RandomRow;
    MobColm = RandomColm;


I dont typically see long code posts on the forums. Going to Implement an Actor and Game class and pastebin it next.

Thank you all a lot! (Really wish my original post didnt go poof)
Last edited on
Could you elaborate on the benefit of it a bit more?

One advantage of making a Game class is that board becomes a member variable and is directly accessible to the member functions. You no longer have to pass the board to every function. Note the signatures of the functions in the class declaration I posted do not pass board.

Another advantage is that by making board a private member variable you restrict access to the board. Only member functions can make changes to the board. This makes debugging a lot easier. It also helps enforce better design.
Thank you. Textbooks/tutorials focus a lot on the how and not the why, so I appreciate it!
I'll implement the classes and post hopefully today :)
You may also want to have a structure to hold the row/col coordinates for the location of the different objects.

And IMO the PlaceGameObjects() function is doing too much. Perhaps it would be better to break this function into several smaller functions that handle one of your objects.

Could you elaborate on the benefit [of a game class] of it a bit more?

In addition to AbstractionAnon's excellent points, I'll add one more from my own experience with a sudoku solver program.

Suppose you want to do some speculative execution of the game. Maybe you want monsters that will move to surround the player. Or maybe you want to see whether the player has any chance of winning. If you have a Game class then your program could copy the current game instance and play both sides of the game a little to see what happens. If you have a game class then this might be an afternoons work. If you don't have a Game class then it could be impossible.
I am receiving an error about my class declarations

66:9: error: expected ‘;’ before ‘Monster’
Mob Monster;
67:12: error: expected ‘;’ before ‘PlayerOne’
Player PlayerOne;

That being said I havent completely flushed out these classes and set the whole program up. However I cant figure out why Im not able to at least declare them. I was expecting errors that would come from me attempting to use things that no longer exist.

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
#include <iostream>
#include <stdio.h>
#include <stdlib.h>//rand srand getchar()
#include <time.h>//time NUZLL for rand
#include <string>
using namespace std;

const int ROWS = 4;
const int COLM = 10;
const char DEFAULT = '.';
const char Trap = 'T';
const char Treasure = 'X';
const char Mob = 'M';
const char Player = 'P';



class Game
{
    char GameBoard[ROWS][COLM];
    public:
    void InitializeBoard();
    void PrintBoard();
    void PlaceGameObjects(int TrapCount);
    void PlacePlayer(int &PlayerRow, int &PlayerColm); // TODO Create place mob & player functions
    void PlaceMob(int &MobRow, int &MobColm);
    bool CheckGameState(int PlayerRow, int PlayerColm);
};


class Player
{
    int PlayerRow;
    int PlayerColm;
    public:
    void MovePlayer(char GameBoard[][COLM]);
    Player();
};

Player::Player()//Default constructor to initialize player
{
    PlayerRow = 0;
    PlayerColm = 0;
}

class Mob
{
    int MobRow;
    int MobColm;
    public:
    void MoveMob(char GameBoard[][COLM]);
    Mob();
};

Mob::Mob()
{
    MobRow = 0;
    MobColm = 0;
}


int main()
{
    srand(time(NULL));//Seed random 
    Game PlayGame;
    Mob Monster;
    Player PlayerOne;

Actually im pretty sure its my constants at the top with the same names. Im dumb. Hold on..

edit:
That was the issue. When Ive got this whole thing running again I'll need to address putting the actors symbol inside their class.

edit x2: Is it easier just to rewrite something to implement classes? This feels like a mess right now. I might have more success just rewriting the whole thing..
Last edited on
in my class I return the gameboard as type char

1
2
3
4
5
6
7
8
9
10
11
12
13
class Game
{
    char GameBoard[ROWS][COLM];
    public:
    void InitializeBoard();
    void PrintBoard();
    void PlaceGameObjects(int TrapCount);
    void PlacePlayer(int &PlayerRow, int &PlayerColm); // TODO Create place mob & player functions
    void PlaceMob(int &MobRow, int &MobColm);
    bool CheckGameState(int PlayerRow, int PlayerColm);
    char PassGameBoard() {return GameBoard[ROWS][COLM];}
};


In another class I need to use that return value, but the class wants a pointer to char. Giving an invalid conversion error.

1
2
3
4
5
6
7
8
9
10
11
class Player
{
    int PlayerRow;
    int PlayerColm;
    public:
    void MovePlayer(char GameBoard[][COLM]);
    int GetPlayerRow() { return PlayerRow;}
    int GetPlayerColm() { return PlayerColm;}
    Player();
};


I cant seem to figure out how to get from point A to B.
A few comments:
Lines 2-4: correct headers for a standards compliant compiler are <cstdio> (which you don't need) , <cstdlib> and <ctime>.

This feels like a mess right now. I might have more success just rewriting the whole thing.

You're not that far off. Don't get discouraged.

Have you noticed that your class Player and class Mob are identical? Yes, I understand you're not finished with them. As dhayden suggested, you need an Actor class. Player and Mob should inherit from Actor. That way you write common functions once.

Lines 25-26: PlacePlayer() and PlaceMob() are also identical with the exception of the symbol representing the Actor. I would consolidate these two functions info
 
bool PlaceActor (Actor & actor, int new row, int newcol);  // returns false if actor can't be placed there 


Lines 36,51: MovePlayer() and MoveMob() really don't belong as members of their respective classes. Doing so requires that they have access to the game board, but the game board is a private member of Game. See my suggestion above regarding PlaceActor().

Not sure if you've covered inheritance yet. Here's a simple example of an Actor class that is inherited by Player and Mob.
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
class Actor
{   int m_row;
    int m_col;
    char m_sym;     //  Type of actor
public:
    Actor (char sym)
    {   m_row = 0;  //  Default position
        m_col = 0;
        m_sym = sym;    //  Type of actor
    }
    
    //  Return the symbol representing the actor
    char get_sym () const
    {   return m_sym;
    }
};                

class Player : public Actor
{   
public:
    Player () : Actor ('P')
    {}
};

class Mob : public Actor 
{
public:
    Mob () : Actor ('M')
    {}
};





I had originally planned for two classes so that one class didnt contain excess everytime I made a new monster. However it looks like inheritance is the way to go with that. I'll do some studying.

PlacePlayer and Placemob are similar, but the Player will only get placed on the first column, while mobs are somewhere in the middle but not on traps.
1
2
3
4
    void PlacePlayer(int &PlayerRow, int &PlayerColm)
    {
        GameBoard[PlayerRow][PlayerColm] = PlayerSymbol;
    }; 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void Game::PlaceMob(int &MobRow, int &MobColm)
{
    int RandomRow;
    int RandomColm;
    //place monster
    do
    {
        RandomRow = rand() % (ROWS - 1);
        RandomColm = rand() % (COLM - 2) + 1;            
        
    }while(GameBoard[RandomRow][RandomColm] == Trap); //If its selected a trap -> Loop
    
    GameBoard[RandomRow][RandomColm] = MobSymbol;
    MobRow = RandomRow;
    MobColm = RandomColm;
}


I believe youre correct about the Move functions needing to be in the Game class, but I'm unsure at this moment how to pass the private variables of a class as reference. Just getting lots of errors.

Lets say I have this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Game
{
char GameBoard [ROWS][COLM];
public:
void MovePlayer(int &PlayerRow, int &PlayerColm);
};

class Actor
{
int PlayerRow;
int PlayerColm;
public:
}


How do I get the references of PlayerRow and Colm passed into the move? Or are all my Actor positions going to need to be public? I've attempted a return PlayerRow function in the public Actor, but It just gives me conversion issues.
Going to study/implement inheritance and maybe that will fix it, just what im confused on right now.
Last edited on
Lines 10-11: PlayerRow and PlayerColm are poor names in your base class. An Actor can be a Player OR a Mob. In the class declaration for Actor that I posted, I named these m_row and m_col since they are generic to anything derived from Actor. The m_ prefix is a convention that indicates the variable is a member variable.

The best way to access private members of the Actor class is to add getters to the Actor class:
1
2
3
4
5
6
7
 
  int get_row () const
  {  return m_row;
  }
  int get_colm () const
  {  return m_colm;
  }


You might find it convenient to make m_row and m_col protected since you will probably want to access then from your derived classes.

As for PlacePlayer(), I would make it something like this:
1
2
3
4
void Game::PlacePlayer (Player & player, int newrow, int newcol)
{   GameBoard[newrow][newcol] = player.get_sym();  //  get the player's symbol
    player.set_position (newrow,newcol);  //  Update the players position
}; 

This implies Actor has a common setter called set_position.

PlaceMob() would be similar.


I understand you can get the value of the positions with getters, however if we update the positions in the Game class wouldn't we want to pass them as reference? Or is the only way to pass them like that is to pass a reference to that object like you do when you create this member function:
 
void Game::PlacePlayer (Player & player, int newrow, int newcol)


The reference locations of private members are unavailable outside the class, unless you pass use a function of the class to modify the values. So in no way would I be able to pass a reference of the private values out of the class. I can however pass the values, modify the values, and use a function to place those modified values back into the private section like you showed in your placeplayer example.

I think I'm starting to get it. Just a lot on my mental plate atm. Some of this will need to be done a few times before I remember it perfectly C:
if we update the positions in the Game class wouldn't we want to pass them as reference?

No need to. Passing by value is adequate. Actor::set_position() would simply store the new values since the Actor object contains the row and column of record for the Actor and anything derived from it.

Or is the only way to pass them like that is to pass a reference to that object like you do when you create this member function

There are multiple ways to accomplish storing the player position. What I suggested is probably the cleanest.

So in no way would I be able to pass a reference of the private values out of the class

No way you should do that. That defeats the purpose of making those values private. If you were going to do that, you might as well make them public and forget about encapsulation.


Last edited on
I've got my code back to where it was. A much stronger grasp on classes and inherited classes.

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
class Actor
{
    int Row;
    int Colm;
    char Symbol;
    public:
    Actor(char ClassSymbol)
    {
        Row = 0;
        Colm = 0;
        Symbol = ClassSymbol;
    }
    char const GetSymbol(){return Symbol;}
    int const GetRow(){return Row;}
    int const GetColm(){return Colm;}
    int UpdatePosition(int NewRow, int NewColm)
    {
        Row = NewRow;
        Colm = NewColm;
    }
    
};

class Player: public Actor // inherited class from Actor
{
    public:
    Player() : Actor('P') //Class Player default constructor is using Actors constructor with Char P
    {}
};

class Mob: public Actor
{
    public:
    Mob() : Actor('M')
    {}
    
};


I am having an issue with my CheckGameState however, And im not sure how to resolved it. The first if in the statement gives me an error
 
if(GameBoard[Player.GetRow()][Player.GetColm()] == Trap || GameBoard[Player.GetRow()][Player.GetColm()] == Mob)


gives me: error: expected primary-expression before ‘)’ token

However if I omit the part after the OR statement it runs just fine.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
bool Game::CheckGameState(Player &Player)
{
    string c;
    if(GameBoard[Player.GetRow()][Player.GetColm()] == Trap)// || GameBoard[Player.GetRow()][Player.GetColm()] == Mob)
    {
        //Lose
        cout << "You were killed by a ";//a smooth criminal
        c = (GameBoard[Player.GetRow()][Player.GetColm()] == Trap) ? "Trap" : "Monster";
        cout << c;
        return false;
    }
    else if(GameBoard[Player.GetRow()][Player.GetColm()] == Treasure)
    {
        //Win
        cout << "You reached the treasure! You Win! \n";
        return false;
    }
    else
    {
        //continue playing
        return true;
    }
}
gives me: error: expected primary-expression before ‘)’ token

You're back to the naming conflict you had before. You have both a class Mob and const char named Mob. The compiler doesn't know which one you meant.



I removed my global char const when I created the classes.

WHICH IS RIGHT I REMOVED IT SO MOB DOESNT EXIST!(My brain worked its exciting)
It fixed it. Why it didnt say "Mob" doesnt exist in this instance baffles me.

I do need to learn more naming conventions, everything named the same is going to get me in trouble more.

Set it to = 'M' currently. Will see about creating another global variable again, and changing the hard coded 'M' in my class and in the function to = MobSymbol as it had before.

Time to clean this up add menus for more monsters/traps and call it done
Why it didn't say "Mob" doesn't exist in this instance baffles me.

Mob does exist. It's the name of a class. The compiler wasn't expecting a class name at that point in the conditional.

The compiler error does makes sense, within the bounds of compiler error speak.
error: expected primary-expression before ‘)’ token

The compiler parsed the left hand side and the == tokens in the conditional expression. It was then expecting a primary expression as the right hand side of the conditional. What it found was a class name. Oops. Not what the compiler was expecting. The best the compiler could tell you was that it was expecting a primary expression.
Pages: 12