Card Game

Pages: 12
Apr 20, 2020 at 3:42pm
Whoops, I forgot that vectors don't have push_front. Use insert with std::begin(the_name_of_vector, value) instead. It should look like this:

 
player_cards.insert(player_cards.begin(), the_card_removed_from_computer);


Although, I suggest you also consider using deque instead of vector since it has the ability to use push_front and push_back, rather than simply push_back.
Last edited on Apr 20, 2020 at 3:51pm
Apr 20, 2020 at 4:13pm
I have made some changes you said, I did change from a vector to a deque thank you for that, and I started using push_front and my player started using seperate cards but the computer keeps using the same car over and over! haha here is an example
Q is higher than A
Computer wins this hand
A is higher than 5
Player wins this hand
7 is higher than 5
Player wins this hand
8 is higher than 5
Player wins this hand
6 is higher than 5
Player wins this hand
J is higher than 5
Player wins this hand
J is higher than 5
Player wins this hand
6 is higher than 5
Player wins this hand
6 is higher than 5
Player wins this hand
X is higher than 5
Player wins this hand

with the code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
deque<card> player_cards(deck, deck + 25);
	deque<card> computer_cards(deck + 25, deck + 52);
	for (i = 0; i < 10; i++)
	{
		int player_higher = play(player_cards, computer_cards);
		if (player_higher == 1 && !computer_cards.empty())
		{
			computer_cards.push_front(player_cards.back());
			player_cards.pop_back();
		}
		else if (player_higher == 2 && !player_cards.empty())
		{
			player_cards.push_front(computer_cards.back());
			computer_cards.pop_back();
		}

		if (player_cards.empty()) cout << "Computer wins";
		if (computer_cards.empty()) cout << "Player wins";
	}


I also changed to an int instead of a bool for my play function which i think will work as I am going to have it return a 1, 2 or 3 depending on the situation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int play(deque<card> const& player, deque<card> const&comp)
{
	auto const& p = player.back();
	auto const& c = comp.back();
		if (p.value > c.value)
		{
			cout << p.value << " is higher than " << c.value << endl;
			cout << "Player wins this hand" << endl;
			return 1;
		}
		else if (p.value < c.value)
		{
			cout << c.value << " is higher than " << p.value << endl;
			cout << "Computer wins this hand" << endl;
			return 2;
		}
		else
		{
			cout << c.value << " is the same as " << p.value << endl;
			cout << "THIS MEANS WAR!" << endl;
		}
	
}



I know I don't have anything returning for war yet but I will get there I should know how to do that. I really appreciate all the help you are giving me and helping me understand what I am doing.
Apr 20, 2020 at 4:22pm
You need to move the winner's card to the "bottom" of his deck, too.
Something like this (and similar for the else part).

1
2
3
4
5
6
7
		if (player_higher == 1 && !computer_cards.empty())
		{
			computer_cards.push_front(computer_cards.back());
			computer_cards.pop_back();
			computer_cards.push_front(player_cards.back());
			player_cards.pop_back();
		}

Also, your play method should return 0 if it's a tie.
I don't see why it's necessary to test if computer_cards is empty since you couldn't have played the hand in that case.
Last edited on Apr 20, 2020 at 4:22pm
Apr 20, 2020 at 4:46pm
dutch that worked thank you.
I am trying to figure out how to get the actual tie to work where each player puts two cards into the middle and flips the third, whoever loses has to collect all, but for now i just put some extra stuff to get it to go.

It will run until one player runs out of cards but then the debugger gives me an error code instead of switching to the cards.empty if statements where the computer wins or player wins.

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
deque<card> player_cards(deck, deck + 25);
	deque<card> computer_cards(deck + 25, deck + 52);
	for (i = 0; i < 1000; i++)
	{
		cout << "Player cards left" << "\tComputer Cards left" << endl;
		cout << player_cards.size() << "\t\t\t" <<  computer_cards.size() << endl;
		cout << "\n";
		int player_higher = play(player_cards, computer_cards);
		if (player_higher == 1 && !computer_cards.empty())
		{
			
			computer_cards.push_front(computer_cards.back());
			computer_cards.pop_back();
			computer_cards.push_front(player_cards.back());
			player_cards.pop_back();
		}
		else if (player_higher == 2 && !player_cards.empty())
		{
			player_cards.push_front(player_cards.back());
			player_cards.pop_back();
			player_cards.push_front(computer_cards.back());
			computer_cards.pop_back();
		}
		else
		{
			player_cards.push_front(player_cards.back());
			player_cards.pop_back();
			player_cards.push_front(computer_cards.back());
			computer_cards.pop_back();
			computer_cards.push_front(computer_cards.back());
			computer_cards.pop_back();
			computer_cards.push_front(player_cards.back());
			player_cards.pop_back();

		}
		
		

		if (player_cards.empty()) cout << "Computer wins";
		if (computer_cards.empty()) cout << "Player wins";
	}


you can ignore the last else statement i put that in there so that it would run through without getting stuck at the war part.
Last edited on Apr 20, 2020 at 4:47pm
Apr 20, 2020 at 5:01pm
Instead of

 
for (i = 0; i < 1000; i++)

use

 
while (!player_cards.empty() && !computer_cards.empty())

Then after the closing brace of that loop:

1
2
3
4
if (player_cards.empty())
	cout << "Computer wins";
else
	cout << "Player wins";


And in the "tie" section (which I realize is just placeholder for now) you need to ensure you don't call back() or pop() when the deque is empty.

1
2
3
4
5
6
7
8
9
10
	for (int i = 0; i < 2; ++i) {
		if (!player_cards.empty()) {
			player_cards.push_front(player_cards.back());
			player_cards.pop_back();
		}
		if (!computer_cards.empty()) {
			player_cards.push_front(computer_cards.back());
			computer_cards.pop_back();
		}
	}

Last edited on Apr 20, 2020 at 5:03pm
Apr 20, 2020 at 5:17pm
OKAY its up and running! thanks for all the help and take it for a spin if you want.

I think the war tie mechanic could get cleaned up a bit because I think it just transfers the cards to eachother without actually seeing who wins but other than that it is firing good.

I am going to clean this up a bit still but for the most part it is looking really good I think.

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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#include<cstdlib>
#include<cmath>
#include<iomanip>
#include<string>
#include<iostream>
#include<fstream>
#include<ctime>
#include<vector>
#include<stack>
#include<algorithm>

using namespace std;

//constant
const int MAX = 52;

//prototypes
void rules();
void shuffle();


//class


class card {
public:
	char value;
	string suit;
	int x = 25;
	void printcard()
	{
		cout << value << " of " << suit;
	}
	

};
card deck[MAX], temp;
int play(deque<card> const& player, deque<card> const&comp);


int main()
{
	//variables
	char again;
	string name;
	cout << "Welcome to the game of WAR!";
	cout << "\n";
	cout << "Please enter your name! : ";
	cin >> name;
	cout << "\n";
	cout << "Welcome " << name << " lets play!" << endl;

	do {
		srand(time(NULL));
		
		int x = 0;
		char value[]{ 'A','2','3','4','5','6','7','8','9','X','J','Q','K' };
		string suit[]{ "Hearts","Diamonds","Clubs","Spades" };
		int i, j, l = 0;
		for (i = 0; i < 4; i++)
		{
			for (j = 0; j < 13; j++)
			{
				deck[l].value = value[j];
				deck[l].suit = suit[i];
				l++;
			}
		}

		//input
		
		rules();


		//calculations
		shuffle();
		deque<card> player_cards(deck, deck + 25);
		deque<card> computer_cards(deck + 25, deck + 52);
		while (!player_cards.empty() && !computer_cards.empty())
		{
			cout << name << " cards left" << "\t\tComputer Cards left" << endl;
			cout << player_cards.size() << "\t\t\t" << computer_cards.size() << endl;
			cout << "\n";
			int player_higher = play(player_cards, computer_cards);
			if (player_higher == 1 && !computer_cards.empty())
			{

				computer_cards.push_front(computer_cards.back());
				computer_cards.pop_back();
				computer_cards.push_front(player_cards.back());
				player_cards.pop_back();
			}
			else if (player_higher == 2 && !player_cards.empty())
			{
				player_cards.push_front(player_cards.back());
				player_cards.pop_back();
				player_cards.push_front(computer_cards.back());
				computer_cards.pop_back();
			}
			else
			{
				for (int i = 0; i < 2; ++i) {
					if (!player_cards.empty()) {
						computer_cards.push_front(player_cards.back());
						player_cards.pop_back();
					}
					if (!computer_cards.empty()) {
						player_cards.push_front(computer_cards.back());
						computer_cards.pop_back();
					}
				}
			}



			if (player_cards.empty()) cout << "===================================You Win!========================================================================"<< endl;
			if (computer_cards.empty()) cout << "==========================================Computer wins=================================================================" << endl;
		}

		cout << "\n";
		cout << "Would you like to play again " << name << "? Y for yes or N for no: ";
		cin >> again;

		//output
		cout << "\n";
	} 
	while (again == 'y' || again == 'Y');
	cout << "\n";
	cout << "Have a Great Day!";
	cout << "\n";
	return 0;
}


//function definitions
void rules()
{
	int ch;
	cout << "Would you like to hear the rules? Press 1 for yes or 2 for no: ";
	cin >> ch;
	if (ch == 1)
	{
		cout << "\n";
		cout << "You will be playing the Computer, each of you will be given 26 cards." << endl;
		cout << "You will both throw down one card, whoever lower card will collect both cards and put them in their decks.\n";
		cout << "If you both have the same value card then you will commence the game of war!\n";
		cout << "Both players will lay down 3 cards face down and then flip a card.\n";
		cout << "Whoever has the lower card loses and collects all the cards in the pile!\n";
		cout << "The first person with zero cards left is declared the winner!\n";
		cout << "Goodluck!\n";
		cout << "\n";
	}
	else
	{
		cout << "no rules" << endl;
	}
}

void shuffle()
{
	int n, m;
	for (n = 0; n < 52; n++)
	{
		m = rand() % 52;
		temp = deck[n];
		deck[n] = deck[m];
		deck[m] = temp;
	}
}



int play(deque<card> const& player, deque<card> const&comp)
{
	auto const& p = player.back();
	auto const& c = comp.back();
		if (p.value > c.value)
		{
			cout << p.value << " is higher than " << c.value << endl;
			cout << "Player wins this hand" << endl;
			cout << "\n";
			return 1;
		}
		else if (p.value < c.value)
		{
			cout << c.value << " is higher than " << p.value << endl;
			cout << "Computer wins this hand" << endl;
			cout << "\n";
			return 2;
		}
		else
		{
			cout << c.value << " is the same as " << p.value << endl;
			cout << "THIS MEANS WAR!" << endl;
			
			return 3;
		}
	
}


Last edited on Apr 20, 2020 at 6:15pm
Apr 20, 2020 at 7:11pm
Check the code that handles ties, and I would actually rewrite your play function to take two cards, rather than two deques.
Last edited on Apr 20, 2020 at 7:17pm
Apr 20, 2020 at 7:24pm
I believe I fixed whatever the problem was. This code seems to work:
http://cpp.sh/7eaq2
Apr 20, 2020 at 7:46pm
There's actually a few problems. As Toaster said, it's the fact that ties always go to one opponent that causes that opponent to win all the time. But of course you said it was just a placeholder logic for now, and that you hadn't actually worked on the real logic yet. When you do fix that you'll also probably want to put a limit on the number of turns since a game can potentially go for thousands of rounds. (Maybe that's what that original i < 1000 for loop was for?)

Other problems:

You are giving the player 25 cards and the computer 27 cards.
It should be:

1
2
		deque<card> player_cards(deck, deck + 26);
		deque<card> computer_cards(deck + 26, deck + 52);

The srand call should be before the loop since it should usually only be called once in the entire run of the program.

You may as well get rid of the variable x since you aren't using it. It's not needed in card or main.

You are comparing char values that include letters. Their "lexicographical" ordering is probably not what you want (for instance 'K' is less than 'Q'). Instead, the value should be an integer.

The initialization of the deck can be placed before the main loop since it only need to be done once.

You forgot to move the if's that print the winner at the end of the loop to after the loop.
Apr 20, 2020 at 8:01pm
Try this code: http://cpp.sh/7eaq2

It seems to work for me. You should probably change it with dutch's suggestions with srand() and the comparison of the values, but other than that, it works just fine.
Apr 20, 2020 at 8:34pm
Thank you guys both, I got it up and running and took both of your suggestions. I have learned a lot working on this and hope to learn a ton more as time goes on. I'll put this as question solved!

Apr 20, 2020 at 10:53pm
edit
Last edited on Apr 20, 2020 at 10:56pm
Topic archived. No new replies allowed.
Pages: 12