同じ変数をまとめたい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
長峰
記事: 32
登録日時: 7年前

同じ変数をまとめたい

#1

投稿記事 by 長峰 » 7年前

調べてわからなかったので質問します。
ステージの縦と横の長さに当たるwidthとheightをまとめたいのですが、方法がわかりません。
テンプレートを使ったクラスで2つ、Stateの方でも1つの計3つ、同じ変数が出来てしまっており、これらをまとめようと思ったのですが、自力でやろうとするとどうしてもテンプレートクラスを崩すやり方しか思いつきませんでした。テンプレートをStateクラスの下位クラスとするなど(?)して変数のスコープを伸ばすやり方はありませんか。回答をお願いします。

※下記コードの元は、SEGAのプログラミング本にある"荷物くん"というコードです。

コード:

#include <fstream>
#include <iostream>
using namespace std;
template<class T> class Array2D{
	T* p;
	int width,height;//Size
public:
	Array2D() :p(0){}
	~Array2D(){ delete[]p; }
	void PinNewArray(int x, int y){ if (p){ delete[]p; } width = x; height = y; p = new T[x*y]; }
	T& operator()(int x, int y){ return p[y*width + x]; }
	const T& operator()(int x, int y)const{ return p[y*width + x]; }
};
class State{
	enum Object{ Wall, Space, Load, Other };
	int width;
	int height;
	int px,py;//Player Position
	int goal, load;
	Array2D<Object>stage;
	Array2D<bool>goalflags;
	void MeasuringSize(const char* stageData, int size){
		width = height = 0;//Initialize
		int x = 0, y = 0;
		for (int i = 0; i < size; ++i){
			switch (stageData[i]){
			case'#':
			case'.':
			case' ':
			case'O':
			case'o':
			case'P':
			case'p':++x; break;
			case'\n'://yを加算してから最大値更新
				++y;
				width = (width > x) ? width : x;
				height = (height > y) ? height : y;
				x = 0;
				break;
			}
		}
	}
	bool CheckDivision(int x, int y){ return (x < 0 || y < 0 || x >= width || y >= height) ? false : true; }
	void MovePlayer(int x, int y){ px = x; py = y; }
public:
	State(const char* stageData, int size){
		goal = load = 0;
		MeasuringSize(stageData, size);
		stage.PinNewArray(width, height);
		goalflags.PinNewArray(width, height);
		//Array Initialize
		for (int y = 0; y < height; ++y){
			for (int x = 0; x < width; ++x){
				stage(x, y) = Wall; goalflags(x, y) = false;
			}
		}
		//stageDataからstage配列に書き込み
		int x = 0;
		int y = 0;
		for (int i = 0; i < size; ++i){
			Object t;
			switch (stageData[i]){
			case'#':t = Wall; break;
			case'.':goalflags(x, y) = true; ++goal;
			case' ':t = Space; break;
			case'O':goalflags(x, y) = true; ++goal;
			case'o':t = Load; ++load; break;
			case'P':goalflags(x, y) = true; ++goal;
			case'p':t = Space; MovePlayer(x, y); break;
			case'\n':x = 0; ++y;
			default:t = Other; break;
			}
			if (t != Other){ stage(x, y) = t; ++x; }
		}
	}
	void Update(char input){
		//入力を変化量に変換
		int dx = 0;
		int dy = 0;
		switch (input){
		case'w':dy = -1; break;
		case's':dy = 1; break;
		case'a':dx = -1; break;
		case'd':dx = 1; break;
		}
		//プレイヤーの移動(移動方向先2マスを調べる)
		int tx = px + dx;
		int ty = py + dy;
		int tx2 = tx + dx;
		int ty2 = ty + dy;
		if (CheckDivision(tx, ty)){
			if (stage(tx, ty) == Space) { MovePlayer(tx, ty); }
			else if (CheckDivision(tx2, ty2) && stage(tx, ty) == Load && stage(tx2, ty2) == Space){ MovePlayer(tx, ty); stage(tx, ty) = Space; stage(tx2, ty2) = Load; }
		}
	}
	void Draw() const{
		for (int y = 0; y < height; ++y){
			for (int x = 0; x < width; ++x){
				switch (stage(x, y)){
				case Wall: cout << '#'; break;
				case Space: if (x == px && y == py){ cout << (goalflags(x, y)? 'P' : 'p'); }
							else{ cout << (goalflags(x, y)? '.' : ' '); } break;
				case Load: cout << (goalflags(x, y)? 'O' : 'o'); break;
				}
			}
			cout << endl;
		}
	}
	bool CheckClear() const{
		int clear = (goal < load) ? goal : load;//クリアに必要なゴールに到達した荷物の数
		for(int y = 0; y < height; ++y){
			for (int x = 0; x < width; ++x){
				if (goalflags(x, y) && stage(x, y) == Load){ if (--clear <= 0)return true; }
			}
		}
		return false;
	}
};

Poco
記事: 161
登録日時: 10年前

Re: 同じ変数をまとめたい

#2

投稿記事 by Poco » 7年前

なぜまとめようと思ったのでしょうか?

2次元配列のユーティリティクラスであるArray2Dが持つwidth,heightと
Stateが持つwidth,heightでは意味合いが全く違いませんか?

長峰
記事: 32
登録日時: 7年前

Re: 同じ変数をまとめたい

#3

投稿記事 by 長峰 » 7年前

Pocoさん、回答ありがとうございます。

テンプレートクラスのwidth,heightには、Stateのwidth,heightと同じ数値が入り、関数での変更もなく、常に3つとも同じ値をとるので、まとめたいと思っていました。

質問して何ですが、質問時に望んでいた結果自体は、State側の変数にstaticをつけクラス外で定義をし、テンプレートをStateクラスに入れ込むことで得られました。

しかし、Pocoさんの回答と重なる部分だと思うのですが、テンプレートクラスが機能していないことに気がつきました。テンプレートクラスの使い方をいろいろと間違っていたようなので使用方法をちゃんと考えたいと思います。

変な質問失礼しました。

閉鎖

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