カードゲームを作っています。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
いせすげr

カードゲームを作っています。

#1

投稿記事 by いせすげr » 6年前

C++ ほぼ初心者です
カードゲームの中身を先に作ろうと思っているのですが、わからないところがあるので質問させてください。

コード:

//Source.cpp
#include"Header.h"
#include"Player.h"

int main()
{
	cPlayer p;
	cCard* test1 = new cTEST1;

	p.Add(test1);

	printf("%d", p.deck[0]->hp);

	delete test1;

	return 0;
}

コード:

//Header.h
#include<stdio.h>
#include<Windows.h>
#include<vector>

using namespace std;

class cCard
{
public:
	cCard() { hp = 1; }
	int hp;
};

class cTEST1 :public cCard
{
public:
	cTEST1() : cCard() { this->hp = 10;  }
};

コード:

//Player.h
class cPlayer
{
public:
	vector<cCard*>deck;// ここにカード突っ込みたい。

	virtual ~cPlayer();// 解放処理

	template<typename T>
	void Add(T*);

};

// 仮なのでここに記述しています。
template<typename T>
void cPlayer::Add(T* _card)
{// ここが問題点。Tの中身をcCardからcTEST1にしたい。
	deck.push_back(new T);
}
これを実行した際にtemplate<T>の中身がcCardになってしまいます。
これをcTEST1が中身に入るようにするにはどうすればいいのでしょうか?
ご協力お願いします。

結城紬
記事: 42
登録日時: 6年前

Re: カードゲームを作っています。

#2

投稿記事 by 結城紬 » 6年前

これでどうですか

コード:

void cPlayer::Add(cCard* _card)
{
	deck.push_back(_card);
}

いせすげr

Re: カードゲームを作っています。

#3

投稿記事 by いせすげr » 6年前

>>結城紬さんへ
返信ありがとうございます。
すいません、少しだけ補足足りませんでした。

cPlayerクラスの中のvector<cCard*>deckには、同じカードを何枚も作成したいのです。
提案されたものを試してみまして、deck内にcCardを2枚作製し、作成されたcCardの中の1枚のhpをいじり、別の1枚の中を参照してみた結果、同じアドレスの中身を変更していたので変更されたものがすべてに適応されていました。実際に実行したコードを載せておきます。
これを複数枚生成してもちゃんと中身は別々に生成されるようにするにはどうすればいいでしょうか。

コード:

//Source.cpp
#include"Header.h"
#include"Player.h"

int main()
{
	cPlayer p;
	
	cCard* test1 = new cTEST1; 
	/* 他の場所で一旦全てのカードを作成し、それを保存しておく場所を作ってる代用品。*/

	p.Add(test1);
	p.Add(test1);
	p.Add(test1);
	p.deck[0]->hp = 2;

	printf("%d", p.deck[1]->hp);// ここでhp10を表示したい。

	delete test1;

	return 0;
}

コード:

// Header.h
#include<stdio.h>
#include<Windows.h>
#include<vector>

using namespace std;

class cCard
{
public:
	cCard() { hp = 1; }
	int hp;
};

class cTEST1 :public cCard
{
public:
	cTEST1() : cCard() { this->hp = 10; }
};

コード:

// Player.h
class cPlayer
{
public:
	vector<cCard*>deck;// ここにカード突っ込みたい。

	virtual ~cPlayer();// 解放処理

	void Add(cCard*);
	void Add(int i);

};

コード:

#include"Header.h"
#include"Player.h"

cPlayer::~cPlayer()
{
	for (auto _card : deck)
	{
		delete _card;
	}
}

void cPlayer::Add(cCard* _card)
{// ここをいじって何とかしたい。
	deck.push_back(_card);
}

void cPlayer::Add(int i)
{// これでやればうまくいきますが、カードが増えるたびにコードを増やさないといけないのでできれば別の方法を探しています。
	switch (i)
	{
	case 0:
		deck.push_back(new cCard);
		break;
	case 1:
		deck.push_back(new cTEST1);
		break;

	default:
		break;
	}
}

かずま

Re: カードゲームを作っています。

#4

投稿記事 by かずま » 6年前

いせすげr さんが書きました:
6年前
cPlayerクラスの中のvector<cCard*>deckには、同じカードを何枚も作成したいのです
カードを何枚も作成したいのなら、
new cTEST1 を何回も実行しないといけません。

他の場所って、どこですか?
cPlayer内で、delete _card を実行するんだったら、
cPlayer内で、new cTEST1 を実行するのかな?

次のコードは参考になりますか?

コード:

class cCard {
public:
	cCard() { hp = 1; }
	int hp;
};

class cTEST1 : public cCard {
public:
	cTEST1() : cCard() { hp = 10; }
};

#include <vector>
using std::vector;

class cPlayer {
public:
	vector<cCard*> deck;
	virtual ~cPlayer() { for (auto _card : deck) delete _card; }
	void Add() { deck.push_back(new cTEST1); }
};

#include <cstdio>
using std::printf;

int main()
{
	cPlayer p;

	for (int i = 0; i < 3; i++) p.Add();
	p.deck[0]->hp = 2;
	for (int i = 0; i < 3; i++) printf(" %d\n", p.deck[i]->hp);
}

いせすげr

Re: カードゲームを作っています。

#5

投稿記事 by いせすげr » 6年前

>>かずまさんへ
返信ありがとうございます。

tenplateでclassの派生後の型を取れないかな~と思っていました。ですが、返信の際に変なコードを乗っけてしまい、勘違いを生む原因を作ってしまっていました。すいません…orz うまい伝え方を思いつきませんでした。

他の場所とは、実際にはゲーム閉じる時までメモリに保持しておくカード一覧表みたいな場所があり、そこから指定したカードをdeckに追加する予定なのですが、一覧表とdeckを繋げる際に下のようなコードだと最終的にコードが冗長になりそうなので、何か別の案がないかと探しています。これで行くしかないのでしょうか?

後、参考に書いていただいたコードですがすいません…参考にならないと思います。

コード:

class cPlayer {
public:
	vector<cCard*> deck;
	virtual ~cPlayer() { for (auto _card : deck) delete _card; }
	void Add(int i);
};

void cPlayer::Add(int i)
{// main.cpp内のAdd()関数をこれに変えればうまくいきますが、カードが増えるたびにコードを増やさないといけないので、できれば別の方法を探しています。
	switch (i)
	{
	case 0:
		deck.push_back(new cCard);
		break;
	case 1:
		deck.push_back(new cTEST1);
		break;

	default:
		/*エラー処理*/
		break;
	}
}

int main()
{
	cPlayer p;
	for (int i = 0; i < 3; i++) p.Add(1);// これなら大丈夫
	return 0;
}

参照魚
記事: 109
登録日時: 6年前

Re: カードゲームを作っています。

#6

投稿記事 by 参照魚 » 6年前

Addの引数から型を推測させたいのであれば、test1がcCrad*になっているのでできないです。
Add( (cTEST1*)nullptr )とするかAdd<cTEST1>( nullptr )と明示的に型を指定しないとだめだと思います。
Add関数内で引数で受け取った基底型のポインターから派生型の情報を取得するのは難しいと思います。

cCradに純粋仮想関数 virtual cCard* Generate( void ) = 0; を定義して、派生型にそれぞれのインスタンスを生成させるGenerateを用意させる方法もあります。deck.push_back(_card->Generate() );

いせすげr

Re: カードゲームを作っています。

#7

投稿記事 by いせすげr » 6年前

>>参照魚さんへ
返信ありがとうございます。
returnでnewを返すのは盲点でした。
見た目が綺麗な仕上がりになりそうだったので参考にさせてもらおうと思います。
ありがとうございました!

返信

“C言語何でも質問掲示板” へ戻る