Modifing an object by another class - c++

My purpose is to change the tank (an object of first class) by another class (the odometer). So I try to passing by reference, its working when I pass directly object to constructor but its doesn't working when I make an object first then passing object by a method(setOdoIndex). Can someone have a way to do make a method to pass these parameters
#include <iostream>
using namespace std;
class FuelGauge {
protected:
double galls;
double check(double) const;
double checkFuel(double) const;
public:
FuelGauge(double galls){
check(galls);
this->galls = galls;
}
FuelGauge(){
*this = FuelGauge(0);
}
double getFuelLeft() const{
return galls;
}
FuelGauge operator++(){
if (galls > 15) throw "Tank max capacity is 15 gallon";
++galls;
return *this;
}
FuelGauge operator--(){
if (galls == 0) throw "Tank is empty";
--galls;
return *this;
}
void refuel(){
galls = 15;
}
};
double FuelGauge::check(double n) const {
if (n < 0) throw "Dont accepted negative value!";
if (n > 15) throw "Tank max capacity is 15 gallon";
return n;
}
class Odometer{
private:
int odo;
FuelGauge &tank;
void calOdo() {
if (odo > 999999) {odo = 0;};
}
public:
Odometer(int odo, FuelGauge &tank):tank(tank) {
this->odo = odo;
this->tank = tank;
}
Odometer():tank(tank) {
odo = 0;
}
int getOdoIndex() const{
return odo;
}
void setOdoIndex(int odo, FuelGauge &tank) {
this->odo = odo;
this->tank = tank;
}
void carDrive() {
--tank;
calOdo();
++odo;
}
};
int main() {
FuelGauge tank;
cout << "--Fill the tank--" << endl;
try {
for (int i = 0; i < 15; i++) {
++tank;
}
}
catch(const char* e) {
cerr << e << '\n';
}
cout << "\n--Car run--" << endl;
Odometer odo1(0, tank);
try {
for(int i = 0; i < 16; i++) {
cout << "Index of odometer: " << odo1.getOdoIndex() << endl;
cout << "Fuel left: " << tank.getFuelLeft() << endl;
odo1.carDrive();
}
}
catch(const char* e) {
cerr << e << '\n';
}
return 0;
}

Related

Is there a command to check if objects in my dynamic array are dynamic or static?

I made a dynamic array with template. The problem is that when I don't keep there pointers (for example: Tab<string> da;) my destructor doesn't have to clear it and throws error caused by delete arr[i];. My question is if I can put some if condition(in which I would put clear() method) which would tell me if my array keeps pointers. In the simplest way I can use clear() in main when I keeps there pointers, but my teacher wants me to make it like I wrote above.
I tried using is_pointer, but it doesn't work or I use it wrong.
Any suggestions?
#ifndef TABLICA_H
#define TABLICA_H
#include <iostream>
#include <type_traits>
using namespace std;
template<class T>
class Tab
{
public:
int size = 0;
int max_size = 1;
T* arr;
bool isDynamic = false;
Tab()
{
arr = new T[max_size];
}
~Tab()
{
clear();
delete[] arr;
}
void check_size()
{
if (size == max_size)
{
max_size = max_size * 2;
T* arr2 = new T[max_size];
for (int i = 0; i < size; i++)
{
arr2[i] = arr[i];
}
delete[] arr;
arr = arr2;
}
}
void push_back(const T& value)
{
check_size();
arr[size] = value;
size++;
}
T return_by_index(int index)
{
if (index<0 || index > size)
{
return NULL;
}
return arr[index];
}
bool replace(int index, const T& value)
{
if (index<0 || index > size)
{
return false;
}
arr[index] = value;
return true;
}
void print(int number)
{
cout << "Rozmiar obecny: " << size << endl;
cout << "Rozmiar maksymalny: " << max_size << endl;
cout << "Adres tablicy: " << arr << endl;
cout << "Kilka poczatkowych elementow tablicy " << "(" << number << ")" << endl;
for (int i = 0; i < number; i++)
{
cout << *arr[i] << endl;
}
}
void clear()
{
for (int i = 0; i < size; i++)
{
delete arr[i];
}
}
};
#endif
//Source:
#include <iostream>
struct object
{
int field1;
char field2;
object()
{
field1 = rand() % 10001;
field2 = rand() % 26 + 'A';
}
};
ostream& operator<<(ostream& out, const object& o)
{
return out << o.field1 << " " << o.field2;
}
int main()
{
Tab < object* >* da = new Tab < object* >();
delete da;
system("PAUSE");
return 0;

How to test the given ADT implementation with templates such as <int, int> and <string, int>?

I am working on a problem that requires the implementation of two ADT's. After Implementing, I need to test my bag implementations with the following template combinations:
<int, string>-- all functions
<string, int> -- insert and find functions only
My testing so far has been entering integers to test the different functions. I do not understand what it means to test the implementations with the templates.
Here is my bagADT implementation:
#include <stdlib.h>
#include "bagADT.h"
template <typename E>
class ABag : public Bag<E> {
private:
int maxSize;
int listSize;
E* listArray;
public:
ABag(int size = defaultSize) { // Constructor
maxSize = size;
listSize = 0;
listArray = new E[maxSize];
}
~ABag() { delete[] listArray; } // Destructor
bool addItem(const E& item) {
if (listSize >= maxSize) {
return false;
}
listArray[listSize] = item;
std::cout << "Add Item: Added " << item << " in spot " << listSize << std::endl;
listSize++;
return true;
}
bool remove(E& item) {
for (int i = 0; i < listSize; i++) {
if (listArray[i] == item) {
std::cout << "Remove: Removed " << item << " from position ";
item = i;
std::cout<< item << " and adjusted the location of all other elements." << std::endl;
for (i= item; i < listSize; i++) {
listArray[i] = listArray[i + 1];
}
listSize--;
return true;
}
}
return false;
}
bool removeTop(E& returnValue) {
if (listSize == 0) {
return false;
}
else {
returnValue = listArray[listSize - 1];
std::cout << "Remove Top: Removed " << returnValue << " from the top of the stack." << std::endl;
for (int i = listSize; i < maxSize; i++) {
listArray[i] = listArray[i + 1];
}
listSize--;
return true;
}
}
bool find(E& returnValue) const {
for (int i = 0; i < (listSize - 1); i++) {
if (listArray[i] == returnValue) {
returnValue = i;
return true;
}
}
return false;
}
bool inspectTop(E& item) const {
if (listSize == 0) {
return false;
}
else {
item = listArray[listSize - 1];
std::cout << "Inspect Top: The value on top is currently " << item << "." << std::endl;
return true;
}
}
void emptyBag() {
delete[] listArray;
listSize = 0;
listArray = new E[maxSize];
std::cout << "Empty Bag: Emptied the bag." << std::endl;
}
bool operator+=(const E& addend) {
if (listSize < maxSize) {
return true;
}
return false;
}
int size() const {
std::cout << "Size: Number of elements in listArray: " << listSize << std::endl;
return (listSize - 1);
}
int bagCapacity() const {
std::cout << "Bag Capacity: The capacity of this bag is " << maxSize << std::endl;
return maxSize;
}
};
Here is another file provided by my professor called kvpairs:
#ifndef KVPAIR_H
#define KVPAIR_H
// Container for a key-value pair
// Key object must be an object for which the == operator is defined.
// For example, int and string will work since they both have == defined,
// but Int will not work since it does not have == defined.
template <typename Key, typename E>
class KVpair {
private:
Key k;
E e;
public:
// Constructors
KVpair() {}
KVpair(Key kval, E eval)
{
k = kval; e = eval;
}
KVpair(const KVpair& o) // Copy constructor
{
k = o.k; e = o.e;
}
void operator =(const KVpair& o) // Assignment operator
{
k = o.k; e = o.e;
}
bool operator==(const KVpair& o) const {
if (o.k == k) {
return true;
}
return false;
}
//The following overload is provided by Adam Morrone, Spring 2016 class.
//Thanks Adam :)
friend ostream& operator<<(ostream& os, const KVpair& o) // output print operator
{
os << "Key: " << o.k << " Value: " << o.e;
return os;
}
// Data member access functions
Key key() { return k; }
void setKey(Key ink) { k = ink; }
E value() { return e; }
};
#endif
I am expected to show the test outputs using the above templates, but I have no idea how to do this. Also, ignore the += overload. It is incorrect and I know. I am supposed to overload it to directly add a new int to the array.
I think I understand now. I could be wrong, but this is my guess.
Your bag is singly templated, but it will be holding KVpair. They said they will use KVpair with <int, string> and <string, int>.
When they talk about testing it, that means they will be instantiating it as follows:
int main() {
ABag<KVPair<int, string>> bag;
bag.addItem(KVpair(1, "hi"));
//...
}
This is what I am pretty sure they mean by "testing it with templates".
As a minor edit, I don't know what C++ version you are using but if it's very archaic, you might need to write template instantiation like ABag<KVPair<int, string> > instead of putting them together. I remember vaguely this being an issue a long time ago.

Compilation error in C++ when using an assignment operator =?

I have written a program which was given to me as a homework assignment (it's a bit longer). The issue is that it compiles in CodeBlocks but it does not compile in Visual Studio 2017 it says - binary '=': no operator found which takes a right-hand operand of type 'CAutomobile' (or there is no acceptable conversion.
I would like to ask why is that because I could not myself find the error? I tried commenting the operator =function but still the error remained.
#include <iostream>
#include <algorithm>
#include <string>
#include <stdlib.h>
using namespace std;
class CVehicle {
string name;
int year;
public:
CVehicle() {
name = "Car";
year = 1990;
}
CVehicle(string n, int y) {
name = n;
year = y;
}
CVehicle(const CVehicle& vc) {
name = vc.name;
year = vc.year;
}
void setName(string n) {
name = n;
}
void setYear(int y) {
year = y;
}
string getName() {
return name;
}
int& getYear() {
return year;
}
virtual void Print(ostream& os) = 0;
};
class CAutomobile :public CVehicle {
double litres;
public:
CAutomobile() :CVehicle() {
litres = 7.2;
}
CAutomobile(string nm, int yr, double l) :CVehicle(nm, yr) {
litres = l;
}
void setLitres(double l) {
l = litres;
}
double& getLitres() {
return litres;
}
void Print(ostream& os) override {
os << getName() << endl;
os << getYear() << endl;
os << litres << endl;
}
friend bool operator< (CAutomobile a1, CAutomobile a2) {
if (a1.litres < a2.litres) {
return true;
}
return false;
}
CAutomobile operator= (CAutomobile& at) {
CAutomobile au;
au.getName() = at.getName();
au.getYear() = at.getYear();
au.getLitres() = at.getLitres();
return au;
}
CAutomobile operator+(CAutomobile aut) {
CAutomobile a;
a.getLitres() = getLitres() + aut.getLitres();
return a;
}
friend ostream& operator<< (ostream& o, CAutomobile a) {
o << a.getName() << endl;
o << a.getYear() << endl;
o << a.getLitres() << endl;
return o;
}
};
int main()
{
CAutomobile a[] = {
CAutomobile(),
CAutomobile("Wolkswagen",1970,80.5),
CAutomobile("Fiat",1979,21.9),
CAutomobile("Opel",1978,13.7)
};
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) {
cout << "Name" << ' ' << a[i].getName() << endl;
cout << "Year" << ' ' << a[i].getYear() << endl;
cout << "Litres" << ' ' << a[i].getLitres() << endl;
}
int range = 2016 - 1990 + 1;
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) {
a[i].setLitres(rand() % 100 + 1);
a[i].setYear(rand() % range + 1996);
}
//сортираме масива по литри и извеждаме
//най малкия (първия) му елемент
for (int i = 0; i < sizeof(a-1); i++) {
for (int j = 0; j < sizeof(a-1); j++) {
if (a[j].getLitres() > a[j + 1].getLitres()) {
swap(a[j], a[j + 1]);
}
}
}
cout << a[0] << endl;
CAutomobile k = a[0] + a[3];
cout << k.getLitres() << endl;
}
CAutomobile::operator = is completely wrong. It takes a non-const reference and assignes its field to a new object. Instead it should take a const reference and modify current object.
CAutomobile & operator =(CAutomobile const & other)
{
assert(this != ::std::addressof(other)); // check for self-assignment
SetName(other.getName());
SetYear(other.getYear());
SetLitres(other.getLitres());
return *this;
}
This will bring up another problem: getters are not const-qualified, so they should be fixes as well:
string const & getName(void) const {
return name;
}
int const & getYear(void) const {
return year;
}

Minimax algorithm for Specker Game

I am creating an minimax player for a game called Specker in c++.
The rules are simple:
There are p players (0 to p - 1) and n heaps (0 to n - 1)
Starting with player 0 each player takes k > 0 coins from a heap x and places m coins (0 <= m < k) on heap y
The winning player is the one which plays last when all coins from all heaps are removed
So I have created the game and some player classes (GreedyPlayer, SpartanPlayer etc.) but they all are a little bit predictable on what they will do. They aren't clever.
so i am creating a player who plays according to minimax (pt18a038)code compiles fine but the program stops responding on execution.
the clever player class:
class pt18a038 : public Player {
private:
string player_type;
public:
pt18a038(const string &n) : Player(n) {
player_type = "Asder aka theRunner";
}
virtual const string &getType() const override {
return player_type;
}
virtual Move play(const State &s) override {
int source_heap = 0;
int target_heap = 0;
int source_coins = 0;
int target_coins = 0;
int sum = 0;
for (source_heap = 0; source_heap < s.getHeaps(); source_heap++) {
for (source_coins = 1; source_coins <= s.getCoins(source_heap); source_coins++) {
for (target_heap = 0; target_heap < s.getHeaps(); target_heap++) {
for (target_coins = 0; target_coins <= source_coins; target_coins++) {
Move m(source_heap, source_coins, target_heap, target_coins);
sum = minimax(s, 3, 0, m);
cout << "Play:" << source_heap << "," << source_coins << "," << target_heap << ","
<< target_coins << ":" << sum << endl;
}
}
}
}
cout << sum << endl;
// ///////////// for debbuging only until minimax is working...
source_heap = 0;
source_coins = 0;
for (int i = 0; i < s.getHeaps(); i++) {
if (s.getCoins(i) > source_coins) {
source_heap = i;
source_coins = s.getCoins(i);
}
}
Move SpartanObject(source_heap, 1, 0, 0);
return SpartanObject;
// /////////////
}
static int minimax(State s, const int &players, int depth, const Move move) {
if (s.winning()) {
cout << "game end!" << endl;
return 1000;
if (depth % players == 0) return 1000; //Maximazing player
else return -1000; //Minimazing player
}
if (depth > 4) {
//cout<<"optimazing"<<endl;
return 0;
}
//cout << s << endl;
s.next(move);
int source_heap = 0;
int target_heap = 0;
int source_coins = 0;
int target_coins = 0;
int max = -100000;
int min = 100000;
int result;
for (source_heap = 0; source_heap < s.getHeaps(); source_heap++) {
for (source_coins = 1; source_coins <= s.getCoins(source_heap); source_coins++) {
for (target_heap = 0; target_heap < s.getHeaps(); target_heap++) {
for (target_coins = 0; target_coins <= source_coins; target_coins++) {
//cout << "Move:" << source_heap << "," << source_coins << "," << target_heap << ","<< target_coins << endl;
Move m(source_heap, source_coins, target_heap, target_coins);
result = minimax(s, players, depth + 1, m);
if (depth % players == 0) {
max = result ? (result > max) : result;
} else {
min = result ? (result < min) : result;
}
}
}
}
}
return max ? (depth % players == 0) : min;
}
};
Here is my code for the rest of the game(it's tested and works fine)
#include <iostream>
#include <stdexcept>
using namespace std;
class Move {
private:
int source_heap, source_coins, target_heap, target_coins;
public:
Move(int sh, int sc, int th, int tc) {
source_heap = sh;
source_coins = sc;
target_heap = th;
target_coins = tc;
}
int getSource() const {
return source_heap;
}
int getSourceCoins() const {
return source_coins;
}
int getTarget() const {
return target_heap;
}
int getTargetCoins() const {
return target_coins;
}
// Let's do some operator overloading
friend ostream &operator<<(ostream &out, const Move &move) {
if (move.getTargetCoins()) {
out << "takes " << move.getSourceCoins() << " coins from heap "
<< move.getSource() << " and puts " << move.getTargetCoins()
<< " coins to heap " << move.getTarget();
} else {
out << "takes " << move.getSourceCoins() << " coins from heap "
<< move.getSource() << " and puts nothing";
}
}
};
class State {
// State with h heaps, where the i-th heap starts with c[i] coins.
private:
int heaps, *heap_coins;
public:
State(int h, const int c[]) {
heaps = h;
heap_coins = new int[heaps];
for (int i = 0; i < heaps; i++)
heap_coins[i] = c[i];
}
~State() {
delete[] heap_coins;
return;
}
int getCoins(int h) const throw(logic_error) {
if (h < 0 || h > heaps) {
throw logic_error(
"Invalid heap number, enter a number between 1 and heaps!");
return 1;
} else {
return heap_coins[h];
}
}
void next(const Move &move) throw(logic_error) {
if ((move.getSource() < 0) || (move.getSource() > heaps) ||
(move.getTarget() < 0) || (move.getTarget() > heaps)) {
throw logic_error("Invalid Heap!");
return;
} else if (
(move.getSourceCoins() < 1) || (move.getTargetCoins() < 0) ||
(move.getSourceCoins() <= move.getTargetCoins()) ||
(move.getSourceCoins() > getCoins(move.getSource()))) {
throw logic_error("Invalid Coin number!");
} else {
heap_coins[move.getSource()] -= move.getSourceCoins();
heap_coins[move.getTarget()] += move.getTargetCoins();
}
}
bool winning() const {
int s = 0;
for (int i = 0; i < heaps; i++)
s += getCoins(i);
return not s; // yeah i know how booleans work :P
}
int getHeaps() const {
return heaps;
}
friend ostream &operator<<(ostream &out, const State &state) {
for (int i = 0; i < state.getHeaps(); i++) {
out << state.heap_coins[i];
if (i != state.getHeaps() - 1)
out << ", ";
}
return out;
}
};
class Player {
public:
Player(const string &n);
virtual ~Player();
virtual const string &getType() const = 0;
virtual Move play(const State &s) = 0;
friend ostream &operator<<(ostream &out, const Player &player);
protected:
string player_name;
};
class GreedyPlayer : public Player {
private:
string player_type;
public:
GreedyPlayer(const string &n) : Player(n) {
player_type = "Greedy";
}
virtual const string &getType() const override {
return player_type;
}
virtual Move play(const State &s) override {
int source_heap = 0;
int source_coins = 0;
for (int i = 0; i < s.getHeaps(); i++) {
if (s.getCoins(i) > source_coins) {
source_heap = i;
source_coins = s.getCoins(i);
}
}
Move GreedyObject(source_heap, source_coins, 0, 0);
return GreedyObject;
}
};
class SpartanPlayer : public Player {
public:
SpartanPlayer(const string &n) : Player(n) {
player_type = "Spartan";
}
virtual const string &getType() const override {
return player_type;
}
virtual Move play(const State &s) override {
int source_heap = 0;
int source_coins = 0;
for (int i = 0; i < s.getHeaps(); i++) {
if (s.getCoins(i) > source_coins) {
source_heap = i;
source_coins = s.getCoins(i);
}
}
Move SpartanObject(source_heap, 1, 0, 0);
return SpartanObject;
}
private:
string player_type;
};
class SneakyPlayer : public Player {
public:
SneakyPlayer(const string &n) : Player(n) {
player_type = "Sneaky";
}
virtual const string &getType() const override {
return player_type;
}
virtual Move play(const State &s) override {
int j = 0;
while (s.getCoins(j) == 0) {
j++;
}
int source_heap = j;
int source_coins = s.getCoins(j);
for (int i = j + 1; i < s.getHeaps(); i++) {
if ((s.getCoins(i) < source_coins) && (s.getCoins(i) > 0)) {
source_heap = i;
source_coins = s.getCoins(i);
}
}
Move SneakyObject(source_heap, source_coins, 0, 0);
return SneakyObject;
}
private:
string player_type;
};
class RighteousPlayer : public Player {
public:
RighteousPlayer(const string &n) : Player(n) {
player_type = "Righteous";
}
virtual const string &getType() const override {
return player_type;
}
virtual Move play(const State &s) override {
int target_heap = 0;
int source_heap = 0;
int source_coins = s.getCoins(0);
int target_coins = source_coins;
for (int i = 1; i < s.getHeaps(); i++) {
if (s.getCoins(i) > source_coins) {
source_heap = i;
source_coins = s.getCoins(i);
} else if (s.getCoins(i) < target_coins) {
target_heap = i;
target_coins = s.getCoins(i);
}
}
source_coins -= source_coins / 2;
Move RighteousObject(
source_heap, source_coins, target_heap, source_coins - 1);
return RighteousObject;
}
private:
string player_type;
};
Player::Player(const string &n) {
player_name = n;
}
Player::~Player() {
player_name.clear();
}
ostream &operator<<(ostream &out, const Player &player) {
out << player.getType() << " player " << player.player_name;
return out;
}
class Game {
private:
int game_heaps, game_players, current_heap, current_player;
int *heap_coins;
Player **players_list;
public:
Game(int heaps, int players) {
heap_coins= new int [heaps];
game_heaps = heaps;
game_players = players;
current_heap = 0;
current_player = 0;
players_list = new Player*[players];
}
~Game() {
delete[] heap_coins;
delete[] players_list;
}
void addHeap(int coins) throw(logic_error) {
if (current_heap > game_heaps)
throw logic_error("All heaps are full with coins!");
else if (coins < 0)
throw logic_error("Coins must be a positive number!");
else {
heap_coins[current_heap++] = coins;
}
}
void addPlayer(Player *player) throw(logic_error) {
if (current_player > game_players)
throw logic_error("All players are added!");
else {
players_list[current_player++] = player;
}
}
void play(ostream &out) throw(logic_error) {
if ((current_player != game_players) && (current_heap != game_heaps)) {
throw logic_error("Have you added all heaps and players?");
} else {
int i = 0;
State currentState(game_heaps, heap_coins);
while (!currentState.winning()) {
out << "State: " << currentState << endl;
out << *players_list[i % game_players] << " "
<< players_list[i % game_players]->play(currentState) << endl;
currentState.next(
players_list[i % game_players]->play(currentState));
i++;
}
out << "State: " << currentState << endl;
i--;
out << *players_list[i % game_players] << " wins" << endl;
}
}
};
int main() {
Game specker(6, 5);
specker.addHeap(10);
specker.addHeap(20);
specker.addHeap(17);
specker.addHeap(17);
specker.addHeap(17);
specker.addHeap(17);
specker.addPlayer(new GreedyPlayer("Alan"));
specker.addPlayer(new SneakyPlayer("Tom"));
specker.addPlayer(new SpartanPlayer("Mary"));
specker.addPlayer(new RighteousPlayer("Robin"));
specker.addPlayer(new pt18a038("Stavros"));
specker.play(cout);
}
Updated
I see a couple of issues in your minimax program, some are serious in nature :
1) Use Alpha Beta pruning to reduce the size of the search tree.
2) There is no proper boundary condition (if depth >5 return score or something) in the minimax recursive call ( see my code snippet for details), the CPU may hang while calling.
3)Your leaf node evaluation is weak, so the evaluated moves , in spite of using minimax algorithm, is not likely to be intelligent ones.
4)To increase the search speed, you may use multi-threading only at the top level branch.
5) If a leaf node gives a winning move while maximizing, you may skip further evaluation by returning a high score.
6) Once your code is functional, refer it at code-review with 'ai' tag , rather than at SO, for more detailed analysis.
int EvaluateLeafNode(State s, const int &players)
{
//TODO analyze here
return score;
}
int minimax(State s, const int &players, int depth , const Move move, int alpha, int beta)
{
if( depth >= 5) return EvaluateLeafNode(s,players); // this was missing in your code
//don't analyze here
//rest of minimax recursive code
}

Creating a deck of Cards

Okay, first off I have looked at various of the questions that were asked about creating a deck of Cards but every single one I looked was using the vector thing, I'm not sure how to write it, cause I have not taken that subject in class so I don't know how to apply it.
The Card.H and Card.cpp are all fine, no need to change a thing in them
I need help in Deck.H and Deck.cpp.
My initialize() function is not finished and I cant seem to know how to finish it and with the other methods in the Deck class I have not tried to write any of them since I cant generate a deck of cards.
CARD.H
Class Card
{
int m_face;
char m_suit;
public:
Card(int _face = 2 , char _suit = 3);
~Card();
int GetFace() const;
char GetSuit() const;
void SetFace(int _face);
void SetSuit(char _suit);
void Show() const;
}
CARD.CPP
#include "Card.h"
Card::Card(int _face, char _suit)
{
m_face = _face;
m_suit = _suit;
}
Card::~Card()
{
}
int Card ::GetFace() const
{
return m_face;
}
char Card ::GetSuit() const
{
return m_suit;
}
void Card::SetFace(int _face)
{
m_face = _face;
}
void Card::SetSuit(char _suit)
{
m_suit = _suit;
}
void Card::Show() const
{
if (m_face == 11)
cout << " J " << m_suit << endl;
else if (m_face == 12)
cout << " Q " << m_suit << endl;
else if (m_face == 13)
cout << " K " << m_suit << endl;
else if (m_face == 14)
cout << " A " << m_suit << endl;
else
cout << m_face << m_suit << endl;
}
DECK.H
#pragma once
#include "stdafx.h"
#include "Card.h"
Class Deck
{
Card m_cards[52];
public:
Deck();
void Initialize();
void Shuffle();
bool Draw(Card& _card);
void Clear();
bool IsEmpty() const;
}
DECK.CPP
#include "Deck.h"
#include"Card.h"
void Deck::Initialize()
{
int count = 0;
char Suits[] = { 3, 4, 5, 6 };
for (int i = 0; i < 4; ++i) //Suits
{
for (int F = 2; F < 14; ++F) //faces
{
m_cards[count].SetSuit(Suits[i]);
m_cards[count].SetFace(F);
}
}
}
void Deck::Shuffle()
{
}
bool Deck::Draw(Card& _card
{
}
void Deck::Clear()
{
}
bool Deck::IsEmpty() const
{
}
I don't think your Initialize function needs much more work.
Only 2 remarks:
You forgot a ++count at the end of the inner for loop (now you're setting the same card every time).
As you wrote the inner for loop, the F variable will only be allowed to go up to 13 (because you used < 14). This means your deck won't contain any aces ... most logical thing for me would be to use <= 14 instead.
A little tweaking and it works.
#include <iostream>
#include <algorithm>
using namespace std;
class Card
{
private:
int m_face;
char m_suit;
public:
Card(int _face = 2 , char _suit = 3)
{
m_face = _face;
m_suit = _suit;
}
~Card(){}
int GetFace() const { return m_face; }
char GetSuit() const { return m_suit; }
void SetFace(int _face) { m_face = _face; }
void SetSuit(char _suit) { m_suit = _suit; }
void Show() const
{
if (m_face == 11)
cout << " J " << m_suit << endl;
else if (m_face == 12)
cout << " Q " << m_suit << endl;
else if (m_face == 13)
cout << " K " << m_suit << endl;
else if (m_face == 14)
cout << " A " << m_suit << endl;
else
cout << m_face << m_suit << endl;
}
};
class Deck
{
private:
Card m_cards[52];
int current;
public:
Deck() { Initialize(); }
void Initialize()
{
current = 51;
int count = 0;
char Suits[] = { 3, 4, 5, 6 };
for (int i = 0; i < 4; ++i) //Suits
{
for (int F = 2; F <= 14; ++F) //faces
{
m_cards[count++].SetSuit(Suits[i]);
m_cards[count++].SetFace(F);
}
}
}
void Shuffle() { std::random_shuffle(m_cards, m_cards + current + 1); }
bool Draw(Card& _card)
{
if (IsEmpty()) return false;
_card = m_cards[current--];
return true;
}
void Clear() { current = -1; }
bool IsEmpty() const { return current < 0; }
};
int main()
{
Deck deck;
while(!deck.IsEmpty())
{
Card c;
deck.Draw(c);
c.Show();
}
return 0;
}