Converting from python to C++ help

So for my final you have to make a class with various card methods, but I have already made the program last semester but in Python. So I'm just going to rewrite it all in C++, however I need some help on a few things. My biggest area of concerns are the methods in the class, as it involves array syntax I don't know how I should write in C++. Also unsure about all the (self), and the __.

My original Python code:

#This is a class that contains methods for various card game actions. Methods include
#resetting, shuffling, and cutting decks.


class deck:
#Constructor
def __init__(self):
self.__cards = []
self.resetdeck()

#Method that resets the deck
def resetdeck(self):
del self.__cards[0:]
for suit in range(1,5):
for value in range(1,14):
self.__cards.append(str(value)+"|"+str(suit))

#Method that shuffles the deck
def shuffle(self):
random.shuffle(self.__cards)

#Method that cuts the deck
def cutdeck(self):
cutdeck1 = self.__cards[:26]
cutdeck2 = self.__cards[26:]
self.__cards = cutdeck2 + cutdeck1

#Method that cuts to a card
def cuttocard(self):
self.cutdeck()
print self.__cards[-1]

#Method that both CPU and user cut to card and highest card wins
def cutCPU(self):
playerTop = self.__cards[-1]
del self.__cards[-1]
compTop = self.__cards[-1]
del self.__cards[-1]
print "Player", "Computer"
print ""
print playerTop," ", compTop

#Method that returns the cards
def get_cards(self):
return self.__cards

#This program gives the user a choice of various actions to be performed with a deck of cards
#Uses the class designed above.


import random

def main():
getcard = deck()
menuloop = 1
#Loop for actions until user decides to exit
while menuloop == 1:
print ""
print "1. Reset the deck"
print "2. Shuffle the deck"
print "3. Cut the deck"
print "4. Cut to a card"
print "5. Cut against the computer"
print "6. Exit the program"
print ""
uM = input("Select a menu option(#): ")
print ""
if uM == 1:
getcard.resetdeck()
print getcard.get_cards()

if uM == 2:
getcard.shuffle()
print getcard.get_cards()

if uM == 3:
getcard.cutdeck()
print getcard.get_cards()

if uM == 4:
getcard.cuttocard()

if uM == 5:
getcard.cutCPU()

#Exit option, ends loop
if uM == 6:
print "BYE"
menuloop = 0

#Secret option, used to show cards
if uM == 7:
print getcard.get_cards()

#Defensive if statement, only accepts #'s 1-7
if uM != 1 and uM != 2 and uM != 3 and uM != 4 and uM != 5 and uM != 6 and uM != 7:
print "Wrong input entered"

main()




And what I have so far:

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
//This is a class that contains methods for various card game actions. Methods include
//resetting, shuffling, and cutting decks.


#include <iostream>
#include <random>;
using namespace std;

class deck {
public:
    //Constructor
    deck() {
        self.__cards = [];
		self.resetdeck(); }

    //Method that resets the deck
    int resetdeck() {
        del self.__cards[0:];
        for suit in range(1,5):
            for value in range(1,14):
			self.__cards.append(str(value)+"|"+str(suit)); }
               
    //Method that shuffles the deck
    int shuffle() {
		random.shuffle(self.__cards); }

    //Method that cuts the deck    
    int cutdeck() {
        cutdeck1 = self.__cards[:26];
        cutdeck2 = self.__cards[26:];
		self.__cards = cutdeck2 + cutdeck1; }
        
    //Method that cuts to a card
    int cuttocard() {
        self.cutdeck();
			cout << self.__cards[-1]; }

    //Method that both CPU and user cut to card and highest card wins
    int cutCPU() {
        playerTop = self.__cards[-1];
        del self.__cards[-1];
        compTop = self.__cards[-1];
        del self.__cards[-1];
        cout << "Player", "Computer";
        cout << "";
		cout << playerTop," ", compTop; }
            
    //Method that returns the cards
    int get_cards() {
		return self.__cards; }
}
//This program gives the user a choice of various actions to be performed with a deck of cards
//Uses the class designed above.

    


int main() 
{
    deck getcard;
    int menuloop = 1;
	int uM;
    //Loop for actions until user decides to exit
    while (menuloop == 1)
	{
        cout << "";
        cout << "1. Reset the deck";
        cout << "2. Shuffle the deck";
        cout << "3. Cut the deck";
        cout << "4. Cut to a card";
        cout << "5. Cut against the computer";
        cout << "6. Exit the program";
        cout << "";
		cout << "Select a menu option(#): ";
        cin >> uM;
        cout << "";
        if (uM == 1) {
            getcard.resetdeck();
				cout << getcard.get_cards(); }
            
        if (uM == 2) {
            getcard.shuffle();
				cout << getcard.get_cards(); }

        if (uM == 3) {
            getcard.cutdeck();
				cout << getcard.get_cards(); }

        if (uM == 4)
            getcard.cuttocard();

        if (uM == 5)
            getcard.cutCPU();

        //Exit option, ends loop
        if (uM == 6) { 
            cout << "BYE";
				menuloop = 0; }

        //Secret option, used to show cards
        if (uM == 7)
            cout << getcard.get_cards();

        //Defensive if statement, only accepts #'s 1-7
        if (uM != 1 && uM != 2 && uM != 3 && uM != 4 && uM != 5 && uM != 6 && uM != 7)
            cout << "Wrong input entered";
    
	}
}
    
Last edited on
I don't know much about python, but I'm guessing that self is similar to this in c++ and that you are trying to access a local member of the class.

Replace self. everywhere in this code with this->. That is the C++ equivalent. However, you could also just delete self. which is more common in C++ as member objects are automatically within scope everywhere in the class (as long as they are declared!).

As for __cards, you need to define that as a private object in the class. Why private? Because you already have get_cards() to access it by the outside world and so it doesn't need to be available to them.
1
2
3
4
5
6
7
class deck {
public:
    deck()
    //...
private:
    int __cards; // perhaps card __cards; and define a class called "card"
}


Finally, your for loops in resetdeck() aren't c++. Use:
1
2
3
for (int suit = 1; suit < 5; ++suit)
    for (int value = 1; value < 14; ++value)
        this->__cards...


You may need to use another class for the cards if yuou want to do things like append as you do in your resetdeck.
Last edited on
You can change
if (uM != 1 && uM != 2 && uM != 3 && uM != 4 && uM != 5 && uM != 6 && uM != 7)
to
if (uM < 1 || uM > 7)

for __cards use vectors. As c++ do not have list like in python
this is wrong __cards = [];

And you need to declare variable cards in class not in it's constructor. Because in constructor it is available to constructor only.
Last edited on
Verbatim translation of the Python class:

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
#include <vector>
#include <string>
#include <algorithm>
#include <random>
#include <sstream>
#include <iostream>

template< typename T > inline std::string str( const T& v )
{
    std::ostringstream stm ;
    stm << '\'' << v << '\'' ;
    return stm.str() ;
}

class deck
{
    public:
        //Constructor
        deck() { resetdeck(); }

        //Method that resets the deck
        void resetdeck()
        {
            _cards.clear() ;
            for( int suit = 1 ; suit < 5 ; ++suit )
                for( int value = 1 ; value < 14 ; ++value )
                  _cards.push_back( str(value) + "|" + str(suit) );
        }

        //Method that shuffles the deck
        void shuffle() { std::random_shuffle( _cards.begin(), _cards.end() ) ; }

        //Method that cuts the deck
        void cutdeck()
        { std::rotate( _cards.begin(), _cards.begin()+_cards.size()/2, _cards.end() ) ; }

        //Method that cuts to a card
        void cuttocard() { cutdeck() ; std::cout << _cards.back() << '\n' ; }

        //Method that both CPU and user cut to card and highest card wins
        void cutCPU()
        {
            std::string playerTop = _cards.back() ;
            _cards.pop_back() ;
            std::string compTop = _cards.back() ;
            _cards.pop_back() ;
            std::cout << "Player Computer" << playerTop << " " << compTop ;
        }

        //Method that returns the cards
        const std::vector<std::string>& get_cards() { return _cards ; }

        private: std::vector<std::string> _cards ;
};

Holy cow, up until now I didn't know anybody replied, I could have sworn I subscribed to it too. JLborges, I plugged that class in with my main(), had a few errors in my int main(), however I got it to compile and run.

I made a few changes to the class however they didn't work the way I wanted, originally in my python program, when it shuffled or the secret menu option, it would display each element in the array, basically all 52 cards on screen, I added a cout statement to those two methods however they print just two of the cards. Anyway to make them print all?

Here's the program so far:

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
#include <vector>
#include <string>
#include <algorithm>
#include <random>
#include <sstream>
#include <iostream>

using namespace std;
template< typename T > inline std::string str( const T& v )
{
    std::ostringstream stm ;
    stm << '\'' << v << '\'' ;
    return stm.str() ;
}

class deck
{
    public:
        //Constructor
        deck() { resetdeck(); }

        //Method that resets the deck
        void resetdeck()
        {
            _cards.clear() ;
            for( int suit = 1 ; suit < 5 ; ++suit )
                for( int value = 1 ; value < 14 ; ++value )
                  _cards.push_back( str(value) + "|" + str(suit) );
        }

        //Method that shuffles the deck
        void shuffle() { std::random_shuffle( _cards.begin(), _cards.end() ) ; std::cout << _cards.back(); }

        //Method that cuts the deck
        void cutdeck()
        { std::rotate( _cards.begin(), _cards.begin()+_cards.size()/2, _cards.end() ) ; std::cout << _cards.back(); }

        //Method that cuts to a card
        void cuttocard() { cutdeck() ; }

        //Method that both CPU and user cut to card and highest card wins
        void cutCPU()
        {
            std::string playerTop = _cards.back() ;
            _cards.pop_back() ;
            std::string compTop = _cards.back() ;
            _cards.pop_back() ;
            std::cout << "Player Computer\n\n" << playerTop << " " << compTop ;
        }

        //Method that returns the cards
        const std::vector<std::string>& get_cards() { return _cards ; }

        private: std::vector<std::string> _cards ;
};

int main() 
{
    deck getcard;
    int menuloop = 1;
	int uM;
    //Loop for actions until user decides to exit
    while (menuloop == 1)
	{
        cout << "\n" << "\n";
        cout << "1. Reset the deck" << "\n";
        cout << "2. Shuffle the deck" << "\n";
        cout << "3. Cut the deck" << "\n";
        cout << "4. Cut to a card" << "\n";
        cout << "5. Cut against the computer" << "\n";
        cout << "6. Exit the program" << "\n";
        cout << "" << "\n";
		cout << "Select a menu option(#): ";
        cin >> uM;
        cout << "" << "\n";
        if (uM == 1) {
            getcard.resetdeck();
				getcard.get_cards(); }
            
        if (uM == 2) {
            getcard.shuffle();
				getcard.get_cards(); }

        if (uM == 3) {
            getcard.cutdeck();
				getcard.get_cards(); }

        if (uM == 4)
            getcard.cuttocard();

        if (uM == 5)
            getcard.cutCPU();

        //Exit option, ends loop
        if (uM == 6) { 
            cout << "BYE";
				menuloop = 0; }

        //Secret option, used to show cards
        if (uM == 7)
            getcard.get_cards();

        //Defensive if statement, only accepts #'s 1-7
        if (uM < 1 || uM > 7)
            cout << "Wrong input entered";
    
	}
}
I do realize I should be cout'ing the get_cards() method, however it gives me errors when I do cout << getcard.get_cards();
1
2
3
4
5
6
7
8
9
        //Secret option, used to show cards
        if (uM == 7)
       {
            const std::vector<std::string>& cards = getcard.get_cards() ;
            std::cout << "[ " ;
            for( std::size_t i = 0 ; i < cards.size() ; ++i )
                std::cout << cards[i] <<  ' '  ;
            std::cout << "]\n" ;
        }
Awesome, everything works great. Question, what does this bit of code do?

1
2
3
4
5
6
template< typename T > inline std::string str( const T& v )
{
    std::ostringstream stm ;
    stm << '\'' << v << '\'' ;
    return stm.str() ;
}
It mimics the behaviour of the python built in function str()

Given an object v of some type T, it returns a string (with quotes around it) that would have been printed if this was possible: std::cout << v ;
Ok, one last thing. For my input validation, I have this code

1
2
3
        //Defensive if statement, only accepts #'s 1-7
        if (uM < 1 || uM > 7)
            std::cout << "Wrong input entered";


However, when I enter a character, like a for example, it will loop endlessly. How can I fix that?
Something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int input_int( int minv, int maxv )
{
    while(true)
    {
        std::cout << "enter a number in the interval [" << minv << ',' << maxv << "]: " ;
        int value ;
        if( std::cin >> value && value >= minv && value <= maxv ) return value ;

        std::cerr << "invalid input.\n" ;

        // http://en.cppreference.com/w/cpp/io/basic_ios/clear
        std::cin.clear() ; // clear the error state (if any)

        // http://en.cppreference.com/w/cpp/io/basic_istream/ignore
        std::cin.ignore( 1024, '\n' ) ; // throw away crud in the input buffer
    }
}

And then:
1
2
3
4
5
6
7
8
9
int main()
{
    // ...

    // only accepts #'s 1-7
    int uM = input_int( 1, 7 ) ;

    // ...
}
Topic archived. No new replies allowed.