Flaskで作る「キャリア・クエスト」- キャリアシミュレーションゲームの開発と今後の展望

## はじめに

こんにちは。今回は、Flaskを使用して開発中の「キャリア・クエスト」というWebアプリケーションについて紹介します。このアプリは、ユーザーが仮想的に様々なキャリアパスを体験し、自己理解を深めることができる革新的なプラットフォームを目指しています。

## アプリケーションの概要

「キャリア・クエスト」は以下の主要機能を持っています：

1. ユーザー登録と適性診断
2. キャリアシミュレーションゲーム
3. タイムラインとアイテム管理
4. 未来の自分との対話機能（開発中）

それでは、各機能の実装について詳しく見ていきましょう。

## 1. ユーザー登録と適性診断

ユーザー登録時に、10の質問からなる適性診断を行います。これにより、ユーザーに最適な業界を提案します。

```python
@app.route('/register', methods=['GET', 'POST'])
def register():
    questions = [
        "新しい技術やツールを学ぶことにワクワクしますか？",
        "ものづくりや製品開発に興味がありますか？",
        # ... 他の質問 ...
    ]
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        answers = [int(request.form[f'q{i}']) for i in range(1, 11)]
        industry, aptitude_scores = determine_aptitude(answers)
        
        new_user = User(
            username=username,
            password=password,
            industry=industry,
            aptitude_scores=json.dumps(aptitude_scores),
            time_crystals=1  # 新規登録時に1個のタイムクリスタルを配布
        )
        db.session.add(new_user)
        db.session.commit()
        
        flash('新規登録キャンペーン!タイムクリスタル1個配布中!', 'success')
        return render_template('registration_result.html', industry=industry, aptitude_scores=aptitude_scores)
    
    return render_template('register.html', questions=questions)
```

適性診断の結果は、`determine_aptitude`関数で計算されます。この関数では、ユーザーの回答と各業界の重みを比較し、最適な業界を決定します。

## 2. キャリアシミュレーションゲーム

ゲームの核心部分は、ユーザーが様々な選択を行い、キャリアパスを形成していくプロセスです。

```python
@app.route('/game')
def game():
    if 'user_id' not in session:
        return redirect(url_for('login'))
    
    user = db.session.get(User, session['user_id'])
    if not user:
        flash('ユーザーが見つかりません。', 'error')
        return redirect(url_for('login'))
    
    career_path = json.loads(user.career_path)
    current_state = career_path[-1] if career_path else "start"
    next_choice = get_next_choice(current_state)
    
    can_go_back = len(career_path) > 1 and user.time_crystals > 0
    
    if not next_choice['choices']:
        return redirect(url_for('game_over'))
    
    choices = list(next_choice['choices'].keys())
    
    return render_template('game.html', user=user, career_path=career_path, 
                           next_question=next_choice['question'], choices=choices,
                           can_go_back=can_go_back)
```

選択肢は`career_choices`辞書で定義されており、各選択がどの次の状態につながるかを指定しています。

## 3. タイムラインとアイテム管理

ユーザーの選択はタイムラインとして記録され、特定のイベントでアイテム（主にタイムクリスタル）を獲得します。

```python
@app.route('/make_choice', methods=['POST'])
def make_choice():
    # ... 前略 ...
    timeline = json.loads(user.timeline)
    timeline.append({
        'state': next_state,
        'question': next_choice['question'],
        'choice': choice,
        'timestamp': datetime.utcnow().isoformat(),
        'crystals_used': 0,
        'is_important': current_state == "career_choice_event"  # 重要な分岐点かどうか
    })
    user.timeline = json.dumps(timeline)
    # ... 後略 ...
```

### タイムクリスタルの実装

タイムクリスタルは、過去の選択に戻るために使用できる特別なアイテムとして実装されています。

```python
@app.route('/use_time_crystal', methods=['POST'])
def use_time_crystal():
    # ... 前略 ...
    cost = calculate_time_crystal_cost(career_path[-1])
    if user.time_crystals < cost:
        return jsonify({"success": False, "message": f"タイムクリスタルが足りません。必要数: {cost}"})

    # 重要な分岐点まで戻る
    while career_path and not is_important_choice(career_path[-1]):
        career_path.pop()

    user.time_crystals -= cost
    user.career_path = json.dumps(career_path)
    # ... 後略 ...
```

### その他のアイテムについて

現在のコードでは、タイムクリスタル以外の具体的なアイテムの実装は限定的です。ユーザーモデルには`item_box`フィールドが存在し、JSON形式でアイテムを保存できるようになっています。

```python
class User(db.Model):
    # ... 他のフィールド ...
    item_box = db.Column(db.String(500), default='[]')  # アイテムボックス
```

しかし、現状ではこのフィールドを活用した多様なアイテムの獲得、使用、効果の実装は行われていません。

### アイテム機能の今後の展開

将来的には、以下のようなアイテム関連機能の拡張を計画しています：

1. 多様なアイテムの導入（スキルブースター、チャンスカードなど）
2. アイテム獲得システムの実装
3. アイテム使用機能の開発
4. アイテム管理画面の作成

これらの機能を実装することで、ゲームプレイの戦略性と興味深さが向上し、ユーザーエンゲージメントの向上が期待できます。

## 4. 未来の自分との対話機能（開発中）

ゲーム終了時に、ユーザーは「未来の自分」と対話することができる機能を計画しています。しかし、現在のコードでは、この機能は完全には実装されていません。以下に示すコードは、将来的なAI機能の基本的な構造を示すプレースホルダーとなっています。

```python
@app.route('/future_self_analysis', methods=['POST'])
def perform_future_self_analysis():
    # ... 前略 ...
    analysis = {
        "strength": "適応力と柔軟性",
        "weakness": "長期的な計画立案",
        "opportunity": "新しい技術スキルの習得",
        "threat": "急速に変化する業界トレンド"
    }
    return jsonify(analysis)

@app.route('/get_ai_response', methods=['POST'])
def generate_ai_response():
    # ... 前略 ...
    question = request.form['question']
    
    # AI応答ロジック（仮実装）
    response = f"あなたの質問 '{question}' に対する未来の自分からの回答: 技術の世界は常に変化しています。新しいスキルを学び続けることが重要です。"
    
    return jsonify({"response": response})
```

### AI機能の将来計画

今後のAI機能の開発では、以下のような改善を予定しています：

1. 自然言語処理（NLP）モデルの導入
2. ユーザーのキャリアパスに基づいた応答生成
3. 機械学習モデルの統合
4. 外部AIサービス（OpenAI GPT-3など）との連携

## まとめ

「キャリア・クエスト」は、Flaskを使用して構築された複雑なWebアプリケーションです。現在のバージョンでは、ユーザー登録、適性診断、キャリアシミュレーション、タイムライン管理、そしてタイムクリスタルを使用した基本的なアイテムシステムが実装されています。

AIを活用した対話機能や多様なアイテムシステムは現在開発中であり、将来的にはより高度で魅力的な機能を提供する予定です。これらの拡張により、ユーザーはより深く、個人化されたキャリア探索体験を得られるようになるでしょう。

このプロジェクトでは、Pythonの強力な機能やFlaskのシンプルさを活かしつつ、複雑なビジネスロジックを実装しています。特に、キャリアシミュレーションのロジックや適性診断のアルゴリズムは、実際のキャリアコンサルティングの知見を取り入れつつ、エンゲージメントを高めるためのゲーミフィケーション要素を組み込んでいます。

今後の展開としては、機械学習モデルを導入してより精緻な適性診断や未来予測を行ったり、ユーザーの行動データを分析して個別化されたアドバイスを提供したりすることが考えられます。

「キャリア・クエスト」のようなアプリケーションは、単なるゲームを超えて、ユーザーの人生選択に実際の影響を与える可能性を秘めています。そのため、倫理的な配慮やデータのセキュリティにも十分注意を払う必要があります。

皆さんも、自分のプロジェクトでFlaskを使ってこのような複雑なアプリケーションを構築する際の参考にしていただければ幸いです。