/// <summary> /// 構築 /// </summary> /// <param name="player">選手</param> /// <param name="defensePosition">守備位置</param> public GameMember(Player player, DefensePosition defensePosition) { Player = player; DefensePosition = defensePosition; // 初期値設定 UseKind = UseKind.Normal; BattingResults = new List<BattingResultKind>(); PitchingResult = new PitchingResult(); // 残り体力全開 ClearRemainingStamina(); }
/// <summary> /// 送球準備時間を取得する /// </summary> /// <param name="defensePosition">送球守備位置</param> /// <returns>送球準備時間</returns> private int GetThrowPrepareTime(DefensePosition defensePosition) { return GetThrowPrepareTime(GameData.GetDefenseMemberAbility(defensePosition)); }
/// <summary> /// 送球のための回転開始から送球完了までの時間を取得 /// </summary> /// <param name="targetBase">送球先ベース</param> /// <param name="throwPosition">送球ポジション</param> /// <param name="startPoint">送球開始位置</param> /// <param name="memberAbility">送球メンバ能力</param> /// <returns>かかる時間時間</returns> private int GetThrowBollReachTimeFromTurn(int targetBase, DefensePosition throwPosition, MPoint startPoint, GameMemberAbility memberAbility) { // 送球開始から完了までの時間を取得 int throwTime = GetThrowBollReachTime(targetBase, throwPosition, startPoint); // 送球前の回転が必要な場合は余分に時間を加算 if (NeedTurnForThrow(memberAbility, targetBase, startPoint)) { throwTime += Constants.TurnForThrowTime; } return throwTime; }
/// <summary> /// 概ね適性のある守備位置か /// </summary> /// <param name="position">指定された守備位置</param> /// <param name="type">対象メンバの守備適性</param> /// <returns>適性か</returns> public static bool MostFitDefensePosition(DefensePosition position, DefenseType type) { // 内野か外野のいずれかであれば概ね適正有りとする if (IsInFielder(type)) { if (position == DefensePosition.First || position == DefensePosition.Second || position == DefensePosition.Third || position == DefensePosition.Short) { return true; } } if (IsOutFielder(type)) { if (position == DefensePosition.Right || position == DefensePosition.Center || position == DefensePosition.Left) { return true; } } return false; }
/// <summary> /// 指定した守備位置が外野か /// </summary> /// <param name="position"></param> /// <returns></returns> public static bool IsOutFielder(DefensePosition position) { return position == DefensePosition.Right || position == DefensePosition.Center || position == DefensePosition.Left; }
/// <summary> /// 守備位置に対して最も適性な守備適性を返す /// </summary> /// <param name="position"></param> /// <returns></returns> public static DefenseType ConvertDefenseType(DefensePosition position) { switch (position) { case DefensePosition.Pitcher: return DefenseType.Pitcher; case DefensePosition.Catcher: return DefenseType.Catcher; case DefensePosition.First: return DefenseType.First; case DefensePosition.Second: return DefenseType.Second; case DefensePosition.Third: return DefenseType.Third; case DefensePosition.Short: return DefenseType.Short; case DefensePosition.Right: return DefenseType.Right; case DefensePosition.Center: return DefenseType.Center; case DefensePosition.Left: return DefenseType.Left; case DefensePosition.Sub: // 控えの場合、例外が発生しないように適当なenumを返しておく // (UIのConverterで一時的に実行されることがあるため) return DefenseType.Nothing; default: throw new Exception("Invalid DefensePosition"); } }
/// <summary> /// 指定した守備位置のメンバがベースカバーに入っているか /// </summary> /// <param name="defensePosition"></param> /// <returns></returns> public bool IsBaseCover(DefensePosition defensePosition) { return (defensePosition == BaseCoverPosition[1] || defensePosition == BaseCoverPosition[2] || defensePosition == BaseCoverPosition[3] || defensePosition == BaseCoverPosition[4]); }
/// <summary> /// 打撃結果の設定(凡退) /// </summary> /// <param name="defensePosition"></param> private void SetBattingResultByOut(DefensePosition defensePosition) { if (GameData.LatestBattingResult != BattingResultKind.Invalid) { if (CurrentBatterForceOutCount < 2) { // すでに打撃結果を設定済みであれば何もしない return; } else { // すでに打撃結果を設定済みもゴロで2アウト以上にした場合は併殺の記録に変更する // (三重殺はどうせ発生は稀なので併殺の記録とまとめる) string resultString = CatchPosition.ToString() + "GetTwo"; GameData.LatestBattingResult = (BattingResultKind)System.Enum.Parse(typeof(BattingResultKind), resultString, true); return; } } // 凡退と認識した場合は打撃結果を設定 // (フライアウトかゴロで元の塁か次の塁でアウトになった場合のみ凡退とする) if (CurrentFlyOut || CurrentBatterForceOutCount > 0) { // 打撃結果の文字列生成 string resultString = defensePosition.ToString(); if (CurrentFlyOut) { // フライの場合 resultString += "Fly"; } else { // ゴロの場合 resultString += "Ground"; } // 打撃結果の設定 GameData.LatestBattingResult = (BattingResultKind)System.Enum.Parse(typeof(BattingResultKind), resultString, true); } }
/// <summary> /// 指定した野手のコントロールを取得する /// </summary> /// <param name="position">ポジション</param> /// <returns>コントロール</returns> private FrameworkElement GetDefenseControl(DefensePosition position) { switch (position) { case DefensePosition.Pitcher: return Defense1; case DefensePosition.Catcher: return Defense2; case DefensePosition.First: return Defense3; case DefensePosition.Second: return Defense4; case DefensePosition.Third: return Defense5; case DefensePosition.Short: return Defense6; case DefensePosition.Left: return Defense7; case DefensePosition.Center: return Defense8; case DefensePosition.Right: return Defense9; default: throw new Exception("Invalid DefensePosition"); } }
/// <summary> /// 指定した守備位置の現在位置を設定する /// </summary> /// <param name="defensePosition">指定する守備</param> /// <param name="point">設定値</param> public void SetDefensePoint(DefensePosition defensePosition, MPoint point) { switch (defensePosition) { case DefensePosition.Pitcher: Defense1Point = point; break; case DefensePosition.Catcher: Defense2Point = point; break; case DefensePosition.First: Defense3Point = point; break; case DefensePosition.Second: Defense4Point = point; break; case DefensePosition.Third: Defense5Point = point; break; case DefensePosition.Short: Defense6Point = point; break; case DefensePosition.Left: Defense7Point = point; break; case DefensePosition.Center: Defense8Point = point; break; case DefensePosition.Right: Defense9Point = point; break; default: throw new Exception("Invalid DefensePosition"); } }
/// <summary> /// 指定した守備位置の現在位置を取得する /// </summary> /// <param name="defensePosition">指定する守備</param> /// <returns>現在位置</returns> public MPoint GetDefensePoint(DefensePosition defensePosition) { switch (defensePosition) { case DefensePosition.Pitcher: return Defense1Point; case DefensePosition.Catcher: return Defense2Point; case DefensePosition.First: return Defense3Point; case DefensePosition.Second: return Defense4Point; case DefensePosition.Third: return Defense5Point; case DefensePosition.Short: return Defense6Point; case DefensePosition.Left: return Defense7Point; case DefensePosition.Center: return Defense8Point; case DefensePosition.Right: return Defense9Point; default: throw new Exception("Invalid DefensePosition"); } }
/// <summary> /// 指定した守備位置のメンバ能力を取得する /// </summary> /// <param name="defensePosition">指定する守備位置</param> /// <returns>メンバ能力</returns> public GameMemberAbility GetDefenseMemberAbility(DefensePosition defensePosition) { GameMember member = GetDefenseMember(defensePosition); return new GameMemberAbility(member, this); }
/// <summary> /// 指定した守備位置のメンバを取得する /// </summary> /// <param name="defensePosition">指定する守備位置</param> /// <returns>メンバ</returns> public GameMember GetDefenseMember(DefensePosition defensePosition) { if (defensePosition == DefensePosition.Sub) { Assertion.Assert(defensePosition != DefensePosition.Sub, "defensePosition != DefensePosition.Sub"); return null; } GameMember member = CurrentDefenseTeam.CurrentPlayingMembers.Single(m => m.DefensePosition == defensePosition); return member; }
/// <summary> /// 送球開始の回転からタッチアウトまでにかかる時間を取得 /// (ベースカバーが遅れて自分でベースまで走る場合も考慮) /// </summary> /// <param name="targetBase">送球先ベース</param> /// <param name="throwPosition">送球ポジション</param> /// <param name="startPoint">送球開始位置</param> /// <param name="memberAbility">送球メンバ能力</param> /// <param name="passedTime">送球開始までに現在時刻からさらに経過している時間(捕球前の予測で使用)</param> /// <returns>かかる時間時間</returns> private int GetThrowTimeFromTurnToTouch(int targetBase, DefensePosition throwPosition, MPoint startPoint, GameMemberAbility memberAbility, int passedTime) { // 送球前の回転から送球完了までの時間の算出 int throwTime = GetThrowBollReachTimeFromTurn(targetBase, throwPosition, startPoint, memberAbility); // ベースカバー完了までの時間を算出(送球開始までにさらに経過している時間は減算) int baseCoverTime = BaseCoverRemainingTime[targetBase] - passedTime; if (baseCoverTime > throwTime) { // ベースカバー完了の方が遅ければ、それが送球完了時間となる // (送球完了時にベースカバー完了するタイミングまで送球開始を待つため) throwTime = baseCoverTime; // 自分でベースまで走った場合と比較してどちらが速いか検証する int throwTimeByRun = GetThrowBollReachTime(targetBase, throwPosition, startPoint, true); if (throwTimeByRun < throwTime) { // 自分でベースまで走った方が早ければ、その時間を送球時間とする throwTime = throwTimeByRun; } } // フォースアウトでも帰塁ランナーのアウトでもなければ // タッチアウト体制への準備時間を加算する if (!IsForceOut(targetBase) && GetBackRunRunner(targetBase) == null) { throwTime += Constants.ReadyingTouchSecond; } // かかる時間を返す return throwTime; }
/// <summary> /// 指定した守備位置に対しての守備要員として能力値(守備固め判定に利用) /// </summary> /// <param name="position">守備位置</param> /// <returns>守備要員としての能力値</returns> public double GetDefenseAbility(DefensePosition position) { double defenseValue; if (DefenseTypeHelper.FitDefensePosition(position, DefenseType)) { // 守備位置の適正がある場合 defenseValue = Defense; } else if (DefenseTypeHelper.MostFitDefensePosition(position, DefenseType)) { // 概ね適正がある場合 defenseValue = Defense - Constants.DownDefenseByMostFit; } else { // 適正がない場合 defenseValue = Defense - Constants.DownDefenseByUnFit; } // 守備:走力:智力=4:1:1 // (内野と外野と捕手で走力の重要度が異なるため適当な比率) return (defenseValue * 4.0 + Run + Wisdom) / 6; }
/// <summary> /// 送球前の回転にかかる時間を取得する /// </summary> /// <param name="position">送球する守備位置</param> /// <param name="targetBase">送球先ベース</param> /// <param name="throwStartPoint">送球開始位置</param> /// <returns>かかる時間</returns> private int GetTurningForThrowTime(DefensePosition position, int targetBase, MPoint throwStartPoint) { GameMemberAbility throwMemberAbility = GameData.GetDefenseMemberAbility(position); if (NeedTurnForThrow(throwMemberAbility, targetBase, throwStartPoint)) { return Constants.TurnForThrowTime; } else { return 0; } }
/// <summary> /// 指定した守備位置のメンバを取得 /// </summary> /// <param name="position"></param> /// <returns></returns> public GameMember GetMember(DefensePosition position) { return CurrentPlayingMembers.First(m => m.DefensePosition == position); }
/// <summary> /// 指定したランナーをアウトにする /// </summary> /// <param name="runnerStatus">アウトにするランナー</param> /// <param name="defensePosition">アウトにする守備位置</param> /// <param name="isAssistOut">捕殺か(捕殺ならtrue、刺殺ならfalse)</param> private void SetOutRunner(RunnerStatus runnerStatus, DefensePosition defensePosition, bool isAssistOut = true) { // アウトカウントの加算 CurrentBatterOutCount++; // 併殺のためのアウトカウント加算 // ゴロであり、元の塁か次の塁でアウトになった場合のみカウント // (ゴロで元の塁でアウトになるのはレアケースだが一応考慮しておく) // (フライアウト、帰塁できないアウト、オーバーランはカウントしない) if (!CurrentFlyOut && (runnerStatus.TargetBase == runnerStatus.RunnerNumber || runnerStatus.TargetBase == runnerStatus.RunnerNumber + 1)) { CurrentBatterForceOutCount++; } // 打撃結果の設定 SetBattingResultByOut(defensePosition); // 指定したランナーをアウトにする GameData.SetOutRunner(runnerStatus.RunnerNumber); // 捕殺・刺殺の加算 GameData.GetDefenseMember(defensePosition).AddOutCount(isAssistOut); // アウトのイベント発行 if (JudgedSafeOrOut != null) { JudgedSafeOrOut(false); } }
/// <summary> /// 起用の種類を考慮し、指定の守備位置で最も守備要員としての能力が高い控え野手を取得する /// (候補がいない場合はnullを返す) /// </summary> /// <param name="defensePosition">守備位置</param> /// <returns>控え野手</returns> public GameMember GetSubFielder(DefensePosition defensePosition) { // 起用の種類が「通常」か「守備要員」で投手以外のメンバを対象とする List<GameMember> candidateMembers = CurrentSubMembers.Where(m => (m.UseKind == UseKind.Normal || m.UseKind == UseKind.Defense) && !m.IsPitcher).ToList(); // 守備要員としての能力が最も高いメンバを返す return candidateMembers.OrderByDescending(m => m.Player.FielderAbility.GetDefenseAbility(defensePosition)).FirstOrDefault(); }
/// <summary> /// 指定したベースカバーに入るポジションを設定する /// </summary> /// <param name="baseNumber">指定する守備位置</param> /// <param name="defensePosition">ベースカバーするポジション</param> public void SetBaseCoverPosition(int baseNumber, DefensePosition defensePosition) { BaseCoverPosition[baseNumber] = defensePosition; }
/// <summary> /// 送球開始から完了までの時間を取得 /// </summary> /// <param name="targetBase">送球先ベース</param> /// <param name="throwPosition">送球ポジション</param> /// <param name="startPoint">送球開始位置</param> /// <returns>送球が届くまでの時間</returns> private int GetThrowBollReachTime(int targetBase, DefensePosition throwPosition, MPoint startPoint) { // 送球中の時間 int throwBollReachTime = GetThrowBollReachTime(targetBase, throwPosition, startPoint, false); // 送球中の時間 return throwBollReachTime; }
/// <summary> /// 指定した守備位置が内野か(投手、捕手を含む) /// </summary> /// <param name="position"></param> /// <returns></returns> public static bool IsInFielder(DefensePosition position) { return position == DefensePosition.Pitcher || position == DefensePosition.Catcher || position == DefensePosition.First || position == DefensePosition.Second || position == DefensePosition.Third || position == DefensePosition.Short; }
/// <summary> /// 送球開始から完了までの時間を取得 /// </summary> /// <param name="targetBase">送球先ベース</param> /// <param name="throwPosition">送球ポジション</param> /// <param name="startPoint">送球開始位置</param> /// <param name="runTargetBase">送球先に自分が走ってベースカバーに行くか</param> /// <returns>送球が届くまでの時間</returns> private int GetThrowBollReachTime(int targetBase, DefensePosition throwPosition, MPoint startPoint, bool runTargetBase) { // 送球メンバ能力の取得 GameMemberAbility memberAbility = GameData.GetDefenseMemberAbility(throwPosition); // 送球が届くまでの時間を取得 return GetThrowBollReachTime(targetBase, memberAbility, startPoint, runTargetBase); }
/// <summary> /// 指定した守備位置が控えか /// </summary> /// <param name="position"></param> /// <returns></returns> public static bool IsSub(DefensePosition position) { return position == DefensePosition.Sub; }
/// <summary> /// 指定した守備位置が指定した守備適性で適性があるか /// </summary> /// <param name="position">指定された守備位置</param> /// <param name="type">対象の守備適性</param> /// <returns>適性か</returns> public static bool FitDefensePosition(DefensePosition position, DefenseType type) { // 守備位置と適性が一致する場合は適性有り DefenseType convertDefenseType = DefensePositionHelper.ConvertDefenseType(position); bool isFit = convertDefenseType == type; // 適性が「内野手」「外野手」の場合は、内野・外野のいずれかであれば適正有りとする if (type == DefenseType.Infielder) { if (position == DefensePosition.First || position == DefensePosition.Second || position == DefensePosition.Third || position == DefensePosition.Short) { isFit = true; } } if (type == DefenseType.Outfielder) { if (position == DefensePosition.Right || position == DefensePosition.Center || position == DefensePosition.Left) { isFit = true; } } return isFit; }