require("debug.lua");
if(DEBUG_FUNCTION)
then
	require("101_common_oop.lua");
	require("111_logger.lua");
	require("151_common_environment.lua");
	require("152_global_instance.lua");
	require("161_common_functions.lua");
end
----------------------------------------------------------------------------------------------------------
-- 
-- 行動情報保持関連機能
--
----------------------------------------------------------------------------------------------------------
	CaptureInfo_dis					=1; -- 相手とのx方向の距離、math.floor(math.abs(x-ex))の返り値と常に同じ数値になります。
	CaptureInfo_dis_x				=2; -- disと同じです。
	CaptureInfo_dis_y				=3; -- 相手とのy方向の距離、math.floor(math.abs(y-ey))の返り値と常に同じ数値になります。
	CaptureInfo_dis2				=4; -- 相手とのxy含めた距離です。math.floor(math.sqrt(dis_x*dis_x+dis_y*dis_y))の返り値と常に同じ数値になります。
	CaptureInfo_my_act				=5; -- 自分の現在モーションです。
	CaptureInfo_enemy_act			=6; -- 相手のモーションです
	CaptureInfo_weather				=7; -- 天候です。極光時に限り一定時間すると極光ではなく実際に発動している天候効果の番号が返るようになります。
	CaptureInfo_my_char				=8; -- 自分のキャラです、以下対応表
	CaptureInfo_enemy_char			=9; -- 相手のキャラです。
	CaptureInfo_my_hp				=10;-- 自分のHPです、最大10000
	CaptureInfo_enemy_hp			=11;-- 相手のHPです。
	CaptureInfo_my_rei				=12;-- 自分の霊力です、霊力球一個当り200、最大で1000になります。
	CaptureInfo_enemy_rei			=13;-- 相手の霊力です。
	CaptureInfo_my_rmax				=14;-- 自分の最大霊力値です、最大1000で一つ割れるごとに200減ります。
	CaptureInfo_enemy_rmax			=15;-- 相手の最大霊力値です。
	CaptureInfo_my_spell			=16;-- 自分のスペルカードゲージの量です、一枚当り500で最大2500です。
	CaptureInfo_enemy_spell			=17;-- 相手のスペルカードゲージの量です。
	CaptureInfo_my_combo			=18;-- 自分のコンボヒット数です、別の攻撃がヒットするまで前回のコンボヒット数を指し続けます。
	CaptureInfo_enemy_combo			=19;-- 相手のコンボヒット数です。
	CaptureInfo_my_dam				=20;-- 自分の合計コンボ与ダメージです。
	CaptureInfo_enemy_dam			=21;-- 相手の合計コンボ与ダメージです。
	CaptureInfo_my_limit			=22;-- 自分の与リミットです。
	CaptureInfo_enemy_limit			=23;-- 相手の与リミットです。
	CaptureInfo_my_rate				=24;-- 自分の与レートです。
	CaptureInfo_enemy_rate			=25;-- 相手の与レートです。
	CaptureInfo_x					=26;-- 自分の現在X座標です。
	CaptureInfo_ex					=27;-- 相手の現在X座標です。
	CaptureInfo_y					=28;-- 自分の現在Y座標です。
	CaptureInfo_ey					=29;-- 相手の現在Y座標です。
	CaptureInfo_obj_dis				=30;-- 自分に最も近い敵ダメージ判定の位置です。
	CaptureInfo_obj_dis2			=31;-- 自分に最も近い敵オブジェクトの位置です。
	CaptureInfo_my_obj_n			=32;-- 現在存在している自分のオブジェクト数です。
	CaptureInfo_enemy_obj_n			=33;-- 現在存在している相手のオブジェクト数です。
	CaptureInfo_my_card				=34;-- 自分の1枚目のカードIDです。
	CaptureInfo_enemy_card			=35;-- 相手の1枚目のカードIDです。
	CaptureInfo_my_air				=36;-- 自分の空中ダッシュ回数です、これが2(風雨ならば3)の場合空中ダッシュが使用できない状態です。
	CaptureInfo_enemy_air			=37;-- 相手の空中ダッシュ回数です。
	CaptureInfo_my_frame			=38;-- 自分がそのモーションをはじめてからの経過フレーム数です。
	CaptureInfo_enemy_frame			=39;-- 相手がそのモーションを始めてからの経過フレーム数です。
	CaptureInfo_battle_time			=40;-- 対戦開始してからの経過フレーム数です。
	CaptureInfo_is_card_use			=41;-- 一枚目のカードが使用可能であれば真、そうでないならば偽が格納されます。
	CaptureInfo_weather_time		=42;-- 気質カウンター(天候表示部分で増減している数字)を10倍した値です。
	CaptureInfo_weather2			=43;-- 天気の予報です。
	CaptureInfo_my_dir				=44;-- 自分が左を向いているときは-1、右を向いているときは1が格納されます。
	CaptureInfo_enemy_dir			=45;-- 相手が左を向いているときは-1、右を向いているときは1が格納されます。
	CaptureInfo_is_dir_front		=46;-- 自分が向いている方向に敵が居る場合は真、そうでないならば偽が格納されます。
	CaptureInfo_my_hitstop			=47;-- 打撃攻撃を当てた、もしくは被弾した時に起こる硬直フレーム数が格納されます。
	CaptureInfo_enemy_hitstop		=48;-- 相手の硬直フレーム数です。
	CaptureInfo_my_xspeed			=49;-- 自分のx方向の速度です。
	CaptureInfo_enemy_xspeed		=50;-- 相手のx方向の速度です。
	CaptureInfo_my_yspeed			=51;-- 自分のy方向の速度です。
	CaptureInfo_enemy_yspeed		=52;-- 相手のy方向の速度です。
	CaptureInfo_my_img				=53;-- 自分の現在表示されているキャラ画像のIDです。
	CaptureInfo_enemy_img			=54;-- 相手の現在表示されているキャラ画像のIDです。
	CaptureInfo_my_hitarea_n		=55;-- 自分の食らい判定を示す四角形の個数です
	CaptureInfo_enemy_hitarea_n		=56;-- 相手の食らい判定を示す四角形の個数です
	CaptureInfo_my_attackarea_n		=57;-- 自分の攻撃判定を示す四角形の個数です。
	CaptureInfo_enemy_attackarea_n	=58;-- 相手の攻撃判定を示す四角形の個数です。
	CaptureInfo_my_correction		=59;-- 自分が最後に相手に与えた特殊補正のフラグです。
	CaptureInfo_enemy_correction	=60;-- 相手が最後に自分に与えた特殊補正のフラグです。

	CaptureInfo_MIN = CaptureInfo_dis;
	CaptureInfo_MAX = CaptureInfo_enemy_correction;

----------------------------------------------------------------------------------------------------------
--
-- 行動状況保持クラス CaptureInfo
-- 
-- 		CaptureInfo.captureInfoTable に 環境変数情報を保持する。
-- 		実際に行動を起こす際の判断の材料となる。
--
--		TODO captureInfo.motion をgetCurrentAct準拠に変更したい。
-- 
----------------------------------------------------------------------------------------------------------
CaptureInfo=extends(Serializable);

	----------------------------------------------------------------------------------------------------------
	-- コンストラクタ
	--	引数
	--		captureTarget	:0⇒自分, 1⇒相手
	--						 act_frame, motion値がどちらの値か判別するため。
	--						 これがないと環境変数どっち遣えばいいかわからん。大ボケだった。
	----------------------------------------------------------------------------------------------------------
	function CaptureInfo:constructor(captureTarget)
		-- キャプチャするターゲット 
		self.captureTarget = captureTarget;
		-- AI学習用モーション値
		self.act = 0;
		-- 行動完了したフレーム数
		self.frame = 0;
		-- 印象値
		self.evaluate = 0;
		-- 状況値保持テーブル
		self.captureInfoTable={};
	end
	
	----------------------------------------------------------------------------------------------------------
	-- 現在の状況をキャプチャします
	-- ポジション指定できるのに順番で登録しないといけないtable.insert()何とかして・・・。
	----------------------------------------------------------------------------------------------------------
	function CaptureInfo:capture()
	
		logger:trace("CaptureInfo", "キャプチャ開始 : " .. self.captureTarget);
		
		-- 一応ここでもやっとく。
		self.act = getTargetCurrentAction(self.captureTarget);

		-- 状況のキャプチャ 
		
		-- 敵味方共通
		self.captureInfoTable[CaptureInfo_dis]					= dis;
		self.captureInfoTable[CaptureInfo_dis_x]				= dis_x;
		self.captureInfoTable[CaptureInfo_dis_y]				= dis_y;
		self.captureInfoTable[CaptureInfo_dis2]					= dis2;
		self.captureInfoTable[CaptureInfo_weather]				= weather;
		self.captureInfoTable[CaptureInfo_battle_time]			= battle_time;
		self.captureInfoTable[CaptureInfo_weather_time]			= weather_time;
		self.captureInfoTable[CaptureInfo_weather2]				= weather2;

		-- Enemy版 is_dir_frontも対応。
		self.captureInfoTable[CaptureInfo_is_dir_front]			= getTargetIsDirFront(self.captureTarget);

		if (self.captureTarget == TARGET_MY)
		then
			logger:trace("CaptureInfo", "自分キャプチャ");

			self.captureInfoTable[CaptureInfo_my_act]				= getTargetCurrentAction(self.captureTarget);--my_act;
			self.captureInfoTable[CaptureInfo_enemy_act]			= getTargetCurrentAction(getReverseTarget(self.captureTarget));--enemy_act;
			self.captureInfoTable[CaptureInfo_my_char]				= my_char;
			self.captureInfoTable[CaptureInfo_enemy_char]			= enemy_char;
			self.captureInfoTable[CaptureInfo_my_hp]				= my_hp;
			self.captureInfoTable[CaptureInfo_enemy_hp]				= enemy_hp;
			self.captureInfoTable[CaptureInfo_my_rei]				= my_rei;
			self.captureInfoTable[CaptureInfo_enemy_rei]			= enemy_rei;
			self.captureInfoTable[CaptureInfo_my_rmax]				= my_rmax;
			self.captureInfoTable[CaptureInfo_enemy_rmax]			= enemy_rmax;
			self.captureInfoTable[CaptureInfo_my_spell]				= my_spell;
			self.captureInfoTable[CaptureInfo_enemy_spell]			= enemy_spell;
			self.captureInfoTable[CaptureInfo_my_combo]				= my_combo;
			self.captureInfoTable[CaptureInfo_enemy_combo]			= enemy_combo;
			self.captureInfoTable[CaptureInfo_my_dam]				= my_dam;
			self.captureInfoTable[CaptureInfo_enemy_dam]			= enemy_dam;
			self.captureInfoTable[CaptureInfo_my_limit]				= my_limit;
			self.captureInfoTable[CaptureInfo_enemy_limit]			= enemy_limit;
			self.captureInfoTable[CaptureInfo_my_rate]				= my_rate;
			self.captureInfoTable[CaptureInfo_enemy_rate]			= enemy_rate;
			self.captureInfoTable[CaptureInfo_x]					= x;
			self.captureInfoTable[CaptureInfo_ex]					= ex;
			self.captureInfoTable[CaptureInfo_y]					= y;
			self.captureInfoTable[CaptureInfo_ey]					= ey;
			self.captureInfoTable[CaptureInfo_my_obj_n]				= my_obj_n;
			self.captureInfoTable[CaptureInfo_enemy_obj_n]			= enemy_obj_n;
			self.captureInfoTable[CaptureInfo_my_card]				= my_card;
			self.captureInfoTable[CaptureInfo_enemy_card]			= enemy_card;
			self.captureInfoTable[CaptureInfo_my_air]				= my_air;
			self.captureInfoTable[CaptureInfo_enemy_air]			= enemy_air;
			self.captureInfoTable[CaptureInfo_my_frame]				= my_frame;
			self.captureInfoTable[CaptureInfo_enemy_frame]			= enemy_frame;
			self.captureInfoTable[CaptureInfo_my_dir]				= my_dir;
			self.captureInfoTable[CaptureInfo_enemy_dir]			= enemy_dir;
			self.captureInfoTable[CaptureInfo_my_hitstop]			= my_hitstop;
			self.captureInfoTable[CaptureInfo_enemy_hitstop]		= enemy_hitstop;
			self.captureInfoTable[CaptureInfo_my_xspeed]			= my_xspeed;
			self.captureInfoTable[CaptureInfo_enemy_xspeed]			= enemy_xspeed;
			self.captureInfoTable[CaptureInfo_my_yspeed]			= my_yspeed;
			self.captureInfoTable[CaptureInfo_enemy_yspeed]			= enemy_yspeed;
			self.captureInfoTable[CaptureInfo_my_img]				= my_img;
			self.captureInfoTable[CaptureInfo_enemy_img]			= enemy_img;
			self.captureInfoTable[CaptureInfo_my_hitarea_n]			= my_hitarea_n;
			self.captureInfoTable[CaptureInfo_enemy_hitarea_n]		= enemy_hitarea_n;
			self.captureInfoTable[CaptureInfo_my_attackarea_n]		= my_attackarea_n;
			self.captureInfoTable[CaptureInfo_enemy_attackarea_n]	= enemy_attackarea_n;
			self.captureInfoTable[CaptureInfo_my_correction]		= my_correction;
			self.captureInfoTable[CaptureInfo_enemy_correction]		= enemy_correction;

			-- あくまで自分基準なのでこいつを判定に使うのは微妙かも
			self.captureInfoTable[CaptureInfo_is_card_use]			= is_card_use;
			self.captureInfoTable[CaptureInfo_obj_dis]				= obj_dis;
			self.captureInfoTable[CaptureInfo_obj_dis2]				= obj_dis2;
		else
			-- 敵の行動をキャプチャする場合は敵味方反転して保存
			logger:trace("CaptureInfo", "相手キャプチャ");
			
			self.captureInfoTable[CaptureInfo_my_act]				= getTargetCurrentAction(getReverseTarget(self.captureTarget));--enemy_act;
			self.captureInfoTable[CaptureInfo_enemy_act]			= getTargetCurrentAction(self.captureTarget);--my_act;
			self.captureInfoTable[CaptureInfo_my_char]				= enemy_char;
			self.captureInfoTable[CaptureInfo_enemy_char]			= my_char;
			self.captureInfoTable[CaptureInfo_my_hp]				= enemy_hp;
			self.captureInfoTable[CaptureInfo_enemy_hp]				= my_hp;
			self.captureInfoTable[CaptureInfo_my_rei]				= enemy_rei;
			self.captureInfoTable[CaptureInfo_enemy_rei]			= my_rei;
			self.captureInfoTable[CaptureInfo_my_rmax]				= enemy_rmax;
			self.captureInfoTable[CaptureInfo_enemy_rmax]			= my_rmax;
			self.captureInfoTable[CaptureInfo_my_spell]				= enemy_spell;
			self.captureInfoTable[CaptureInfo_enemy_spell]			= my_spell;
			self.captureInfoTable[CaptureInfo_my_combo]				= enemy_combo;
			self.captureInfoTable[CaptureInfo_enemy_combo]			= my_combo;
			self.captureInfoTable[CaptureInfo_my_dam]				= enemy_dam;
			self.captureInfoTable[CaptureInfo_enemy_dam]			= my_dam;
			self.captureInfoTable[CaptureInfo_my_limit]				= enemy_limit;
			self.captureInfoTable[CaptureInfo_enemy_limit]			= my_limit;
			self.captureInfoTable[CaptureInfo_my_rate]				= enemy_rate;
			self.captureInfoTable[CaptureInfo_enemy_rate]			= my_rate;
			self.captureInfoTable[CaptureInfo_x]					= ex;
			self.captureInfoTable[CaptureInfo_ex]					= x;
			self.captureInfoTable[CaptureInfo_y]					= ey;
			self.captureInfoTable[CaptureInfo_ey]					= y;
			self.captureInfoTable[CaptureInfo_my_obj_n]				= enemy_obj_n;
			self.captureInfoTable[CaptureInfo_enemy_obj_n]			= my_obj_n;
			self.captureInfoTable[CaptureInfo_my_card]				= enemy_card;
			self.captureInfoTable[CaptureInfo_enemy_card]			= my_card;
			self.captureInfoTable[CaptureInfo_my_air]				= enemy_air;
			self.captureInfoTable[CaptureInfo_enemy_air]			= my_air;
			self.captureInfoTable[CaptureInfo_my_frame]				= enemy_frame;
			self.captureInfoTable[CaptureInfo_enemy_frame]			= my_frame;
			self.captureInfoTable[CaptureInfo_my_dir]				= enemy_dir;
			self.captureInfoTable[CaptureInfo_enemy_dir]			= my_dir;
			self.captureInfoTable[CaptureInfo_my_hitstop]			= enemy_hitstop;
			self.captureInfoTable[CaptureInfo_enemy_hitstop]		= my_hitstop;
			self.captureInfoTable[CaptureInfo_my_xspeed]			= enemy_xspeed;
			self.captureInfoTable[CaptureInfo_enemy_xspeed]			= my_xspeed;
			self.captureInfoTable[CaptureInfo_my_yspeed]			= enemy_yspeed;
			self.captureInfoTable[CaptureInfo_enemy_yspeed]			= my_yspeed;
			self.captureInfoTable[CaptureInfo_my_img]				= enemy_img;
			self.captureInfoTable[CaptureInfo_enemy_img]			= my_img;
			self.captureInfoTable[CaptureInfo_my_hitarea_n]			= enemy_hitarea_n;
			self.captureInfoTable[CaptureInfo_enemy_hitarea_n]		= my_hitarea_n;
			self.captureInfoTable[CaptureInfo_my_attackarea_n]		= enemy_attackarea_n;
			self.captureInfoTable[CaptureInfo_enemy_attackarea_n]	= my_attackarea_n;
			self.captureInfoTable[CaptureInfo_my_correction]		= enemy_correction;
			self.captureInfoTable[CaptureInfo_enemy_correction]		= my_correction;
		end
	end
	
	----------------------------------------------------------------------------------------------------------
	-- キャプチャした情報の詳細を取得します。
	--	引数
	-- 		index	:取得する環境変数index。CaptureInfo_環境変数名で定義される。
	----------------------------------------------------------------------------------------------------------
	function CaptureInfo:getParameter(index)
		return self.captureInfoTable[index];
	end

	----------------------------------------------------------------------------------------------------------
	-- AI学習用のモーション値をセットします。（グレイズ用に一部拡張しているため）
	--	引数
	-- 		act		:AI学習用モーション値
	----------------------------------------------------------------------------------------------------------
	function CaptureInfo:setAct(act)
		self.act = act;
	end

	----------------------------------------------------------------------------------------------------------
	-- AI学習用の実測フレームをセットします。
	--	引数
	-- 		frameCount	:フレーム数
	----------------------------------------------------------------------------------------------------------
	function CaptureInfo:setFrame(frame)
		self.frame = frame;
	end
	
	----------------------------------------------------------------------------------------------------------
	-- 保持している値を似非CSV形式の文字列に変換します。
	--	戻り値
	--		似非CSV形式の文字列
	--
	--	TODO テーブルに格納されてる値の型も保持せんとだめだ。
	----------------------------------------------------------------------------------------------------------
	function CaptureInfo:serialize()
		-- AI学習用特殊パラメータ
		local result = "";
		result = result .. self.captureTarget .. ",";
		result = result .. self.act .. ",";
		result = result .. self.frame .. ",";
		result = result .. self.evaluate .. ",";
		
		-- 環境変数群
		for key = CaptureInfo_MIN, CaptureInfo_MAX, 1
		do
			result = result .. tostring(self.captureInfoTable[key]);
			-- 末尾に「,」はいらないよ
			if (key < #self.captureInfoTable - 1)
			then
				result = result .. ",";
			end
		end
		return result;
	end
	
	----------------------------------------------------------------------------------------------------------
	-- 似非CSV形式の文字列から環境変数情報他を復元します。
	--	引数
	--		似非CSV形式の文字列
	--
	--	TODO テーブルに格納されてる値の型も復元せんとだめだ。
	----------------------------------------------------------------------------------------------------------
	function CaptureInfo:deserialize(line)
		local count = 1;
		for value, separator in string.gmatch(line, "([^,]*)(,?)")
		do
			if (value ~= nil)
			then
				if (count == 1)
				then
					self.captureTarget = self:toVariableTypes(value);
				elseif (count == 2)
				then
					self.act = self:toVariableTypes(value);
				elseif (count == 3)
				then
					self.frame = self:toVariableTypes(value);
				elseif (count == 4)
				then
					self.evaluate = self:toVariableTypes(value);
				else
					table.insert(self.captureInfoTable, self:toVariableTypes(value));
				end
				count = count + 1;
			end
		end
	end

----------------------------------------------------------------------------------------------------------
-- 以下、テスト用
----------------------------------------------------------------------------------------------------------
function main()
	local capture = CaptureInfo.new(0);
	while (true)
	do
		if (my_act ~= 0)
		then
			capture:capture();
			print(capture:serialize());
		end
		yield();
	end
end
