質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
参照

参照は、プログラミングにおいて変数や関数といったメモリ空間上での所在を指示するデータのことを指します。その中にはデータ自体は含まれず、他の場所にある情報を間接的に指示するプログラムです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

6593閲覧

C++でブラックジャックを作成:非const左辺値参照エラーが出ます

ryotakimoto

総合スコア1

参照

参照は、プログラミングにおいて変数や関数といったメモリ空間上での所在を指示するデータのことを指します。その中にはデータ自体は含まれず、他の場所にある情報を間接的に指示するプログラムです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/08/26 04:26

非const左辺値参照エラーを解決したいです

Qiitaの「プログラミング入門者からの卒業試験は『ブラックジャック』を開発すべし」の記事を読んで、c++を使用してトランプゲームのブラックジャック作成に挑戦しています。

  • Cardクラスでカードの数(no)、マーク(mark)を持つ
  • Deckクラスで山札(vector<Card*> cards)を作成(CreateDeck関数、ShuffleCards関数)
  • Playerクラスでcardsからカードを一枚引き(DrawCards関数)、手札(vector<Card*> playerCards)に追加する

上記を実装したいのですが、DrawCardsに以下のエラーが出てしまい、てこずっています。。

html

1Non-const lvalue reference to type 'vector<Card *>' cannot bind to a value of unrelated type 'Deck' 2
  • DrawCards()の引数をDeck &cardsにすればいいのか?と思いましたが、そうすると今度はundefined variableとなってしまいます。
  • Deckオブジェクトがvector<Card*> cardsを返すGetCard()関数を作って、DrawCards内で呼び出す?とも思いましたが、うまくいかず、コード内には関数が残っていますが使っていません。
  • Playerクラスは今後UserとDealerに分けて継承クラスを作るつもりです。

Playerオブジェクトがvector<Card*> cardsからカードを引くにはどうしたら良いのでしょうか?
ご教授よろしくお願いいたします。

main.cpp

html

1#include <iostream> 2#include <vector> 3#include <string> 4 5#include "deck.hpp" 6#include "card.hpp" 7#include "player.hpp" 8 9using std::cout; 10using std::vector; 11using std::string; 12 13void StartGame() { 14 //Start a game 15 cout << "Let's begin Black Jack!!\n\n"; 16 return; 17} 18 19 20int main() { 21 Deck cards; 22 Player player; 23 Player playerCards; //card list that the user has 24 25 StartGame(); 26 cards.CreateDeck(); 27 cards.ShuffleCards(); 28 29 player.DrawCards(cards); //エラーが出る 30 31 return 0; 32} 33

card.hpp

html

1#ifndef card_hpp 2#define card_hpp 3 4#include <stdio.h> 5#include <iostream> 6#include <vector> 7#include <string> 8 9using std::string; 10using std::vector; 11 12 13// Define Card class 14class Card { 15 public: 16// Card(); 17// ~Card(); 18 void Print(); 19 void SetNos(int nos); 20 void SetMarks(int marks); 21 int mark; 22 int no; 23 private: 24}; 25 26#endif /* card_hpp */

card.cpp

html

1#include <iomanip> 2#include "card.hpp" 3 4using std::cout; 5using std::setw; 6 7void Card::Print() { 8 string markStr = "default"; 9 10 switch (this->mark) { 11 case 0: 12 markStr = "♠︎"; 13 break; 14 case 1: 15 markStr = "☘"; 16 break; 17 case 2: 18 markStr = "❤︎"; 19 break; 20 case 3: 21 markStr = "♦︎"; 22 break; 23 } 24 cout << setw(2)<< this->no << " of " << markStr << "\n"; 25} 26 27void Card::SetNos(int nos) { 28 no = (nos % 13) + 1 ; 29 return; 30} 31 32void Card::SetMarks(int marks) { 33 // 0:Spade 1:Club 2:Heart 3:Diamond 34 mark = marks / 13; 35 return; 36}

deck.hpp

html

1#ifndef deck_hpp 2#define deck_hpp 3 4#include <stdio.h> 5#include <vector> 6#include "card.hpp" 7 8using std::vector; 9 10// Define Deck class 11class Deck { 12 public: 13 void CreateDeck(); 14 void ShuffleCards(); 15 Card* GetCard(); 16 private: 17 vector<Card*> cards; 18}; 19 20#endif /* deck_hpp */

deck.cpp

html

1# include <algorithm> 2#include <iostream> 3#include <vector> 4#include <array> 5#include <random> 6#include "deck.hpp" 7#include "card.hpp" 8 9 10using std::cout; 11using std::vector; 12using std::string; 13using std::array; 14 15 16void Deck::CreateDeck() { 17 int CARD = 52; 18 19 for (int i = 0; i < CARD; ++i) { 20 Card* cd; 21 cd = new Card; 22 cd->SetNos(i); 23 cd->SetMarks(i); 24 cards.push_back(cd); 25 } 26 27 cout << "Before Shuffle:\n"; 28 for (auto& e : cards) { 29 e->Print(); 30 } 31 return; 32} 33 34void Deck::ShuffleCards() { 35 std::random_device seed_gen; 36 std::mt19937 engine(seed_gen()); 37 std::shuffle(cards.begin(), cards.end(), engine); 38 39 cout << "\nAfter shuffle:\n"; 40 for (auto& e : cards) { 41 e->Print(); 42 } 43 return; 44} 45 46Card* Deck::GetCard() { 47 Card* cd; 48 cd = new Card; 49 50 cd = cards.at(0); 51 cards.erase(cards.begin()); 52 53 return cd; 54}

player.hpp

html

1#ifndef player_hpp 2#define player_hpp 3 4#include <stdio.h> 5#include <iostream> 6#include <vector> 7#include <string> 8#include "deck.hpp" 9#include "card.hpp" 10 11 12using std::string; 13using std::vector; 14 15 16// Define Player class 17class Player { 18 public: 19 Player(); // Constructor 20 void DrawCards(vector<Card*> &cards); 21// bool isBurst(); 22 private: 23 vector<Card*> playerCards; 24 int playerPoint; 25}; 26 27// Define User class, derived from Player class 28class User : public Player { 29 public: 30 void DrawCards(); 31 private: 32}; 33 34// Define Dealer class, derived from Player class 35class Dealer : public Player { 36 public: 37 void DrawCards(); 38 private: 39}; 40 41 42#endif /* player_hpp */

player.cpp

html

1#include <iostream> 2#include <vector> 3#include <string> 4#include "player.hpp" 5 6 7using std::cout; 8using std::string; 9using std::vector; 10 11 12Player::Player() { 13 // FIXME 14} 15 16void Player::DrawCards(vector<Card*> &cards) { 17 Card* hand; 18 19 hand = cards.at(0); 20 cards.erase(cards.begin()); 21 playerCards.push_back(hand); 22 23 cout << "Your card is "; 24 hand->Print(); 25 return; 26}

利用環境・ツール

macOS Catalina version 10.15.6
Xcode Version 11.5 (11E608c)
Apple clang version 11.0.3 (clang-1103.0.32.62)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

void Player::DrawCards(vector<Card*> &cards)の引数に,
main()内でDeck型のオブジェクトを渡そうとしている.
→当然,引数の型と異なるので怒られる.

起きていることはそれだけのことに見えます.


Player::DrawCards()の引数のように,vector<Card*>によってデック(またはパケット,パイル)を表現するのだとしたら,
その世界におけるDeck型って何のための(何の役目を持つ)型ですか?

逆に言えば,デック(または…略)をDeck型として扱うのであれば,Player::DrawCards()のようなものが引数にvector<Card*>を要求するのは妥当でしょうか?

あなたが考えている世界の仕様(ルール)をはっきりさせて,それに従った実装を行ってください.
足元が揺らいでいるならば,何が正しくて何が違うのかを決めることはできません.

投稿2020/08/26 05:22

編集2020/08/26 05:24
fana

総合スコア11996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2020/08/26 05:47

コードの状況を見ての個人的な意見ですが, とりあえず vector<Card*> ではなく vector<Card> としてはどうか. (Card*であることに強いこだわりがあるとかでないならば,ですが.) 最初は newだの何だのを中途半端な理解状況で使わずに(把握すべき事柄がなるべく少なくて済む世界で)作ってみると良いのではないかと. リンク先をざっと見た感じ,継承を用いること自体が適した話には見えないので,継承とかいう余計な要素も考えずに愚直に作ってみるべきに思います.(ユーザとディーラの1vs1の対決ならば,極端な話,「似たようなコード」が2重に書かれた実装を行えばそれで動くものはできるわけで.)
fana

2020/08/26 05:50 編集

もしも,Player とか Deck とかいうクラスを設けたことが,あなたにとって話の難易度を上げているのだとしたら, そういったクラスを設ける必要性が本当にあるのか?と自問してみてもよいでしょう. それらが無くても実装できるなら,まずは無いバージョンの実装をしてみるのもよいのではないかと思います.(現状よりもずっとシンプルで小さなプログラムでブラックジャックを実現できるかもしれません)
ryotakimoto

2020/08/27 01:48

ありがとうございます。確かに正直、Card*やnewもよくわからないまま使っていたので、ご指摘いただいてハッとしました。。(以前作成したチュートリアルで使ったので、できるかな、、と甘く思ってました) まずは無理せずvector<Card>で作ってみて、またつまずいたら質問させていただきます。ありがとうございました^^
fana

2020/08/27 02:04

例えば, 「デック」も「手札」も要はただのカードの束ですからどちらも vector< Card > で表すとすれば, main()関数内のローカル変数として,3つの vector< Card >型の変数(デック用,ユーザの手札用,ディーラーの手札用)を用意する(&初期状態としてデック用に52枚を突っ込む)とかで,必要なデータはすべて揃うでしょう. そのくらいの形から出発してみればよいのではないかと.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問