Its a card game, I draw 2 cards from the deck (the array) with the help of two functions.
Each element of the array represent one card with a symbol Spades, Hearts, Diamonds or Clubs.
These numbers in the array \5 \4 \3 \6, represent Clubs, Dimaond, Heatrs, spades (just if ur curious)
The problem!
When I draw a card two times I sometimes get Duplicates.. The same card twice.
How do I make sure the same card cant be drawn twice?
How do I avoid getting duplicates??
This is how the code Looks like.
Some INFO about the array...
The further in, in the array, the higher value the element has.
I have shortened the array... for easy testing of a solution... later the array will be 52 elements.
array<string, 3> cards = { "Ess \5", "Ess \4", "Ess \3" };
//The function.
pair<string, int> draw_card()
{
int random_index = rand() % 52;
string card = cards[random_index];
return { card, random_index };
}
int main()
{
// Seed, random.
srand((unsigned int)time(NULL));
// Calling the function 2 times.
pair<string, int> you_drew = draw_card();
cout << "You drew: " << you_drew.first << endl;
pair<string, int> comp_drew = draw_card();
cout << "Computer drew: " << comp_drew.first << endl;
// Deciding the winner.
int your_score{ 0 };
int the_computers_score{ 0 };
if (you_drew.second > comp_drew.second) {
cout << "You Won!" << endl;
your_score++;
}
else if (you_drew.second < comp_drew.second) {
cout << "You Lost!" << endl;
the_computers_score++;
}
return 0;
}
Everything is working fine, EXCEPT sometimes I get duplicates... I want to make sure I can Not get that...
Somehow when I draw a card the element in the array should not be able to be drawn.. I want to avoid getting duplicates. Please help me!
Shouldnt something like this work? its not but.. shouldnt it?
pair<string, int> comp_drew = draw_card();
if (you_drew == comp_drew) {
bool run8 = true;
while (run8) {
pair<string, int> comp_drew = draw_card();
if (comp_drew != you_drew) {
cout << "Computer drew: " << comp_drew.first << endl;
run8 = false;
}
}
}
Or maybe another solution..
Perhaps after calling the function one time i can delete the return index from the array?
You can swap the drawn card to the end and only choose an index smaller than 51 the next time.
int array_len = 52; // global variables are not great, but it's easier here
pair<string, int> draw_card()
{
int random_index = rand() % array_len;
--array_len;
string card = cards[random_index];
std::swap(cards[random_index], cards[array_len]);
return { card, random_index };
}
There are many different ways to do this.
std::random_shuffle
#include <iostream>
#include <algorithm>
using namespace std;
class CardMachine {
static unsigned constexpr DECK_SIZE = 4;
int cards[DECK_SIZE] = {1,2,3,4};
int lastUsedCardIndex = -1;
public:
int getCard() {
if (lastUsedCardIndex == DECK_SIZE - 1)
shuffle();
return cards[++lastUsedCardIndex];
}
void shuffle() {
random_shuffle(begin(cards), end(cards));
}
};
int main()
{
CardMachine cardMachine = CardMachine();
cout << "unhsuffled - 1,2,3,4 without duplicates:" << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << "Shuffled. Random order, and still no duplicates:" << endl;
cardMachine.shuffle(); // or call getCard which can shuffle
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
return EXIT_SUCCESS;
}
Mark Card as Taken
#include <iostream>
#include <random>
using namespace std;
class CardMachine {
static unsigned constexpr DECK_SIZE = 4;
inline static int constexpr cards[DECK_SIZE] = {1,2,3,4};
bool cardIsGone[DECK_SIZE] = {false, false, false, false};
public:
int getCard() {
while(true) {
int const RANDOM_INDEX = rand()%DECK_SIZE;
if(!cardIsGone[RANDOM_INDEX]) {
cardIsGone[RANDOM_INDEX] = true;
return cards[RANDOM_INDEX];
}
}
}
void shuffle() {
for(bool &isGone : cardIsGone)
isGone = false;
lastUsedCardIndex = -1;
}
};
int main()
{
CardMachine cardMachine = CardMachine();
cout << "Shuffled - Random order, and still no duplicates:" << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << "Shuffled. Random order, and still no duplicates:" << endl;
cardMachine.shuffle(); // Causes infinite loop if you call getCard DECK_SIZE + 1 times
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
return EXIT_SUCCESS;
}
It's not the most efficient solution, but with small values like 52, it should be instant.
Swap Used Cards to Back and Keep Track of Range
#include <iostream>
#include <random>
using namespace std;
class CardMachine {
static unsigned constexpr DECK_SIZE = 4;
int cards[DECK_SIZE] = {1,2,3,4};
int lastCardIndexExlusive = DECK_SIZE;
public:
int getCard() {
int const RANDOM_INDEX = rand()%lastCardIndexExlusive;
swap(cards[RANDOM_INDEX],cards[lastCardIndexExlusive - 1]);
return cards[--lastCardIndexExlusive];
}
void shuffle() {
lastCardIndexExlusive = DECK_SIZE;
}
};
int main()
{
CardMachine cardMachine = CardMachine();
cout << "Shuffled - Random order, and still no duplicates:" << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << "Shuffled. Random order, and still no duplicates:" << endl;
cardMachine.shuffle(); // Causes exception if getCard DECK_SIZE + 1 times
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
return EXIT_SUCCESS;
}
Remember Last Card
#include <iostream>
#include <random>
using namespace std;
class CardMachine {
static unsigned constexpr DECK_SIZE = 4;
int cards[DECK_SIZE] = {1,2,3,4};
int lastCard = -1;
public:
int getCard() {
int const RANDOM_INDEX = rand()%DECK_SIZE;
if (lastCard == RANDOM_INDEX) {
return getCard();
}
lastCard = cards[RANDOM_INDEX];
return lastCard;
}
void shuffle() {
lastCard = -1;
}
};
int main()
{
CardMachine cardMachine = CardMachine();
cout << "Shuffled - Random order, and still no duplicates, but only able to produce 2:" << endl;
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
cout << "Shuffled. Random order, and still no duplicates:" << endl;
cardMachine.shuffle(); // Causes potential duplicates if getCards 3+ times
cout << cardMachine.getCard() << endl;
cout << cardMachine.getCard() << endl;
return EXIT_SUCCESS;
}
All of these solutions make use of a class to hold state for use in getCard to make sure we get the right behavior.
I am posting my code below as tested, with the respective outputs shown in comments after the "cout"-statements, and my QUESTIONS as to the output that I do not understand indicated by "--> WHY". I am completely at a loss and I apologize in advance for my assumed stupidity that appears to prevent me from understanding what is going on.
#include <experimental/filesystem>
#include <iostream>
#include <vector>
using namespace std;
struct S
{
struct BASE
{
static double testval;
virtual void set_testval(double val) {testval = val;}
virtual double get_testval() {return testval;}
};
template<typename T>
struct DerivedTemplate : public BASE
{
static double testval;
void set_testval(double val) {testval = val;}
double get_testval() {return testval;}
};
struct DERIVED_01 : DerivedTemplate<DERIVED_01>
{
//...
};
struct DERIVED_02 : DerivedTemplate<DERIVED_02>
{
//...
};
struct DERIVED_03 : DerivedTemplate<DERIVED_03>
{
//...
};
vector<unique_ptr<BASE> > DERIVED_TYPES;
S();
}; // END struct S
S::S()
{
DERIVED_TYPES.resize(4);
}
double S::BASE::testval = 0;
template <typename T>
double S::DerivedTemplate<T>::testval = 1;
S s;
int main()
{
// Assign pointers to objects of derived structs to fields in vector of unique_ptr of base struct
{
unique_ptr<S::DERIVED_01> DERIVED (new S::DERIVED_01());
s.DERIVED_TYPES[0] = move(DERIVED);
}
{
unique_ptr<S::DERIVED_02> DERIVED (new S::DERIVED_02());
s.DERIVED_TYPES[1] = move(DERIVED);
}
{
unique_ptr<S::BASE> BASE (new S::BASE());
s.DERIVED_TYPES[2] = move(BASE);
}
{
unique_ptr<S::DERIVED_03> DERIVED (new S::DERIVED_03());
s.DERIVED_TYPES[3] = move(DERIVED);
}
cout << s.DERIVED_TYPES[0]->testval << endl; // Output: 0
cout << s.DERIVED_TYPES[0]->get_testval() << endl; // Output: 1 --> WHY is the output of this line "1" while that of the prior line was "0"?
// I assumed to be accessing the same member variable of the same object in both cases
cout << endl;
cout << s.DERIVED_TYPES[1]->testval << endl; // Output: 0
cout << s.DERIVED_TYPES[1]->get_testval() << endl; // Output: 1 --> WHY [same question]
cout << endl;
cout << s.DERIVED_TYPES[2]->testval << endl; // Output: 0
cout << s.DERIVED_TYPES[2]->get_testval() << endl; // Output: 0
cout << endl;
cout << s.DERIVED_TYPES[3]->testval << endl; // Output: 0
cout << s.DERIVED_TYPES[3]->get_testval() << endl; // Output: 1 --> WHY [same question]
cout << endl;
// Assign values to static member variables of derived struct objects
s.DERIVED_TYPES[0]->testval = 0.5;
s.DERIVED_TYPES[1]->testval = 1.5;
s.DERIVED_TYPES[2]->testval = 2.5;
s.DERIVED_TYPES[3]->testval = 2.75;
cout << s.DERIVED_TYPES[0]->testval << endl; // Output: 2.75
cout << s.DERIVED_TYPES[1]->testval << endl; // Output: 2.75
cout << s.DERIVED_TYPES[2]->testval << endl; // Output: 2.75
cout << s.DERIVED_TYPES[3]->testval << endl; // Output: 2.75 --> WHY are the outputs all "2.75"?
cout << endl;
s.DERIVED_TYPES[0]->set_testval(3.5);
s.DERIVED_TYPES[1]->set_testval(4.5);
s.DERIVED_TYPES[2]->set_testval(5.5);
s.DERIVED_TYPES[3]->set_testval(6.5);
cout << s.DERIVED_TYPES[0]->testval << endl; // Output: 5.5
cout << s.DERIVED_TYPES[0]->get_testval() << endl; // Output: 3.5
cout << endl;
cout << s.DERIVED_TYPES[1]->testval << endl; // Output: 5.5
cout << s.DERIVED_TYPES[1]->get_testval() << endl; // Output: 4.5
cout << endl;
cout << s.DERIVED_TYPES[2]->testval << endl; // Output: 5.5
cout << s.DERIVED_TYPES[2]->get_testval() << endl; // Output: 5.5
cout << endl;
cout << s.DERIVED_TYPES[3]->testval << endl; // Output: 5.5
cout << s.DERIVED_TYPES[3]->get_testval() << endl; // Output: 6.5
// Now, a "DIRECT ACCESS" of "testval" [s.DERIVED_TYPES[x]->testval]
// does not produce an output equal to the value assigned to
// s.DERIVED_TYPES[3]->testval, the last one assigned, but an
// output equal to the one assigned to the pointer pointing to the
// one object of struct BASE instead of "DERIVED_..."
// --> WHY?
cin.get();
return 0;
}
my english not good ,sorry.
clion class variable not initialized why appear z =16
and vs2019 situation not same
#include <iostream>
using namespace std;
class bas {
public:
int showget();
private:
int x, z, y;
};
int main() {
bas B;
B.showget();
return 0;
}
int bas::showget() {
cout << x << " " << " " << z << " " << y << "\n";
int *t;
t = &x;
cout << t<<"\n";
t = &y;
cout << t<< "\n";
t = &z;
cout << t;
return 0;
}
}
}
enter image description here
How do I access the y (which is inside namespace n2), from n1 namespace:
The test code is below:
#include<iostream>
using namespace std;
namespace n1
{
int x = 20;
int m = ::n2::y;
void printx()
{
cout << "n1::x is " << x << endl;
cout << "n2::y is " << m << endl;
}
}
namespace n2
{
int y = 10;
}
int main()
{
cout << n1::x << endl;
n1::printx();
cout << n2::y << endl;
return 0;
}
I am getting below error:
test.cpp:7:15: error: ‘::n2’ has not been declared
int m = ::n2::y;
Just change the order, so that n2 is resolvable inside n1 :
#include<iostream>
using namespace std;
namespace n2
{
int y = 10;
}
namespace n1
{
int x = 20;
int m = n2::y;
void printx()
{
cout << "n1::x is " << x << endl;
cout << "n2::y is " << m << endl;
}
}
int main()
{
cout << n1::x << endl;
n1::printx();
cout << n2::y << endl;
return 0;
}
I am asked to do this code and i need to use array or something similar to print out different classes. The only way i know is individually doing every single class is there a faster way of doing this. Following is the way i am using at the moment.
Ground_Transport Gobj;
Air_Transport Aobj;
Sea_Transport Sobj;
Car Cobj;
Train Tobj;
Bus Bobj;
Gobj.estimate_time();
Gobj.estimate_cost();
cout << Gobj.getName() << endl;
Bobj.estimate_time();
Bobj.estimate_cost();
cout << Bobj.getName() << endl;
Sobj.estimate_time();
Sobj.estimate_cost();
cout<<Sobj.getName()<<endl;
Aobj.estimate_time();
Aobj.estimate_cost();
cout << Aobj.getName() << endl;
Cobj.estimate_time();
Cobj.estimate_cost();
cout << Cobj.getName() << endl;
Tobj.estimate_time();
Tobj.estimate_cost();
cout << Tobj.getName() << endl;
Transport_KL_Penang Kobj;
cout << Kobj.getName() << endl;
This is the header file Transport_KL_Penang
#include <iostream>
#include <string>
using namespace std;
class Transport_KL_Penang
{
public:
Transport_KL_Penang() {}
virtual string getName() {
return Name;
}
int Time_in_hours1 ;
int Time_in_hours2 ;
int Cost_in_RM1 ;
int Cost_in_RM2 ;
void estimate_time() ;
void estimate_cost() ;
private:
static string Name;
};
void Transport_KL_Penang::estimate_time()
{
cout << "It takes " << Time_in_hours1 << "-" << Time_in_hours2 <<
" hours if you use " << Name << endl;
}
void Transport_KL_Penang::estimate_cost()
{
cout << "It will cost around " << Cost_in_RM1 << "-" << Cost_in_RM2 <<
"RM if you use " << Name << endl;
}
If you don't need a specific object name, you can write something as a code below, creating a multiples generics objects:
#include <iostream>
#include <cstdlib>
#include <time.h>
class Myclass {
private:
int randTime;
float cost;
public:
void estimate_time(){
randTime = rand()%100;
}
void estimate_cost(){
cost = randTime * 0.2;
}
float getEstimateCost(){
return cost;
}
};
int main(){
srand(time(NULL));
int numberOfObjects = 7;
Myclass obj[numberOfObjects];
//input
for(int i = 0; i < numberOfObjects; i++){
obj[i].estimate_time();
obj[i].estimate_cost();
}
// printing
for(int i = 0; i < numberOfObjects; i++){
std::cout << obj[i].getEstimateCost() << std::endl;
}
return 0;
}