0

ブラックジャックのゲームをコーディングしようとしています。私は空き時間に C++ を独学しており、プログラミングに関する Web サイトに投稿するのはこれが初めてです。

私は自分の問題に対する答えを調べながら、かなり多くのことを学びました..しかし、この問題は私を完全に困惑させました. 私は完全に間違った仕事に取り組んでいるのではないかと心配しています。うまくいけば、これを手伝ってくれます.

Card クラスと、52 枚のカードのベクトルを保持する Deck クラスがあります。ベクターは Deck クラスのプライベート メンバーですが、これは私の問題なのでしょうか?

コードに random_shuffle 行を追加すると、正常にコンパイルされますが、コンソール ウィンドウがクラッシュします (Windows 7 x64、code::blocks、c++)。私は自分が間違っていることを理解できません。ベクトル ランダム アクセス反復子 begin() および end() を呼び出します...

デッキ.h

#ifndef DECK_H
#define DECK_H

#include <vector>

using namespace std;

/** Card Class */
class Card
{
public:
/** Constructor prototypes */
//Card(); //default constructor
Card(int s, int r) : suit(s), rank(r) {} 

/** GET function prototypes */
int getRank(); // returns card number as int
string getSuit(); // returns the suit in a string

private:
int rank;
int suit;
} ;

/** Deck class */
class Deck
{
public:
Deck();
vector <Card> get_deck() { return deck; };

private:
vector<Card> deck;
};

#endif // DECK_H

デッキ.cpp

#include <iostream>
#include <string>
#include <vector>
#include "deck.h"

using namespace std;

/** Deck ctor to initialise deck */
Deck::Deck()
{
for(int suit = 0; suit < 4; suit++)
{
    for(int rank = 0; rank < 13; rank++)
    {
        deck.push_back(Card(suit,rank));
    }
}

}

/** Functions to GET rank and suit */
// Function to get rank as int
int Card::getRank()
{
return rank;
}

// Function to get suit as string
string Card::getSuit()
{
switch(suit)
{
    case 0:
    return "Diamonds";

    case 1:
    return "Hearts";

    case 2:
    return "Clubs";

    case 3:
    return "Spades";

    default:
    return "Error";
}
}

main.cpp

#include <iostream>
#include <algorithm>
#include <ctime> // time()
#include <string>
#include <vector>

#include "deck.h"

using namespace std;

int main()
{

Deck mydeck;

random_shuffle( mydeck.get_deck().begin(), mydeck.get_deck().end() );

// Loop to iterate through deck of cards
for(int i = 0; i<52; i++)
{
    cout << mydeck.get_deck()[i].getRank() << " of " << mydeck.get_deck()[i].getSuit() << endl;
}

// Display size of deck
//cout << endl << "The size of deck is: " << mydeck.get_deck().size() << endl;


return 0;
}

助けや知恵の言葉があれば大歓迎です。すべてが正しくフォーマットされていることを願っています...

どうもありがとう

ダン

4

2 に答える 2

6

このアクセサ メソッド:

vector <Card> get_deck() { return deck; };

カードのベクトルのコピーを返します。したがって、2 回呼び出すと、2 つの異なるコピーが取得begin()され、最初のコピーの が 2 番目のコピーの と一致しないend()ため、クラッシュします。

これを修正するには、コピーが作成されないように、参照によって配列を返す必要があります。

vector <Card>& get_deck() { return deck; }  // no semicolon needed here
//           ^
//           |
//    this is a reference

ただし、これにより、呼び出し元が内部配列を変更できるようになりますが、これは一般的に悪い考えです。constこれを避けるには、参照によって返す必要があります。

const vector <Card>& get_deck() { return deck; }

しかし、そうするとstd::random_shuffle、配列を変更できなくなります。したがって、それを修正するための理想的な解決策は、それ自体Deckを呼び出すクラス メソッドをクラスに追加することです。random_shuffle

于 2012-10-31T15:46:52.353 に答える
2

vector<Card>&から戻ってみてくださいget_deck()。投稿されたコードでは、2 つの別々のコピーを作成し、それらを返しています。

random_shuffleしたがって、その仕事をしようとすると、2 つの異なるベクトルを指すイテレータがあります。

@Willが別の回答へのコメントで指摘しているように、メンバーvoid Deck::shuffle()を呼び出してまったく公開しないメソッドを実装することにより、カプセル化を維持する方がよいでしょう。random_shuffledeckdeck

于 2012-10-31T15:46:31.013 に答える