如何在C++中对对象向量进行洗牌。

huangapple go评论72阅读模式
英文:

How to shuffle a vector of objects in c++

问题

抱歉,我只会翻译文本,不会回答你的问题。以下是代码的翻译部分:

我是C++编程的新手,正在尝试制作一个二十一点(Blackjack)游戏,首先要使逻辑工作,然后使用一些代码来制作图形版本。

我的代码如下,Visual Studio显示没有找到问题,但当我尝试编译代码时,出现以下错误:

严重性	Code	描述	项目	文件		抑制状态
错误	C2672	'swap':未找到匹配的重载函数	blackJack	C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\include\utility	78	

请注意,代码中的错误信息并没有被翻译,保留了原文的格式。如果你需要关于错误的更多信息或解决方案,请提供详细的错误消息以便获得帮助。

英文:

I'm new to c++ programming and trying to make a blackjack game with a view of getting the logic working and then using some of the code to make a graphical version.

My code is below and Visual Studio states no issues found, but when I try and compile the code, I get the following error:

Severity Code Description Project File Line Suppression State
Error C2672 'swap': no matching overloaded function found blackJack C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\include\utility 78



#include <iostream>
#include <string>
#include <map>
#include <string_view>
#include <vector>
#include <algorithm>
#include <random>
#include <iterator>
#include <cstdlib>
#include <utility>

class card
{
public:
	std::string suite;
	char pictureCard = 'n';
	int value = 0;
	const int numberOfDecks = 1;
	void setCardValue(const int& value, std::string suite, char pictureCard);
	void getDeck();
	void setDeck(const int& numberOfDecks);

	void shuffle();
	std::vector <card> v;
};

void::card::setCardValue(const int& value, std::string suite, char pictureCard)
{
	this->value = value;
	this->suite = suite;
	this->pictureCard = pictureCard;
}

void::card::setDeck(const int& numberOfDecks) 
{
	card c1;
	for (int n = 0; n < numberOfDecks; n++)
	{ 
		int j = 2;
		for (int i = 0; i < 9; i++) //set Numbered cards
		{
			c1.setCardValue(j, "Hearts", 'N');
			v.push_back(c1);
			c1.setCardValue(j, "Clubs", 'N');
			v.push_back(c1);
			c1.setCardValue(j, "Diamonds", 'N');
			v.push_back(c1);
			c1.setCardValue(j, "Spades", 'N');
			v.push_back(c1);
			j++;
		}

		for (int p = 0; p < 4; p++) //set Pictured cards
		{
			char N = 'N';
			if (p == 0) { N = 'J'; }
			else if (p == 1) { N = 'Q'; }
			else if (p == 2) { N = 'K'; }
			else if (p == 3) { N = 'A'; };

			c1.setCardValue(10, "Hearts", N);
			v.push_back(c1);
			c1.setCardValue(10, "Clubs", N);
			v.push_back(c1);
			c1.setCardValue(10, "Diamonds", N);
			v.push_back(c1);
			c1.setCardValue(10, "Spades", N);
			v.push_back(c1);
		}
	}

	int seed = 1;
	std::default_random_engine e(seed);


	std::shuffle(v.begin(), v.end(), e);


}

void card::getDeck()
{
	for (auto it = begin(v); it != end(v); ++it)
	{
		std::cout << it->value << it->suite << it->pictureCard << std::endl;
	}
	std::cout << v.size() << std::endl;


}



int main()
{
	card c2;
	c2.setDeck(6);
	c2.getDeck();

	return 0;
}

Apologies in advance if this is a really basic error, but can't seem to figure it out as my debugging skills are basic as well.

答案1

得分: 2

如果您查看错误消息上下几行,您的编译器应该会告诉您程序中的哪一行导致了错误级联:

t.C:76:17:   required from here
/usr/include/c++/12/bits/stl_algobase.h:182:11: error: no matching function for call to swap(card&, card&)
  182 |       swap(*__a, *__b);

第76行是对std::shuffle的调用。

const int numberOfDecks = 1;

您的card类具有非静态的const成员。这会自动从类中删除默认赋值和移动操作符。您不能默认将一个card赋给另一个,因为这意味着,根据定义,一个对象的const成员会神秘地被另一个对象的成员值替换。正如Spock先生所说:“这是不合逻辑的”。

您需要删除const类成员,或者为card类定义自己的operator=重载,以执行对card类而言有意义的操作。

英文:

If you look a few lines above and below the error message your compiler should tell which line in your program resulted in the cascade of errors:

t.C:76:17:   required from here
/usr/include/c++/12/bits/stl_algobase.h:182:11: error: no matching function for call to ‘swap(card&, card&)’
  182 |       swap(*__a, *__b);

Line 76 is the call to std::shuffle.

 const int numberOfDecks = 1;

Your card class has a non-static const member. That automatically removes the default assignment and move operators from the class. You can't assign one card to another, by default, just like that, because that would mean -- by definition -- that one object's const member gets mysteriously replaced by another object's member's value. As Mr. Spock would say: "this is not logical".

You'll either need to remove the const class member or define your own operator= overload for the card class that does whatever makes sense for = to do, with your card classes.

答案2

得分: 0

谢谢大家的回复。它们都非常有帮助 - 我有很多东西要学习,但我觉得很有趣!

Sam Varshavchik,你的答案第一次就起作用了。一旦我移除了const类成员,程序就能成功编译。

我也考虑了大家关于类设计的评论,我提出了下面的解决方案,它完美地起作用。现在我将在处理函数等方面玩得开心。

再次感谢大家。


#include <iostream>
#include <string>
#include <map>
#include <string_view>
#include <vector>
#include <algorithm>
#include <random>
#include <iterator>
#include <cstdlib>
#include <utility>

class card
{
public:
    std::string suite;
    char pictureCard = 'n';
    int value = 0;
    void setCardValue(const int& value, std::string suite, char pictureCard);
};

void::card::setCardValue(const int& value, std::string suite, char pictureCard)
{
    this->value = value;
    this->suite = suite;
    this->pictureCard = pictureCard;
}


class deck
{
public:
    const int numberOfDecks = 1;
    void setDeck(const int& numberOfDecks);
    std::vector <card> v;    
};

void::deck::setDeck(const int& numberOfDecks)
{
    card c1;
    for (int n = 0; n < numberOfDecks; n++)
    {
        int j = 2;
        for (int i = 0; i < 9; i++) //set Numbered cards
        {
            c1.setCardValue(j, "Hearts", 'N');
            v.push_back(c1);
            c1.setCardValue(j, "Clubs", 'N');
            v.push_back(c1);
            c1.setCardValue(j, "Diamonds", 'N');
            v.push_back(c1);
            c1.setCardValue(j, "Spades", 'N');
            v.push_back(c1);
            j++;
        }

        for (int p = 0; p < 4; p++) //set Pictured cards
        {
            char N = 'N';
            if (p == 0) { N = 'J'; }
            else if (p == 1) { N = 'Q'; }
            else if (p == 2) { N = 'K'; }
            else if (p == 3) { N = 'A'; };

            c1.setCardValue(10, "Hearts", N);
            v.push_back(c1);
            c1.setCardValue(10, "Clubs", N);
            v.push_back(c1);
            c1.setCardValue(10, "Diamonds", N);
            v.push_back(c1);
            c1.setCardValue(10, "Spades", N);
            v.push_back(c1);
        }
    }
}


class dealer
{
public:
    void shuffle(deck &deck);
    void getDeck(deck &deck);
};

void::dealer::shuffle(deck &deck)
{
    auto e = std::default_random_engine{};
    std::shuffle(deck.v.begin(), deck.v.end(), e);
}

void::dealer::getDeck(deck &deck)
{
    for (auto it = begin(deck.v); it != end(deck.v); ++it)
    {
        std::cout << it->value << it->suite << it->pictureCard << std::endl;
    }
    std::cout << deck.v.size() << std::endl;
}


int main()
{
    deck deck;
    dealer dealer;
    deck.setDeck(6);
    dealer.shuffle(deck);
    dealer.getDeck(deck);

    return 0;
}
英文:

Thank you everyone for the responses. They were all really helpful - I have a lot to learn but I'm finding it fun!

Sam Varshavchik your answer worked first time. As soon as I removed the const class member the program compiled without error.

I have also taken everyone's comments regarding class design on board and I have come up with the following solution below that works perfectly. I will now have some fun working on dealing functions etc.

Many thanks again.


#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;map&gt;
#include &lt;string_view&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;random&gt;
#include &lt;iterator&gt;
#include &lt;cstdlib&gt;
#include &lt;utility&gt;
class card
{
public:
std::string suite;
char pictureCard = &#39;n&#39;;
int value = 0;
void setCardValue(const int&amp; value, std::string suite, char pictureCard);
};
void::card::setCardValue(const int&amp; value, std::string suite, char pictureCard)
{
this-&gt;value = value;
this-&gt;suite = suite;
this-&gt;pictureCard = pictureCard;
}
class deck
{
public:
const int numberOfDecks = 1;
void setDeck(const int&amp; numberOfDecks);
std::vector &lt;card&gt; v;	
};
void::deck::setDeck(const int&amp; numberOfDecks)
{
card c1;
for (int n = 0; n &lt; numberOfDecks; n++)
{
int j = 2;
for (int i = 0; i &lt; 9; i++) //set Numbered cards
{
c1.setCardValue(j, &quot;Hearts&quot;, &#39;N&#39;);
v.push_back(c1);
c1.setCardValue(j, &quot;Clubs&quot;, &#39;N&#39;);
v.push_back(c1);
c1.setCardValue(j, &quot;Diamonds&quot;, &#39;N&#39;);
v.push_back(c1);
c1.setCardValue(j, &quot;Spades&quot;, &#39;N&#39;);
v.push_back(c1);
j++;
}
for (int p = 0; p &lt; 4; p++) //set Pictured cards
{
char N = &#39;N&#39;;
if (p == 0) { N = &#39;J&#39;; }
else if (p == 1) { N = &#39;Q&#39;; }
else if (p == 2) { N = &#39;K&#39;; }
else if (p == 3) { N = &#39;A&#39;; };
c1.setCardValue(10, &quot;Hearts&quot;, N);
v.push_back(c1);
c1.setCardValue(10, &quot;Clubs&quot;, N);
v.push_back(c1);
c1.setCardValue(10, &quot;Diamonds&quot;, N);
v.push_back(c1);
c1.setCardValue(10, &quot;Spades&quot;, N);
v.push_back(c1);
}
}
}
class dealer
{
public:
void shuffle(deck &amp;deck);
void getDeck(deck &amp;deck);
};
void::dealer::shuffle(deck &amp;deck)
{
auto e = std::default_random_engine{};
std::shuffle(deck.v.begin(), deck.v.end(), e);
}
void::dealer::getDeck(deck &amp;deck)
{
for (auto it = begin(deck.v); it != end(deck.v); ++it)
{
std::cout &lt;&lt; it-&gt;value &lt;&lt; it-&gt;suite &lt;&lt; it-&gt;pictureCard &lt;&lt; std::endl;
}
std::cout &lt;&lt; deck.v.size() &lt;&lt; std::endl;
}
int main()
{
deck deck;
dealer dealer;
deck.setDeck(6);
dealer.shuffle(deck);
dealer.getDeck(deck);
return 0;
}

huangapple
  • 本文由 发表于 2023年2月23日 21:33:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75545550.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定