クラスメンバの扱いに困っています。

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

クラスメンバの扱いに困っています。

#1

投稿記事 by myon » 14年前

こんにちは。現在、

・プレイヤーをNPCの二人でじゃんけんゲームを行う
・プレイヤーはキーボード入力で手を決める。
・NPCはランダムで手を決める。
・勝敗を判定する。
・プレイヤーの勝敗に応じた結果を表示する。

というような簡単なゲームを考えています。
プレイヤーとNPCはplayerクラスでのことを考えており、
勝敗の判断や画像の表示はzyanken_fieldクラスを想定しています。

しかしながら、勝敗の判断void zyanken_field::syouhai_handan()の中身がどうもうまくかけません。
また、if(player::te==GUU) DrawGraph(te_hyouzi_iti_x,te_hyouzi_iti_y,guu_img,FALSE);のような記述も不自然に思えます。

勝敗の判断はプレイヤーとNPCの手の値がどうしても必要になります。これをクラスで実現するにはどうすればよいでしょうか。

グローバル変数を使う、クラスを使わないなどの措置を行えば簡単に実装できますが、できる限りクラス内以外での変数は用いたくありません。(それとも、このような場合は通常クラスを用いないのでしょうか?)

よろしければアドバイスお願いします。

環境はVisualC++、windowsXPとなります。

コード:

#include "DxLib.h"
#define GUU 1
#define TYOKI 2
#define PAA 3

int Key[256]; // キーが押されているフレーム数を格納する

// キーの入力状態を更新する
int gpUpdateKey(){
        char tmpKey[256]; // 現在のキーの入力状態を格納する
        GetHitKeyStateAll( tmpKey ); // 全てのキーの入力状態を得る
        for( int i=0; i<256; i++ ){ 
                if( tmpKey[i] != 0 ){ // i番のキーコードに対応するキーが押されていたら
                        Key[i]++;     // 加算
                } else {              // 押されていなければ
                        Key[i] = 0;   // 0にする
                }
        }
        return 0;
}


class player{
private:
public:
	static int te;
	void te_kettei();
};

int player::te=0;

void player::te_kettei(){
	if( Key[KEY_INPUT_G] == 1 ) te=GUU;
	if( Key[KEY_INPUT_T] == 1 ) te=TYOKI;
	if( Key[KEY_INPUT_P] == 1 ) te=PAA;
}


class zyanken_field{
private:
	int syohai;
	int kati_img;
	int make_img;
	int aiko_img;
	int guu_img;
	int paa_img;
	int tyoki_img;
	int haikei_img;
	int te_hyouzi_iti_x;
	int te_hyouzi_iti_y;
public:
	void te_hyouzi();
	void syouhai_handan();
	void syouhai_hyouzi();
	void game_start();
	void haikei_hyouzi();
	void gazou_in();
	void te_xy();
};

void zyanken_field::te_hyouzi(){
	if(player::te==GUU) DrawGraph(te_hyouzi_iti_x,te_hyouzi_iti_y,guu_img,FALSE);
	if(player::te==TYOKI) DrawGraph(te_hyouzi_iti_x,te_hyouzi_iti_y,tyoki_img,FALSE);
	if(player::te==PAA) DrawGraph(te_hyouzi_iti_x,te_hyouzi_iti_y,paa_img,FALSE);
}

void zyanken_field::syouhai_handan(){
}

void zyanken_field::syouhai_hyouzi(){
	DrawGraph(200,200,haikei_img,FALSE);
}

void zyanken_field::game_start(){

}

void zyanken_field::haikei_hyouzi(){
	DrawGraph(0,0,haikei_img,FALSE);
}

void zyanken_field::gazou_in(){
        guu_img   = LoadGraph( "img/guu.bmp" );
        tyoki_img = LoadGraph( "img/tyoki.bmp" );
		paa_img   = LoadGraph( "img/paa.bmp" );
		haikei_img= LoadGraph( "img/haikei.bmp");
		kati_img  = LoadGraph( "img/kati.bmp");
		make_img  = LoadGraph( "img/make.bmp");
		aiko_img  = LoadGraph( "img/aiko.bmp");
}



int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
	ChangeWindowMode( TRUE ) ;
	if( DxLib_Init() == -1 ) return -1; 


	WaitKey();
	DxLib_End();
	return 0; 
}

アバター
a5ua
記事: 199
登録日時: 15年前

Re: クラスメンバの扱いに困っています。

#2

投稿記事 by a5ua » 14年前

playerクラスのteメンバーがstaticになっていますが、これはどのようなことを意図していますか?
この場合、player::teという変数の実体は1つしかないので、二人でのじゃんけんという仕様に反しているように思います。


さて、本題ですが、

クラスを使わないアプローチとしては、
以下のように、プレイヤー(人間)の手を決定する関数と、NPCの手を決定する関数を
それぞれ用意して、

コード:

int player_te_kettei()
{
	if( Key[KEY_INPUT_G] == 1 ) return GUU;
	if( Key[KEY_INPUT_T] == 1 ) return TYOKI;
	if( Key[KEY_INPUT_P] == 1 ) return PAA;
	
	return 0;	// 未決定:GUUでもTYOKIでもPAAでもない値
}

int npc_te_kettei()
{
	return 1 + GetRand(2);
}
勝敗判断の関数で、

コード:

void zyanken_field::syouhai_handan()
{
	int player_te = player_te_kettei();
	int npc_te = npc_te_kettei();
	
	// 二人の手が決定していたら、どっちが勝ちか判定する
}
のようにするのは、どうでしょう?


クラスを使うとしても、今のところ、必要なメンバー変数が、teしかないので、

コード:

class player
{
public:
    void te_kettei();
private:
	int te;
};

class npc
{
public:
	void te_kettei();
private:
	int te;
};
としても、クラスを使わない場合と大きな差がありません。

playerクラスとnpcクラスでは、te_kettei()の中身だけが異なります。
このような場合、継承を使ったポリモーフィズムの利用が考えられますが、、
すこし難しい話であり、長くなるのでここでは説明しません。(興味があるなら、調べてみるといいでしょう)

myon

Re: クラスメンバの扱いに困っています。

#3

投稿記事 by myon » 14年前

お返事ありがとうございます。よくわかりました。
追記で質問ですが、

if(player::te==GUU) DrawGraph(te_hyouzi_iti_x,te_hyouzi_iti_y,guu_img,FALSE);

このような記述をzyanken_fieldクラスメンバでしたいとき、playerクラスの変数を用いて判定しなければなりません。このように別クラスの変数を用いるとき、この記述でよいのでしょうか? なんとも不自然な感じがします。

あるいは、あるクラスの変数をほかのクラスで用いる方法はどのようなものがあるのでしょうか。

アバター
a5ua
記事: 199
登録日時: 15年前

Re: クラスメンバの扱いに困っています。

#4

投稿記事 by a5ua » 14年前

クラスも型の一種ですから、普通にメンバ変数として宣言すればいいですよ。

コード:

class player
{
public:
	int te;
	/* 略 */
};

class zyanken_field
{
private:
	player player1;
public:
	void te_hyouzi();
	/* 略 */
};

void zyanken_field::te_hyouzi()
{
	if (player1.te == GUU) /* 略 */
}

myon

Re: クラスメンバの扱いに困っています。

#5

投稿記事 by myon » 14年前

よくわかりました。ありがとうございました。
なんだか完全にクラスの勉強不足でした。精進したいと思います。

閉鎖

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