DemonFace DemonFace - 2 months ago 8
C++ Question

invalid conversion from ‘const char*’ to ‘char’ / uninitialized const member in struct

I started to practice my programming in C++ (I know just a bit), so I started to write a simple, Hearthstone-like card-game, just in purpose of practicing. It was all good, but now, at a point I get an error.
Here is my code:

Header:

#ifndef DRAW_H_INCLUDED
#define DRAW_H_INCLUDED

struct Card
{
char name;
int mana;
int attack;
int defense;
};

Card deck_p1[32];
Card deck_p2[32];

int cardsLeft_p1 = 30;
int cardsLeft_p2 = 30;

struct BattleG
{
Card p1_bg1;
Card p1_bg2;
Card p1_bg3;
Card p1_bg4;
Card p1_bg5;
Card p2_bg1;
Card p2_bg2;
Card p2_bg3;
Card p2_bg4;
Card p2_bg5;
};

BattleG battleG;

struct Player
{
char name;
int hp;
int mana;
Card hand1;
Card hand2;
Card hand3;
Card hand4;
Card hand5;
Card hand6;
Card hand7;
};

#endif // DRAW_H_INCLUDED


Main:

#include <iostream>
#include <ctime>
#include <cstdlib>
#include <string>
#include "draw.h"

using namespace std;

int getRandomNumber(int min, int max)
{
static const double fraction = 1.0 / (static_cast<double>(RAND_MAX) + 1.0);
return static_cast<int>(rand() * fraction * (max - min + 1) + min);
}

Card drawCard(int p)
{
if (p == 1)
{
int currentCard = getRandomNumber(1, cardsLeft_p1);
Card drawnCard = deck_p1[currentCard];
for (int i = currentCard; i < cardsLeft_p1; i++)
deck_p1[i] = deck_p1[i + 1];
cardsLeft_p1--;
return drawnCard;
}
else
{
int currentCard = getRandomNumber(1, cardsLeft_p2);
Card drawnCard = deck_p2[currentCard];
for (int i = currentCard; i < cardsLeft_p2; i++)
deck_p2[i] = deck_p2[i + 1];
cardsLeft_p2--;
return drawnCard;
}
}

void newPage()
{
for (int i = 0; i < 25; i++)
cout << endl;
}

void printDetails(Card player_hand)
{
cout << "Attack: " << player_hand.attack << endl;
cout << "Defense: " << player_hand.defense << endl;
cout << "Mana cost: " << player_hand.mana << endl;
}

void printBattleG(Player player1, Player player2, BattleG battleG)
{
cout << endl << "Current cards on the battleground:\n" << endl;
cout << player1.name << "'s first card on the battleground: " << battleG.p1_bg1.name << endl;
cout << player1.name << "'s second card on the battleground: " << battleG.p1_bg2.name << endl;
cout << player1.name << "'s third card on the battleground: " << battleG.p1_bg3.name << endl;
cout << player1.name << "'s fourth card on the battleground: " << battleG.p1_bg4.name << endl;
cout << player1.name << "'s fifth card on the battleground: " << battleG.p1_bg5.name << endl;
cout << player2.name << "'s first card on the battleground: " << battleG.p2_bg1.name << endl;
cout << player2.name << "'s second card on the battleground: " << battleG.p2_bg2.name << endl;
cout << player2.name << "'s third card on the battleground: " << battleG.p2_bg3.name << endl;
cout << player2.name << "'s fourth card on the battleground: " << battleG.p2_bg4.name << endl;
cout << player2.name << "'s fifth card on the battleground: " << battleG.p2_bg5.name << endl;
}

void useCard(Player player, Card nothing)
{
cout << endl << "Which card do you want to use? (Write the card's name or 'none')" << endl;
char choise;
cin >> choise;

if (choise == player.hand1.name)
{
if (player.hand1.mana <= player.mana)
{
if (battleG.p1_bg1.name == nothing.name)
{
battleG.p1_bg1 = player.hand1;
cout << "First card on your side of the battleground: " << battleG.p1_bg1.name << endl;
}
else if (battleG.p1_bg2.name == nothing.name)
{
battleG.p1_bg2 = player.hand1;
cout << "Second card on your side of the battleground: " << battleG.p1_bg2.name << endl;
}
else if (battleG.p1_bg3.name == nothing.name)
{
battleG.p1_bg3 = player.hand1;
cout << "Third card on your side of the battleground: " << battleG.p1_bg3.name << endl;
}
else if (battleG.p1_bg4.name == nothing.name)
{
battleG.p1_bg4 = player.hand1;
cout << "Fourth card on your side of the battleground: " << battleG.p1_bg4.name << endl;
}
else if (battleG.p1_bg5.name == nothing.name)
{
battleG.p1_bg5 = player.hand1;
cout << "Fifth card on your side of the battleground: " << battleG.p1_bg5.name << endl;
}
player.mana = player.mana - player.hand1.mana;
player.hand1 = nothing;
}
else
cout << "You don't have enough mana." << endl;
}

else if (choise == player.hand2.name)
{
if (player.hand2.mana <= player.mana)
{
if (battleG.p1_bg1.name == nothing.name)
{
battleG.p1_bg1 = player.hand2;
cout << "First card on your side of the battleground: " << battleG.p1_bg1.name << endl;
}
else if (battleG.p1_bg2.name == nothing.name)
{
battleG.p1_bg2 = player.hand2;
cout << "Second card on your side of the battleground: " << battleG.p1_bg2.name << endl;
}
else if (battleG.p1_bg3.name == nothing.name)
{
battleG.p1_bg3 = player.hand2;
cout << "Third card on your side of the battleground: " << battleG.p1_bg3.name << endl;
}
else if (battleG.p1_bg4.name == nothing.name)
{
battleG.p1_bg4 = player.hand2;
cout << "Fourth card on your side of the battleground: " << battleG.p1_bg4.name << endl;
}
else if (battleG.p1_bg5.name == nothing.name)
{
battleG.p1_bg5 = player.hand2;
cout << "Fifth card on your side of the battleground: " << battleG.p1_bg5.name << endl;
}
player.mana = player.mana - player.hand2.mana;
player.hand2 = nothing;
}
else
cout << "You don't have enough mana." << endl;
}

else if (choise == player.hand3.name)
{
if (player.hand3.mana <= player.mana)
{
if (battleG.p1_bg1.name == nothing.name)
{
battleG.p1_bg1 = player.hand3;
cout << "First card on your side of the battleground: " << battleG.p1_bg1.name << endl;
}
else if (battleG.p1_bg2.name == nothing.name)
{
battleG.p1_bg2 = player.hand3;
cout << "Second card on your side of the battleground: " << battleG.p1_bg2.name << endl;
}
else if (battleG.p1_bg3.name == nothing.name)
{
battleG.p1_bg3 = player.hand3;
cout << "Third card on your side of the battleground: " << battleG.p1_bg3.name << endl;
}
else if (battleG.p1_bg4.name == nothing.name)
{
battleG.p1_bg4 = player.hand3;
cout << "Fourth card on your side of the battleground: " << battleG.p1_bg4.name << endl;
}
else if (battleG.p1_bg5.name == nothing.name)
{
battleG.p1_bg5 = player.hand3;
cout << "Fifth card on your side of the battleground: " << battleG.p1_bg5.name << endl;
}
player.mana = player.mana - player.hand3.mana;
player.hand3 = nothing;
}
else
cout << "You don't have enough mana." << endl;
}

else if (choise == player.hand4.name)
{
if (player.hand4.mana <= player.mana)
{
if (battleG.p1_bg1.name == nothing.name)
{
battleG.p1_bg1 = player.hand4;
cout << "First card on your side of the battleground: " << battleG.p1_bg1.name << endl;
}
else if (battleG.p1_bg2.name == nothing.name)
{
battleG.p1_bg2 = player.hand4;
cout << "Second card on your side of the battleground: " << battleG.p1_bg2.name << endl;
}
else if (battleG.p1_bg3.name == nothing.name)
{
battleG.p1_bg3 = player.hand4;
cout << "Third card on your side of the battleground: " << battleG.p1_bg3.name << endl;
}
else if (battleG.p1_bg4.name == nothing.name)
{
battleG.p1_bg4 = player.hand4;
cout << "Fourth card on your side of the battleground: " << battleG.p1_bg4.name << endl;
}
else if (battleG.p1_bg5.name == nothing.name)
{
battleG.p1_bg5 = player.hand4;
cout << "Fifth card on your side of the battleground: " << battleG.p1_bg5.name << endl;
}
player.mana = player.mana - player.hand4.mana;
player.hand4 = nothing;
}
else
cout << "You don't have enough mana." << endl;
}

else if (choise == player.hand5.name)
{
if (player.hand5.mana <= player.mana)
{
if (battleG.p1_bg1.name == nothing.name)
{
battleG.p1_bg1 = player.hand5;
cout << "First card on your side of the battleground: " << battleG.p1_bg1.name << endl;
}
else if (battleG.p1_bg2.name == nothing.name)
{
battleG.p1_bg2 = player.hand5;
cout << "Second card on your side of the battleground: " << battleG.p1_bg2.name << endl;
}
else if (battleG.p1_bg3.name == nothing.name)
{
battleG.p1_bg3 = player.hand5;
cout << "Third card on your side of the battleground: " << battleG.p1_bg3.name << endl;
}
else if (battleG.p1_bg4.name == nothing.name)
{
battleG.p1_bg4 = player.hand5;
cout << "Fourth card on your side of the battleground: " << battleG.p1_bg4.name << endl;
}
else if (battleG.p1_bg5.name == nothing.name)
{
battleG.p1_bg5 = player.hand5;
cout << "Fifth card on your side of the battleground: " << battleG.p1_bg5.name << endl;
}
player.mana = player.mana - player.hand5.mana;
player.hand5 = nothing;
}
else
cout << "You don't have enough mana." << endl;
}

else if (choise == player.hand6.name)
{
if (player.hand6.mana <= player.mana)
{
if (battleG.p1_bg1.name == nothing.name)
{
battleG.p1_bg1 = player.hand6;
cout << "First card on your side of the battleground: " << battleG.p1_bg1.name << endl;
}
else if (battleG.p1_bg2.name == nothing.name)
{
battleG.p1_bg2 = player.hand6;
cout << "Second card on your side of the battleground: " << battleG.p1_bg2.name << endl;
}
else if (battleG.p1_bg3.name == nothing.name)
{
battleG.p1_bg3 = player.hand6;
cout << "Third card on your side of the battleground: " << battleG.p1_bg3.name << endl;
}
else if (battleG.p1_bg4.name == nothing.name)
{
battleG.p1_bg4 = player.hand6;
cout << "Fourth card on your side of the battleground: " << battleG.p1_bg4.name << endl;
}
else if (battleG.p1_bg5.name == nothing.name)
{
battleG.p1_bg5 = player.hand6;
cout << "Fifth card on your side of the battleground: " << battleG.p1_bg5.name << endl;
}
player.mana = player.mana - player.hand6.mana;
player.hand6 = nothing;
}
else
cout << "You don't have enough mana." << endl;
}

else if (choise == player.hand7.name)
{
if (player.hand7.mana <= player.mana)
{
if (battleG.p1_bg1.name == nothing.name)
{
battleG.p1_bg1 = player.hand7;
cout << "First card on your side of the battleground: " << battleG.p1_bg1.name << endl;
}
else if (battleG.p1_bg2.name == nothing.name)
{
battleG.p1_bg2 = player.hand7;
cout << "Second card on your side of the battleground: " << battleG.p1_bg2.name << endl;
}
else if (battleG.p1_bg3.name == nothing.name)
{
battleG.p1_bg3 = player.hand7;
cout << "Third card on your side of the battleground: " << battleG.p1_bg3.name << endl;
}
else if (battleG.p1_bg4.name == nothing.name)
{
battleG.p1_bg4 = player.hand7;
cout << "Fourth card on your side of the battleground: " << battleG.p1_bg4.name << endl;
}
else if (battleG.p1_bg5.name == nothing.name)
{
battleG.p1_bg5 = player.hand7;
cout << "Fifth card on your side of the battleground: " << battleG.p1_bg5.name << endl;
}
player.mana = player.mana - player.hand7.mana;
player.hand7 = nothing;
}
else
cout << "You don't have enough mana." << endl;
}
}

int main()
{
srand(static_cast<unsigned int>(time(0)));
rand();

Card card1 = {"Card1", 1, 1, 1};
Card card2 = {"Card2", 2, 2, 2};
Card card3 = {"Card3", 2, 3, 1};
Card card4 = {"Card4", 2, 1, 3};
Card card5 = {"Card5", 3, 3, 3};
Card card6 = {"Card6", 3, 4, 2};
Card card7 = {"Card7", 3, 5, 1};
Card card8 = {"Card8", 3, 2, 4};
Card card9 = {"Card9", 3, 1, 5};
Card card10 = {"Card10", 4, 4, 4};
Card card11 = {"Card11", 4, 5, 3};
Card card12 = {"Card12", 4, 6, 2};
Card card13 = {"Card13", 4, 7, 1};
Card card14 = {"Card14", 4, 3, 5};
Card card15 = {"Card15", 4, 2, 6};
Card card16 = {"Card16", 4, 1, 7};
Card card17 = {"Card17", 5, 5, 5};
Card card18 = {"Card18", 5, 6, 4};
Card card19 = {"Card19", 5, 7, 3};
Card card20 = {"Card20", 5, 8, 2};
Card card21 = {"Card21", 5, 9, 1};
Card card22 = {"Card22", 5, 4, 6};
Card card23 = {"Card23", 5, 3, 7};
Card card24 = {"Card24", 5, 2, 8};
Card card25 = {"Card25", 5, 1, 9};
Card card26 = {"Card26", 1, 2, 2};
Card card27 = {"Card27", 2, 4, 4};
Card card28 = {"Card28", 3, 6, 6};
Card card29 = {"Card29", 4, 8, 8};
Card card30 = {"Card30", 5, 10, 10};
Card nothing = {"Empty"};

deck_p1[1] = card1;
deck_p1[2] = card2;
deck_p1[3] = card3;
deck_p1[4] = card4;
deck_p1[5] = card5;
deck_p1[6] = card6;
deck_p1[7] = card7;
deck_p1[8] = card8;
deck_p1[9] = card9;
deck_p1[10] = card10;
deck_p1[11] = card11;
deck_p1[12] = card12;
deck_p1[13] = card13;
deck_p1[14] = card14;
deck_p1[15] = card15;
deck_p1[16] = card16;
deck_p1[17] = card17;
deck_p1[18] = card18;
deck_p1[19] = card19;
deck_p1[20] = card20;
deck_p1[21] = card21;
deck_p1[22] = card22;
deck_p1[23] = card23;
deck_p1[24] = card24;
deck_p1[25] = card25;
deck_p1[26] = card26;
deck_p1[27] = card27;
deck_p1[28] = card28;
deck_p1[29] = card29;
deck_p1[30] = card30;

deck_p2[1] = card1;
deck_p2[2] = card2;
deck_p2[3] = card3;
deck_p2[4] = card4;
deck_p2[5] = card5;
deck_p2[6] = card6;
deck_p2[7] = card7;
deck_p2[8] = card8;
deck_p2[9] = card9;
deck_p2[10] = card10;
deck_p2[11] = card11;
deck_p2[12] = card12;
deck_p2[13] = card13;
deck_p2[14] = card14;
deck_p2[15] = card15;
deck_p2[16] = card16;
deck_p2[17] = card17;
deck_p2[18] = card18;
deck_p2[19] = card19;
deck_p2[20] = card20;
deck_p2[21] = card21;
deck_p2[22] = card22;
deck_p2[23] = card23;
deck_p2[24] = card24;
deck_p2[25] = card25;
deck_p2[26] = card26;
deck_p2[27] = card27;
deck_p2[28] = card28;
deck_p2[29] = card29;
deck_p2[30] = card30;

BattleG battleG;

Player player1;
cout << "Player1! What's your name?\n";
cin >> player1.name;
player1.hp = 30;
player1.mana = 1;

Player player2;
cout << "Player2! What's your name?\n";
cin >> player2.name;
player2.hp = 30;
player2.mana = 1;

player1.hand1 = drawCard(1);
player1.hand2 = drawCard(1);
player1.hand3 = drawCard(1);
player1.hand4 = drawCard(1);
player1.hand5 = drawCard(1);
player1.hand6 = nothing;
player1.hand7 = nothing;

newPage();
cout << player1.name << "'s turn:\n" << endl;

cout << endl << "Your first card is: " << player1.hand1.name << endl;
printDetails(player1.hand1);
cout << endl << "Your second card is: " << player1.hand2.name << endl;
printDetails(player1.hand2);
cout << endl << "Your third card is: " << player1.hand3.name << endl;
printDetails(player1.hand3);
cout << endl << "Your fourth card is: " << player1.hand4.name << endl;
printDetails(player1.hand4);
cout << endl << "Your fifth card is: " << player1.hand5.name << endl;
printDetails(player1.hand5);

battleG.p1_bg1 = nothing;
battleG.p1_bg2 = nothing;
battleG.p1_bg3 = nothing;
battleG.p1_bg4 = nothing;
battleG.p1_bg5 = nothing;
battleG.p2_bg1 = nothing;
battleG.p2_bg2 = nothing;
battleG.p2_bg3 = nothing;
battleG.p2_bg4 = nothing;
battleG.p2_bg5 = nothing;

useCard(player1, nothing);

player2.hand1 = drawCard(2);
player2.hand2 = drawCard(2);
player2.hand3 = drawCard(2);
player2.hand4 = drawCard(2);
player2.hand5 = drawCard(2);
player2.hand6 = nothing;
player2.hand7 = nothing;

newPage();
cout << player2.name << "'s turn:\n";

cout << endl << "Your first card is: " << player2.hand1.name << endl;
printDetails(player2.hand1);
cout << endl << "Your second card is: " << player2.hand2.name << endl;
printDetails(player2.hand2);
cout << endl << "Your third card is: " << player2.hand3.name << endl;
printDetails(player2.hand3);
cout << endl << "Your fourth card is: " << player2.hand4.name << endl;
printDetails(player2.hand4);
cout << endl << "Your fifth card is: " << player2.hand5.name << endl;
printDetails(player2.hand5);

printBattleG(player1, player2, battleG);

cout << endl << "Which card do you want to use? (Write the card's name or 'none')" << endl;
cin >> choise;

return 0;
}


The errors are: invalid conversion from ‘const char’ to ‘char’* at the defines of the cards (
Card card1 = {"Card1", 1, 1, 1};
,
Card card2 = {"Card1", 1, 1, 1};
, etc.) and uninitialized const member in struct at
const char name;
(header/4st line) if I rewrite the char to const char.
I searched a lot about this errors, but none of the solutions worked for me. I have an earlier code what is working, but I can't coppy it here, because it is beyond the character limit. I'm using GNU GCC compiler in CodeBlocks 16.01.

Answer

Two related syntax problems leap out:

in

struct Card
{
    char name;
    int mana;
    int attack;
    int defense;
};

Card::name is a single character. With

(Card card1 = {"Card1", 1, 1, 1};

OP is attempting to place a pointer to many characters ( almost a char *. I'll expand on this in a moment) into the single character. They types are too different so the assignment cannot be made.

The first solution to come to mind is probably

struct Card
{
    char * name;
    int mana;
    int attack;
    int defense;
};

But this won't work because of problem 2. A string literal, "Card1" for example, may or may not be stored in a writable region of memory. As a result string literals are always const to make sure the compiler will catch the mistake if you try to write to it.

So struct Card could be defined as

struct Card
{
    const char * name;
    int mana;
    int attack;
    int defense;
};

But this is C++, so

struct Card
{
    std::string name;
    int mana;
    int attack;
    int defense;
};

would be preferred and beneficial to you as you do a lot of string comparisons that will compile but flat out not work as written with a const char *.

Either will result in a torrent of other syntax errors to be revealed. For one thing

char choise;

will need to be

std::string choise;

I'm not going to address the logic errors in this code other than recommend OP get familiar with their development environment's debugger.

Recommendation: Never write this much code without testing. Odds are staggeringly good that assumptions you have made will not survive testing, and you'll have to throw out a lot of your work--both the code that doesn't work and the code that is built upon the code that doesn't work. An early mistake casts a long shadow, so test early and test often.

Happy coding!