I'm trying to learn how to use classes in C . This is my file structure.
main.cpp (sueca.cpp)
#include "Card.h"
#include "Deck.h"
#include "Player.h"
#include "Turn.h"
#include "Game.h"
int main ()
{
std::cout << "\t\t\t.:: Sueca Game ::." << std::endl;
Game sueca;
//sueca.startGame();
return 0;
}
Card.h:
#ifndef CARD_H
#define CARD_H
#include <iostream> // std::cout
#include <string> // std::string
class Card {
public:
Card();
Card(int&, int&);
~Card();
int getSuit() const;
int getRank() const;
int getPoints() const;
void printCard () const;
void setSuit(int&);
void setRank(int&);
void setCard(int&, int&);
private:
int suit;
int rank;
};
#endif
Card.cpp
#include "Card.h"
Card::Card ()
{
suit = -1;
rank = -1;
}
Card::Card (int &isuit, int &irank)
{
suit = isuit;
rank = irank;
}
Card::~Card ()
{
}
int Card::getSuit () const
{
return suit;
}
int Card::getRank () const
{
return rank;
}
void Card::setSuit (int &isuit)
{
suit = isuit;
return;
}
void Card::setRank (int &irank)
{
rank = irank;
return;
}
void Card::setCard (int &isuit, int &irank)
{
suit = isuit;
rank = irank;
}
int Card::getPoints () const
{
if (rank <= 4)
return 0;
else if (rank <= 7)
return rank-3;
else
return rank 2;
}
void Card::printCard () const
{
std::string naipe, nome;
switch (suit)
{
case 0:
naipe = "HEARTS";
break;
case 1:
naipe = "DIAMONDS";
break;
case 2:
naipe = "CLUBS";
break;
case 3:
naipe = "SPADES";
break;
}
switch (rank)
{
case 0:
nome = "TWO";
break;
case 1:
nome = "THREE";
break;
case 2:
nome = "FOUR";
break;
case 3:
nome = "FIVE";
break;
case 4:
nome = "SIX";
break;
case 5:
nome = "QUEEN";
break;
case 6:
nome = "JACK";
break;
case 7:
nome = "KING";
break;
case 8:
nome = "SEVEN";
break;
case 9:
nome = "ACE";
break;
}
std::cout << nome << " of " << naipe;
return;
}
Deck.h:
#ifndef DECK_H
#define DECK_H
#include <iostream> // std::cout
#include <algorithm> // std::shuffle
#include <array> // std::array
#include <string> // std::string
#include <random> // std::default_random_engine
#include <chrono> // std::chrono::system_clock
#include "Card.h"
class Deck : public Card{
public:
Deck();
~Deck();
void shuffleDeck(int&);
void printDeck();
private:
std::array<Card,40> element;
};
#endif
Deck.cpp:
#include "Deck.h"
Deck::Deck ()
{
auto i = 0;
for (auto s = 0; s < 4; s)
{
for (auto r = 0; r < 10; r)
{
element[i].setCard(s, r);
i;
}
}
}
void Deck::shuffleDeck (int ×)
{
for (auto i = 0; i < times; i)
{
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::shuffle(element.begin(), element.end(), std::default_random_engine(seed));
}
return;
}
void Deck::printDeck ()
{
for (auto c = 0; c < element.size(); c)
{
std::cout << "card\t(" << c << ")\t";
element[c].printCard();
}
return;
}
Player.h:
#ifndef PLAYER_H
#define PLAYER_H
#include <iostream> // std::cout
#include <string> // std::string
#include <array> // std::array
#include "Card.h"
class Player : public Card {
public:
Player();
Player(int&, std::string&);
~Player();
int getID() const;
std::string getName() const;
int getPoints() const;
int printHand() const;
void setID(int&);
void setName(std::string&);
void setPoints(int&);
private:
int id;
std::string name;
int points = 0;
std::array<Card,10> hand;
};
#endif
Player.cpp
#include "Player.h"
Player::Player ()
{
id = -1;
points = 0;
}
Player::Player (int &iid, std::string &iname)
{
id = iid;
name = iname;
points = 0;
}
Player::~Player ()
{
}
int Player::getID () const
{
return id;
}
std::string getName () const
{
return name;
}
int Player::getPoints () const
{
return points;
}
int Player::printHand () const
{
if (hand.size() == 0)
{
std::cout << "\t\t\tERROR: Player " << name << " has no cards (" << id << ")" << std::endl;
return -1;
}
std::cout << "(" << id << ") " << name << "'s cards:" << std::endl;
for (auto i = 0; i < 10; i)
hand[i].printCard();
return 0;
}
void Player::setID(int &iid)
{
id = iid;
return;
}
void Player::setName(std::string &iname)
{
name = iname;
return;
}
void Player::setPoints(int &ipoints)
{
points = ipoints;
return;
}
Turn.h:
#ifndef TURN_H
#define TURN_H
#include <iostream> // std::cout
#include <array> // std::array
#include "Player.h"
#include "Card.h"
// NOTE: I'd like to access the variable "trump" from the class Game, making it the parent of this class (one game has many turns)
class Turn {
public:
Turn();
Turn(int&, std::array<Player,4>&);
~Turn();
int getID() const;
int playTurn();
int getTurnWinner();
private:
int id;
//int trump; --> use the trump variable from the parent Game instead
std::array<Player,4> gamer;
std::array<Card,4> move;
};
#endif
Turn.cpp:
#include "Turn.h"
Turn::Turn ()
{
id = -1;
}
Turn::Turn (int &roundNO, std::array<Player,4> &players)
{
id = roundNO;
gamer = players;
}
int Turn::getID () const
{
return id;
}
int Turn::playTurn ()
{
for (auto p = 0; p < 4; p)
{
std::cout << "\t(" << p << ") " << gamer[p].getName() << "'s turn!" << std::endl;
if (gamer[p].printHand() == -1)
return -1;
std::cout << "Pick the number of the card you want to play: ";
int playcard;
std::cin >> playcard;
while (playcard > 10)
{
std::cout << "Invalid selection!\nPick the number of the card you want to play: ";
std::cin >> playcard;
}
//move[p] = gamer[p].hand[playcard];
}
return 0;
}
int Turn::getTurnWinner ()
{
Card max, maxtrunfo;
int winner, winnertrunfo, points = 0;
bool trunfo = false;
if (move.size() < 4)
{
std::cout << "\t\t\tERROR: Round " << id << " has" << move.size() << " cards." << std::endl;
return -1;
}
if (gamer.size() < 4)
{
std::cout << "\t\t\tERROR: Round " << id << " has" << gamer.size() << " cards." << std::endl;
return -2;
}
for (auto i = 0; i < 4; i)
{
if (move[i].getRank() > max.getRank())
{
max = move[i];
winner = i;
}
if ((move[i].getSuit() == trump) && (move[i].getRank() > maxtrunfo.getRank())) ///VER ISTO
{
maxtrunfo = move[i];
trunfo = true;
winnertrunfo = i;
}
points = move[i].getPoints();
}
if (trunfo)
{
std::cout << "\t(" << winnertrunfo << ") " << gamer[winnertrunfo].getName() << " wins!" << std::endl;
//gamer[winnertrunfo].getPoints() = points;
}
else
{
std::cout << "\t(" << winner << ") " << gamer[winner].getName() << " wins!" << std::endl;
//gamer[winner].getPoints() = points;
}
return 0;
}
Game.h:
#ifndef GAME_H
#define GAME_H
#include <iostream> // std::cout
#include <algorithm> // std::shuffle
#include <array> // std::array
#include <string> // std::string
#include <random> // std::default_random_engine
#include <chrono> // std::chrono::system_clock
#include "Turn.h"
#include "Player.h"
class Game {
public:
//Game();
//~Game();
int startGame();
int setTrump();
private:
int trunfo;
int duration;
Deck gamedeck;
std::array<Turn,10> round;
std::array<Player,4> gamer;
};
#endif
Game.cpp
#include "Game.h"
/*Game::Game ()
{
trunfo = -1;
duration = 0;
}
Game::~Game ()
{
}*/
int Game::setTrump ()
{
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator(seed);
std::uniform_int_distribution<int> gamer(0,3);
int player = gamer(generator);
return player;
}
int Game::startGame ()
{
int shuffle = 1;
std::cout << "How many times do you want to shuffle the deck? ";
std::cin >> shuffle;
while (shuffle < 1)
{
std::cout << "Please insert an integer bigger than 0.\nHow many times do you want to shuffle the deck? ";
std::cin >> shuffle;
}
gamedeck.printDeck();
gamedeck.shuffleDeck(shuffle);
std::cout << "Deck shuffled " << shuffle << " times!" << std::endl;
std::cout << "\t * The player pairings will be (1 & 3) and (2 & 4). Let's proceed to name each player." << std::endl;
std::string playername;
for (auto i = 0; i < 4; i)
{
std::cout << "Type the name of Player " << i 1 << ": ";
std::cin >> playername;
while (playername.size() == 0)
{
std::cout << "Please insert a readable name.\nType the name of Player " << i 1 << ": ";
std::cin >> playername;
}
gamer[i].id = i;
gamer[i].name = playername;
for (auto c = 0; c < 10; c )
gamer[i].hand[c] = gamedeck.element[c i*10]; /// APRENDER A PASSAR O ENDEREÇO DA CARTA
}
// Set trump card & suit
int trump_player, trump_card;
trump_player = setTrump();
std::cout << "The trump card is (" << trump_player << ") "<< gamer[trump_player].name << "'s ";
gamer[trump_player].hand[0].print_card();
trunfo = gamer[trump_player].hand[0].suit;
return 0;
}
Terminal Error:
g sueca.cpp -o sueca
/usr/bin/ld: /tmp/ccmCL0jl.o: in function `std::array<Turn, 10ul>::array()':
sueca.cpp:(.text._ZNSt5arrayI4TurnLm10EEC2Ev[_ZNSt5arrayI4TurnLm10EEC5Ev] 0x27): undefined reference to `Turn::Turn()'
/usr/bin/ld: sueca.cpp:(.text._ZNSt5arrayI4TurnLm10EEC2Ev[_ZNSt5arrayI4TurnLm10EEC5Ev] 0x7d): undefined reference to `Turn::~Turn()'
/usr/bin/ld: /tmp/ccmCL0jl.o: in function `std::array<Turn, 10ul>::~array()':
sueca.cpp:(.text._ZNSt5arrayI4TurnLm10EED2Ev[_ZNSt5arrayI4TurnLm10EED5Ev] 0x39): undefined reference to `Turn::~Turn()'
/usr/bin/ld: /tmp/ccmCL0jl.o: in function `std::array<Player, 4ul>::array()':
sueca.cpp:(.text._ZNSt5arrayI6PlayerLm4EEC2Ev[_ZNSt5arrayI6PlayerLm4EEC5Ev] 0x27): undefined reference to `Player::Player()'
/usr/bin/ld: sueca.cpp:(.text._ZNSt5arrayI6PlayerLm4EEC2Ev[_ZNSt5arrayI6PlayerLm4EEC5Ev] 0x76): undefined reference to `Player::~Player()'
/usr/bin/ld: /tmp/ccmCL0jl.o: in function `std::array<Player, 4ul>::~array()':
sueca.cpp:(.text._ZNSt5arrayI6PlayerLm4EED2Ev[_ZNSt5arrayI6PlayerLm4EED5Ev] 0x39): undefined reference to `Player::~Player()'
/usr/bin/ld: /tmp/ccmCL0jl.o: in function `Game::Game()':
sueca.cpp:(.text._ZN4GameC2Ev[_ZN4GameC5Ev] 0x1d): undefined reference to `Deck::Deck()'
/usr/bin/ld: sueca.cpp:(.text._ZN4GameC2Ev[_ZN4GameC5Ev] 0x75): undefined reference to `Deck::~Deck()'
/usr/bin/ld: /tmp/ccmCL0jl.o: in function `Game::~Game()':
sueca.cpp:(.text._ZN4GameD2Ev[_ZN4GameD5Ev] 0x40): undefined reference to `Deck::~Deck()'
collect2: error: ld returned 1 exit status
Additionally, I understand that these are very basic isses I've been reading "A tour of C " but it doesn't go into much detail on how some things are done so I browse the web looking for solutions to issues occuring in my code. Trying to learn C by myself with some prior C knowledge. If you could recommend me some ways to progress, I'd appreciate it (maybe another book I should buy?). This program is my attempt at coding a popular card game from my country.
CodePudding user response:
You may need to step back in your book a bit, but I'll explain a little bit.
Include (.h) files typically exist so that you can have 10 .cpp files that make use of the declared class. This is where you put class Foo { ... } stuff. Then anyone who wants to use Foo can include the .h file.
The .cpp files are where you implement the class. I think you understand this.
When you compile, you compile each of the .cpp's and then link them together. Or you can just do this:
g --std=c 17 A.cpp B.cpp C.cpp -o MyProgram
This will program MyProgram (you can call it whatever you want) and include all the code from those three .cpp files.
It can be a lot more complicated than that, of course. But if you do a g line that is similar to the one I shows you, listing all of your .cpp files, then as long as you've implemented all the code that you've defined, it should build.