----------------------------------------------------------------------------------------------------------
-- 
-- 行動再生スレッド
-- 
-- 続きで覚えないでフラットに覚えるように変更。
-- 
----------------------------------------------------------------------------------------------------------
actionManager=ActionManager.new(runningAction);

----------------------------------------------------------------------------------------------------------
-- 実行動スレッド 総元締め
----------------------------------------------------------------------------------------------------------
function actionThread()

	-- tracerの初期化が終わるまで待つ。
	yield();

	logger:info("行動スレッド", "行動スレッド総元締め起動");

	-- selector登録
	--actionManager:addSelector(ActionSelector.new(AI_NAME_OFFENSIVE,	evaluateSituation,	DEFAULT_RELATION_PROPOSAL_SIZE,	20),	everyTime);

	actionManager:addSelector(ActionSelector.new(AI_NAME_OFFENSIVE,	evaluateSituation,	DEFAULT_RELATION_PROPOSAL_SIZE,	20),	offensiveSituation);
	actionManager:addSelector(ActionSelector.new(AI_NAME_KATAME,	evaluateSituation,	DEFAULT_RELATION_PROPOSAL_SIZE,	20),	katameSituation);
	actionManager:addSelector(ActionSelector.new(AI_NAME_OIUCHI,	evaluateSituation,	DEFAULT_RELATION_PROPOSAL_SIZE,	20),	oiuchiSituation);
	--actionManager:addSelector(ActionSelector.new(AI_NAME_DEFENSIVE,	evaluateSituation,	DEFAULT_RELATION_PROPOSAL_SIZE,	20),	defensiveSituation);

	--actionManager:addSelector(ActionSelectorForFlatTable.new(AI_NAME_GUARD,	evaluateSituation,	DEFAULT_RELATION_PROPOSAL_SIZE,	100),	defensiveSituation);

	-- あとでインタラプト扱いに
	actionManager:addInterrupter(ActionSelectorForFlatTable.new(AI_NAME_GUREIZU,	evaluateSituation,	100),	gureizuSituation);


	-- 行動再生スレッド起動
	create_thread(actionPlayThread);

	while (not battleFinished())
	do
		if (battle_time % 100 == 0)
		then
			--logger:debug("行動スレッド総元締め", "基本:" .. #BASIC_MOTIONS .. " 攻撃:" .. #ATTACK_MOTIONS .. " ガード:" .. #GUARD_MOTIONS .. " 被ダメ:" .. #DAMAGE_MOTIONS);
		end
		yield();
	end
	logger:info("行動スレッド", "行動スレッド総元締め終了");
end

----------------------------------------------------------------------------------------------------------
-- 基本行動スレッド
----------------------------------------------------------------------------------------------------------
function actionPlayThread()
	actionManager:action();
end

----------------------------------------------------------------------------------------------------------
-- 行動条件評価判定
--	シグモイド関数を利用した誤差で評価。0に近いほど評価が高い。
--	各種パラメータ評価の平均値で全体を評価。加重平均値なので重み付け可能。
----------------------------------------------------------------------------------------------------------
function evaluateSituation(captureInfo)
	--[[
	if (isIncrementAirMotion(captureInfo.act))
	then
		print("↓飛翔しない原因デバッグ  act:" .. captureInfo.act, "y:" .. y, "cap.y:" .. captureInfo:getParameter(CaptureInfo_y), "my_air:" .. my_air, "cap.my_air:" .. captureInfo:getParameter(CaptureInfo_my_air));
	end
	]]--

	------------------------------------------------------------------------------------------------
	-- 一致してなかったら評価するまでもないやつ
	--	・正面向いてるか否か。
	--	・自キャラが一致してない。
	--	・敵キャラが一致してない。
	------------------------------------------------------------------------------------------------
	if ((captureInfo:getParameter(CaptureInfo_is_dir_front) ~= is_dir_front) or
		(captureInfo:getParameter(CaptureInfo_my_char) ~= my_char))
	then
		--print(captureInfo.act, "向きが違う");
		-- 最大の差を返して絶対通らないように。
		return DEFAULT_THRESHOLDS;
	end
	------------------------------------------------------------------------------------------------
	-- 一致してなかったら評価するまでもないやつ2
	--	・花曇時、台風時に評価するcaptureInfoの天気が一致しない場合。
	------------------------------------------------------------------------------------------------
	-- ストールするので除外
	--[[
	if (
		--((weather == 13) or (weather == 5)) and
		(weather == 5) and
		(captureInfo:getParameter(CaptureInfo_weather) ~= weather)
	   )
	then
		--print(captureInfo.act, "天候違い");
		return DEFAULT_THRESHOLDS;
	end
	]]--
	------------------------------------------------------------------------------------------------
	-- 一致してなかったら評価するまでもないやつ3
	--	空中と地上行動を明確に分離
	------------------------------------------------------------------------------------------------
	if (
		((captureInfo:getParameter(CaptureInfo_y) == 0) and (y ~= 0)) or
		((captureInfo:getParameter(CaptureInfo_y) ~= 0) and (y == 0))
	   )
	then
		--print(captureInfo.act, "地上空中違い");
		return DEFAULT_THRESHOLDS;
	end
	------------------------------------------------------------------------------------------------
	-- 一致してなかったら評価するまでもないやつ4
	--	カード実行時にカード利用できる状態じゃなけりゃダメ
	------------------------------------------------------------------------------------------------
	if (isCardUseMotion(captureInfo.act) and 
			(not 
				(
					(my_card == cardIdResolver:getCardId(captureInfo.act)) and is_card_use
				)
			)
		)
--			(not ((my_card == captureInfo:getParameter(CaptureInfo_my_card)) and is_card_use)))
	then
		--[[
		logger:debug("evaluate", " cardId:" .. cardIdResolver:getCardId(captureInfo.act) .. 
								 " my_card:" .. my_card ..
								 " is_card_use:" .. tostring(is_card_use) ..
								 " captureInfo.act:" .. captureInfo.act);
		]]--
		return DEFAULT_THRESHOLDS;
	end
	------------------------------------------------------------------------------------------------
	-- 一致してなかったら評価するまでもないやつ5
	--	飛翔回数 遥か上空お空に飛んでいくのはNGです。
	--	飛翔行動直後にmy_airが加算されるため、+1してイコールで結べるか。
	------------------------------------------------------------------------------------------------
	if (isIncrementAirMotion(captureInfo.act) and (y > 0) and (captureInfo:getParameter(CaptureInfo_my_air) ~= my_air + 1))
	    or ((not isIncrementAirMotion(captureInfo.act)) and (y > 0) and (captureInfo:getParameter(CaptureInfo_my_air) ~= my_air))
	--if ((y > 0) and (captureInfo:getParameter(CaptureInfo_my_air) ~= my_air))
	then
		--print(captureInfo.act, "飛翔回数違い", captureInfo:getParameter(CaptureInfo_my_air), my_air);
		return DEFAULT_THRESHOLDS;
	end
	------------------------------------------------------------------------------------------------
	-- 一致してなかったら評価するまでもないやつ6
	--	相手が空中かどうかで分割判断する。
	------------------------------------------------------------------------------------------------
	if (
		((captureInfo:getParameter(CaptureInfo_ey) == 0) and (ey ~= 0)) or
		((captureInfo:getParameter(CaptureInfo_ey) ~= 0) and (ey == 0))
	   )
	then
		--print(captureInfo.act, "敵の地上空中違い");
		--return DEFAULT_THRESHOLDS;
	end
	------------------------------------------------------------------------------------------------
	-- 一致してなかったら評価するまでもないやつ7
	--	霊力使用行動で霊球が1未満の場合
	------------------------------------------------------------------------------------------------
	if (isUseReiMotion(captureInfo.act) and my_rei < 200)
	then
		--print(captureInfo.act, "霊力足りない");
		return DEFAULT_THRESHOLDS;
	end
	------------------------------------------------------------------------------------------------
	-- 一致してなかったら評価するまでもないやつ8
	--	攻撃キャンセル行動。hitstopで判断
	------------------------------------------------------------------------------------------------
	if (
		isBlowMotion(captureInfo.act) and
		((captureInfo:getParameter(CaptureInfo_enemy_hitstop) > 0) and (enemy_hitstop == 0))
		or
		((captureInfo:getParameter(CaptureInfo_enemy_hitstop) == 0) and (enemy_hitstop > 0))
	   )
	then
		--print(captureInfo.act, "ヒットストップ関連");
		--return DEFAULT_THRESHOLDS;
	end

	-- 平均値算出用インスタンス
	local calculator = AverageCalculator.new();


	------------------------------------------------------------------------------------------------
	-- 敵キャラ判定 2値判定。敵が別キャラでもそれなりに動けるようにしとく。
	------------------------------------------------------------------------------------------------
	calculator:addValue(evaluateBinary(captureInfo:getParameter(CaptureInfo_enemy_char) == enemy_char), 4);

	------------------------------------------------------------------------------------------------
	-- 下飛翔促進 なるべく飛びっぱなしにならないようバイアスかける
	------------------------------------------------------------------------------------------------
	if (my_air == 1)
	then
		calculator:addValue(evaluateBinary(((captureInfo:getParameter(CaptureInfo_my_act) >= 2141) and (captureInfo:getParameter(CaptureInfo_my_act) <= 2143))), 10);
	end

	------------------------------------------------------------------------------------------------
	-- 座標x 判定 壁際だけ厳密に判定
	------------------------------------------------------------------------------------------------
	calculator:addValue(evaluateMargin(getRelativePositionX(captureInfo:getParameter(CaptureInfo_x)), getRelativePositionX(x), DEFAULT_GAIN), 40);
	calculator:addValue(evaluateMargin(getRelativePositionX(captureInfo:getParameter(CaptureInfo_ex)), getRelativePositionX(ex), DEFAULT_GAIN), 40);
	--calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_x), x, DEFAULT_GAIN), 15);
	--calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_ex), ex, DEFAULT_GAIN), 15);
	
	------------------------------------------------------------------------------------------------
	-- 座標y 判定 地上行動か空中行動かで閾値をかえる
	------------------------------------------------------------------------------------------------
	calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_y), y, DEFAULT_GAIN), 30);
	calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_ey), ey, DEFAULT_GAIN), 30);
	calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_y) - captureInfo:getParameter(CaptureInfo_ey), y - ey, DEFAULT_GAIN), 40);

	------------------------------------------------------------------------------------------------
	-- 相対距離評価 X座標を相対位置で評価するなら相対距離も同一の重みで判定する。
	------------------------------------------------------------------------------------------------
	if (isDamageMotion(getTargetAct(TARGET_ENEMY)) or isGuardMotion(getTargetAct(TARGET_ENEMY)))
	then
		-- hitstop中は条件緩和
		calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_dis_x), dis_x, DEFAULT_GAIN), 10);
		calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_dis_y), dis_y, DEFAULT_GAIN), 10);
		calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_dis2), dis2, DEFAULT_GAIN), 10);
	else
		calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_dis_x), dis_x, DEFAULT_GAIN), 40);
		calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_dis_y), dis_y, DEFAULT_GAIN), 40);
		calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_dis2), dis2, DEFAULT_GAIN), 40);
	end

	------------------------------------------------------------------------------------------------
	-- 敵の攻撃オブジェクト距離評価 相手行動学習時に取れないのでNG
	------------------------------------------------------------------------------------------------
	--calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_obj_dis), obj_dis, DEFAULT_GAIN), 6);
	------------------------------------------------------------------------------------------------
	-- ヒットストップ評価
	------------------------------------------------------------------------------------------------
	--calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_my_hitstop), my_hitstop, DEFAULT_GAIN), 1);
	--calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_enemy_hitstop), enemy_hitstop, DEFAULT_GAIN), 1);
	------------------------------------------------------------------------------------------------
	-- 移動速度評価
	------------------------------------------------------------------------------------------------
	calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_my_xspeed), my_xspeed, DEFAULT_GAIN), 10);
	calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_my_yspeed), my_yspeed, DEFAULT_GAIN), 10);
	calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_enemy_xspeed), enemy_xspeed, DEFAULT_GAIN), 10);
	calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_enemy_yspeed), enemy_yspeed, DEFAULT_GAIN), 10);
	------------------------------------------------------------------------------------------------
	-- 霊力評価 差分
	------------------------------------------------------------------------------------------------
	if (isUseReiMotion(captureInfo.act))
	then
		calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_my_rei), my_rei, DEFAULT_GAIN), 5);
	elseif (isGureizuMotion(captureInfo.act))
	then
		calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_my_rei), my_rei, DEFAULT_GAIN), 3);
	end
	--calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_enemy_rei) <= enemy_rei), 1);
	------------------------------------------------------------------------------------------------
	-- HP評価
	------------------------------------------------------------------------------------------------
	--calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_my_hp), my_hp, DEFAULT_GAIN), 1);
	--calculator:addValue(evaluateMargin(captureInfo:getParameter(CaptureInfo_enemy_hp), enemy_hp, DEFAULT_GAIN), 1);


	------------------------------------------------------------------------------------------------
	-- コンボ評価 コンボ中なら2値で評価
	------------------------------------------------------------------------------------------------
	calculator:addValue(evaluateBinary((captureInfo:getParameter(CaptureInfo_my_combo) > 0) and (my_combo > 0)), 0.5);
	------------------------------------------------------------------------------------------------
	-- 向き評価
	------------------------------------------------------------------------------------------------
	calculator:addValue(evaluateBinary((captureInfo:getParameter(CaptureInfo_my_dir) == my_dir)), 3);
	calculator:addValue(evaluateBinary((captureInfo:getParameter(CaptureInfo_enemy_dir) == enemy_dir)), 3);


	------------------------------------------------------------------------------------------------
	-- 天気はあってるかどうかなので2値で評価
	------------------------------------------------------------------------------------------------
	if ((weather == 13) or (weather == 5))
	then
		calculator:addValue(evaluateBinary(captureInfo:getParameter(CaptureInfo_weather) == weather), 40);
	else
		calculator:addValue(evaluateBinary(captureInfo:getParameter(CaptureInfo_weather) == weather), 10);
	end
	------------------------------------------------------------------------------------------------
	-- 霊力評価
	------------------------------------------------------------------------------------------------
	--calculator:addValue(evaluateBinary(captureInfo:getParameter(CaptureInfo_my_rei) >= my_rei), 1);
	--calculator:addValue(evaluateBinary(captureInfo:getParameter(CaptureInfo_enemy_rei) <= enemy_rei), 1);
	------------------------------------------------------------------------------------------------
	-- 飛翔回数評価
	------------------------------------------------------------------------------------------------
	--calculator:addValue(evaluateBinary(captureInfo:getParameter(CaptureInfo_my_air) <= my_air), 1);
	--calculator:addValue(evaluateBinary(captureInfo:getParameter(CaptureInfo_enemy_air) <= enemy_air), 1);
	------------------------------------------------------------------------------------------------
	-- 行動値評価
	------------------------------------------------------------------------------------------------
	calculator:addValue(evaluateBinary(captureInfo:getParameter(CaptureInfo_my_act) == getTargetCurrentAction(TARGET_MY)), 1);
	calculator:addValue(evaluateBinary(captureInfo:getParameter(CaptureInfo_enemy_act) == getTargetCurrentAction(TARGET_ENEMY)), 3);
	--[[
	calculator:addValue(evaluateBinary(captureInfo.act == getCurrentAction(my_act, my_xspeed, my_yspeed)), 2);
	calculator:addValue(evaluateBinary(getCurrentAction(captureInfo:getParameter(CaptureInfo_enemy_act),
														captureInfo:getParameter(CaptureInfo_enemy_xspeed),
														captureInfo:getParameter(CaptureInfo_enemy_yspeed)) 
										== getCurrentAction(enemy_act, enemy_xspeed, enemy_yspeed)), 2);
	]]--
	calculator:addValue(evaluateBinary(captureInfo:getParameter(CaptureInfo_my_img) == my_img), 0.2);
	calculator:addValue(evaluateBinary(captureInfo:getParameter(CaptureInfo_enemy_img) == enemy_img), 0.2);

	calculator:addValue(evaluateBinary(captureInfo:getParameter(CaptureInfo_enemy_correction) == enemy_correction), 15);

	-- 平均値算出
	return calculator:average();
end

-- 以下使ってない･･･と思う。
----------------------------------------------------------------------------------------------------------
-- 状況一致度点数を返します。
----------------------------------------------------------------------------------------------------------
function getEvaluatePoint(match, pointIfTrue, pointIfFalse)
	if (match)
	then
		return pointIfTrue;
	end
	return pointIfFalse;
end

----------------------------------------------------------------------------------------------------------
-- 画面のX軸中心を 0 とした相対X座標を返します。
----------------------------------------------------------------------------------------------------------
function getRelativePositionX(position)
	if (position == nil)
	then
		return 0
	end
	return math.abs(position - 640); -- ステージによって違う？
end

----------------------------------------------------------------------------------------------------------
-- 敵モーション種別判定
--  ガードモーションである場合 true。回避結界含む。
----------------------------------------------------------------------------------------------------------
function isEnemyGuardMotion(captureInfo)
	return  (
				(enemy_act >= 150) and (enemy_act < 170)
			)
			or 
			(
				(enemy_act >= 220) and (enemy_act <= 226)
			);
end

----------------------------------------------------------------------------------------------------------
-- 敵モーション種別判定
--  被ダメージモーションである場合 true
----------------------------------------------------------------------------------------------------------
function isEnemyDamageMotion(captureInfo)
	return (enemy_act >= 50) and (enemy_act < 99);
end


----------------------------------------------------------------------------------------------------------
-- 敵モーション種別判定
--  Hitstop中である場合 true
----------------------------------------------------------------------------------------------------------
function isEnemyHitstop(captureInfo)
	return enemy_hitstop > 0;
end

