Pythonでプレイヤーの道徳値を管理するモジュールを実装

このタスクでは、ゲーム「Immaculate Mirage」におけるプレイヤーの道徳値管理モジュールをPythonで実装します。プレイヤーの選択に応じて道徳値(善、中立、悪)を更新し、極端なエンディングのトリガー判定、およびボスマッチ前のキャラクター生成に使用される道徳的傾向の割合を計算する純粋関数を作成します。

関数シグネチャとデータ構造

以下の2つの関数を実装します。

from typing import Optional, Tuple, Dict
import random

def update_morality_values(
    current_round: int,
    previous_choice: Optional[str],
    current_choice: str,
    current_good: int,
    current_neutral: int,
    current_evil: int,
    consecutive_count: int
) -> Tuple[int, int, int, int, Optional[str]]:
    """
    プレイヤーの選択に基づいて道徳値を更新し、極端なエンディングの可能性を判定します。

    Args:
        current_round: 現在のゲームラウンド(1から開始)。
        previous_choice: 前回のプレイヤーの選択 ('A', 'B', 'C', 'D')。最初のラウンドではNone。
        current_choice: 今回のプレイヤーの選択 ('A', 'B', 'C', 'D')。
        current_good: 現在の善の値。
        current_neutral: 現在の中立の値。
        current_evil: 現在の悪の値。
        consecutive_count: 前回の選択からの連続回数。

    Returns:
        - updated_good: 更新後の善の値。
        - updated_neutral: 更新後の中立の値。
        - updated_evil: 更新後の悪の値。
        - next_consecutive_count: 次のラウンドに渡す連続回数。
        - ending_trigger: 極端なエンディングがトリガーされた場合の傾向 ('good', 'neutral', 'evil')、またはNone。
    """
    pass

def calculate_morality_distribution(good_val: int, neutral_val: int, evil_val: int) -> Dict[str, float]:
    """
    現在の善、中立、悪の値を基に、各傾向の割合と優勢な傾向を計算します。

    Args:
        good_val: 善の値。
        neutral_val: 中立の値。
        evil_val: 悪の値。

    Returns:
        辞書形式で以下の値を含みます:
        - 'good_ratio': 善の割合 (0.0から1.0)。
        - 'neutral_ratio': 中立の割合 (0.0から1.0)。
        - 'evil_ratio': 悪の割合 (0.0から1.0)。
        - 'dominant_tendency': 最も割合が高い傾向 ('good', 'neutral', 'evil')。合計値が0の場合はNone。
    """
    pass
    

アルゴリズムの詳細

道徳値の更新ロジック (update_morality_values)

各選択肢には、基本値、連続ボーナス、およびランダムな影響が適用されます。

1. 基本値の加算

選択肢 基本値加算 連続ボーナス対象 特殊効果
A 善 +10 なし
B 中立 +8 中立 50%の確率で善または悪に +4 のランダム偏移
C 悪 +10 なし
D 善または悪に +8 (ランダム選択) ランダムに選択された方 なし

2. 連続ボーナスの計算

連続ボーナスは、consecutive_count(現在のラウンド開始前の連続回数)に基づいて決定されます。

  • consecutive_count = 0: ボーナス 0
  • consecutive_count = 1: ボーナス 3
  • consecutive_count = 2: ボーナス 5
  • consecutive_count = 3: ボーナス 7
  • consecutive_count ≥ 4: ボーナス 8

このボーナスは、選択肢に対応する主要な道徳値(Aなら善、Cなら悪、BとDはランダムに選ばれた方)に追加されます。

3. 連続回数の更新

  • current_choice == previous_choice の場合: next_consecutive_count = consecutive_count + 1
  • それ以外の場合 (current_choice != previous_choice または最初のラウンド): next_consecutive_count = 0

4. ランダム性の処理

BとDの選択肢におけるランダムな値の決定には random.random() を使用し、50%の確率で分岐させます。テストの再現性のために、random.seed() を設定可能とします。

5. 極端なエンディングの判定

以下の条件をすべて満たす場合、極端なエンディングがトリガーされます。

  1. 現在のラウンド current_round ≥ 10
  2. 道徳値の合計 total_morality = good + neutral + evil ≥ 80
  3. いずれかの道徳値の割合が 0.9 以上 (例: good / total_morality ≥ 0.9)

条件を満たす場合、ending_trigger に対応する傾向 ('good', 'neutral', 'evil') を返します。それ以外の場合は None を返します。

道徳分布の計算 (calculate_morality_distribution)

この関数は、与えられた善、中立、悪の値から、それぞれの割合と最も高い割合を持つ「優勢な傾向」を計算します。

total = good_val + neutral_val + evil_val
if total == 0:
    return {'good_ratio': 0.0, 'neutral_ratio': 0.0, 'evil_ratio': 0.0, 'dominant_tendency': None}

ratios = {
    'good_ratio': good_val / total,
    'neutral_ratio': neutral_val / total,
    'evil_ratio': evil_val / total
}
# 最も高い割合を持つキー(傾向)を取得
dominant = max(ratios, key=ratios.get)
ratios['dominant_tendency'] = dominant
return ratios
    

テスト要件

unittest または pytest を使用して、以下のシナリオを網羅する単体テストを作成してください。

  • テスト1: 基本値加算と連続カウントの検証(Aを連続選択)。
  • テスト2: B選択肢におけるランダム偏移の確率検証(乱数シード固定)。
  • テスト3: D選択肢におけるランダム傾向選択とボーナス適用検証(乱数シード固定)。
  • テスト4: 連続カウントの中断と再開の検証。
  • テスト5: 極端なエンディングのトリガー条件(ラウンド、合計値、割合)と非トリガー条件の検証。
  • テスト6: 道徳分布計算の正確性(割合、優勢な傾向)と、合計値ゼロの場合の処理検証。
  • テスト7: 境界条件(合計値、割合がちょうど条件を満たす場合)の検証。

提出物

  • 必要なインポート文を含む、実行可能なPythonコードファイル。
  • すべてのテストケースに合格する単体テストコード。
  • コード内の主要なロジックを説明するコメント。

タグ: Python ゲーム開発 純粋関数 状態管理 アルゴリズム

5月15日 07:02 投稿