0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【初心者向け】oTree で簡単な囚人のジレンマゲームを実装する【オンライン実験】

Last updated at Posted at 2025-04-09

1. はじめに

東京大学で社会心理学の研究をしている D1 の髙橋龍と申します.

この記事では,oTree を使った簡単な社会実験(囚人のジレンマゲーム)の実装方法について解説していきます!

(この記事は oTree のセットアップについて,以下の記事を前提として書かれています)
【初心者向け】oTree を自分の PC で動かす!【Windows 編】 #Python - Qiita

今回は 「囚人のジレンマゲーム」と呼ばれる経済ゲーム を題材に,超シンプルなサンプルを作ってみましょう!
このコードを理解できると, 一対一で他者とインタラクションをする実験の作り方 がわかるようになります.最後まで一緒に頑張りましょう!

※ 今回の記事は otree==5.11.1 を前提としています.バージョンが心配な方は,上記の記事を参考に環境構築を行ってください.

2. 今回実装する実験の概要

2.1 囚人のジレンマとは

囚人のジレンマは一見すると難しそうですが,実は ふつうの生活の中でもよく見られる構造 です.

たとえば,あなたと友達が一緒に授業のレポートを出すとします.2 人で分担して,うまくやればラクに終わるはず.
しかし,どちらかが「相手がちゃんとやってくれるだろう」と思ってサボると,自分だけ得をします.
問題は,もしお互いに「相手がやってくれるでしょ」って思ってサボったら…当然レポートは提出できず,2 人とも単位を落としてしまいます(社会的ジレンマ)

今回の記事では,このジレンマの仕組みを実際に体験できる,簡単な実験を作ります.
2 人がお互いに「協力する」か「裏切る」かを選び,協力すれば 2 人とも得をするけど,裏切れば自分だけが得をしやすい…
でも,2 人とも裏切ると最悪な結果になる.そんなルールで進めます.

2.2 今回の実験状況

  • プレイヤー数: 2 人
  • プレイヤーの行動:「協力」 or 「非協力」を選ぶ
  • 目標: oTree を使ってこのロジックを実装し,Web 上で簡単に実験を回せるようにする

3. フォルダの作成

3.1 otree startapp でフォルダを作成する

oTree のアプリを作るときは,まずターミナルやコマンドプロンプトで,以下のコマンドを打ちます.

手順

  1. コマンドプロンプト,ターミナルを開く
    1. Windows の場合:Windows キーを押して「cmd」と入力し,Enter
    2. Mac の場合:Spotlight 検索で「ターミナル」と入力し,Enter
  2. oTree のプロジェクトフォルダに移動
    cd path/to/your/otree_project
    
  3. otree startapp simple_pd を入力し,実行

イメージはこんな感じです.Created app folder が表示されれば成功です!
(エラーが出た場合は,以下の Case1, Case2 をご参照ください)

image.png

Case 1: 既にあるというエラー

こういうエラーが出たときは,

There is already an app called "simple_pd" in this folder. Either delete that folder first, or use a different name.

simple_pd が既にあるということ.なので,simple_pd を削除して再度 otree startapp simple_pd を実行してみてください

image.png

Case 2: AssertionError と出る

こんな感じのエラーが出たら,

image.png

settings.py というファイルに simple_pd が登録されてしまっているはずです.

なので,settings.pyを開いて,

image.png

オレンジ色の枠の部分を削除してください.

スクリーンショット 2025-04-17 113927.png

無事に削除出来たら,再度 otree startapp simple_pd を実行してみてください!

3.2 作成されたファイル構造の確認

otree startapp コマンドを実行すると,simple_pd フォルダ配下に以下のようなファイルが出来上がります.

image.png

  • __init__.py
  • MyPage.html
  • Results.html

この通りできていれば,次のステップに進んでいきましょう!

4. 実装コードの概要

ここからは実際にコードを編集していきます.oTree は __init__.py に実験ロジックや設定を書き込むのが特徴的です.
今回は「自分とパートナーの選択によって,自分が獲得できるポイント(i.e., 利得)が変わる」というルールを実装していきます.

(難しい言葉が続くので, よく分からない人は「5. メインロジックの解説」まで読み飛ばしても大丈夫 です!)

4.1 __init__.py による実験ロジックの記述

oTree では,下記のように定数やプレイヤー数を管理する C クラス,実験の進行管理を行う Subsession / Group / Player クラスなどを定義します.また,ページ遷移に関するクラス(ここでは Page など)もこの中に書いていきます.

4.2 HTML ファイル(ページテンプレート)の役割

ユーザーが実際に目にする画面は,HTML ファイル で決定します.oTree 独自のテンプレートタグ({{ formfields }} など)が使えて,Python コード側と連動してフォームや結果を表示できます.

4.3 全体のディレクトリ構成

最終的にはこんな構成を想定しています:

simple_pd/
├─ __init__.py    # 実験のメインコード
├─ MyPage.html    # プレイヤーが選択するページ
└─ Results.html   # 結果表示ページ

それでは,実際のコードを見ていきましょう!

5. メインロジックの解説

__init__.py を開いてください.すると,以下のようなコードが記述されているはずです.

1741584370081.png

まずは,オレンジ色の枠の部分を編集しましょう.

image.png

以下のコードに編集してください.

# __init__.py

class C(BaseConstants):
    NAME_IN_URL = "simple_pd"
    PLAYERS_PER_GROUP = 2
    NUM_ROUNDS = 1
    PAYOFF_MATRIX = {
        ("C", "C"): [3, 3],
        ("C", "D"): [0, 5],
        ("D", "C"): [5, 0],
        ("D", "D"): [1, 1],
    }

これで,定数や設定値を管理する C クラスの実装が完了しました.
次に,Subsession / Group / Player クラスを実装していきます.以下のコードのオレンジ色の部分を編集してください.

image-1.png

記述するコードは以下です.

# __init__.py

class Subsession(BaseSubsession):
    pass


class Group(BaseGroup):
    @staticmethod
    def set_payoffs(group: BaseGroup):
        p1, p2 = group.get_players()
        p1_decision = p1.decision
        p2_decision = p2.decision
        p1.payoff, p2.payoff = C.PAYOFF_MATRIX[(p1_decision, p2_decision)]


class Player(BasePlayer):
    decision = models.StringField(
        choices=["C", "D"],
        doc="This player's decision",
        widget=widgets.RadioSelect,
        label="Choose: Cooperate (C) or Defect (D)",
    )

最後に,ページ遷移に関するクラスを実装します.以下のコードのオレンジ色の部分を編集してください.

image-2.png

# __init__.py

# PAGES
class MyPage(Page):
    form_model = "player"
    form_fields = ["decision"]


class ResultsWaitPage(WaitPage):
    after_all_players_arrive = Group.set_payoffs


class Results(Page):
    @staticmethod
    def vars_for_template(player: Player):
        other_player = player.get_others_in_group()[0]
        return {
            "player": player,
            "other_player": other_player,
        }

これで,実験のメインロジックが完成しました!
ここまでくれば,あとは HTML ファイルを編集して,実際の画面を作成するだけです.
あと少しです.頑張りましょう!

このセクションの残りの部分では,各クラスや編集したコードの解説をします.初学者の方は「6. ページテンプレート (HTML) の解説」まで読み飛ばしても大丈夫です!

5.1 C クラスの実装と解説 (定数,設定値)

  • PLAYERS_PER_GROUP = 2: 今回は 2 人 1 組で囚人のジレンマをプレイするので、グループサイズは常に 2 です
  • NUM_ROUNDS = 1: 1 ラウンドのみのシンプルな構成
  • PAYOFF_MATRIX: 囚人のジレンマ特有の報酬行列です
    • どちらも協力 → [3, 3]
    • 自分が裏切って相手が協力 → [5, 0]
    • 自分が協力して相手が裏切る → [0, 5]
    • どちらも裏切り → [1, 1]

5.2 Subsession / Group / Player クラスの解説 (実験の根幹ロジック)

  • Subsession: セッション開始時の設定を記述する場所です.ここでは特にプレイヤー数の設定を行っています.
  • Group: プレイヤーの選択から利得を算出するロジックを管理します.set_payoffs という名前のメソッドはよく使われるので,ぜひ覚えておきましょう.
  • Player: 各プレイヤー個別の情報を保持します.ここでは decision (協力 or 非協力) のみを記録します。

5.3 ページクラスの解説 (入力ページ,WaitPage,結果表示ページ)

  • MyPage: プレイヤーが協力 or 非協力を選ぶ入力ページ.form_fields で指定された項目が表示されます.
  • ResultsWaitPage: 全プレイヤーの回答が集まるまで待つページ.このページで Group.set_payoffs を呼び出し,全員の利得を一括計算しています.
  • Results: 結果表示ページ.全プレイヤーの選択状況や自分の利得などを見せています.

6. ページテンプレート (HTML) の解説

このセクションでは,MyPage.htmlResults.html の HTML テンプレートを解説します.
参加者に対してどのような画面を表示するか,を決定するのが HTML ファイルの役割です.

6.1 MyPage.html の解説

MyPage.html を開いてください.以下のようなコードが記述されているはずです.

1741584896650.png

こちらのコードを以下のように編集してください.

<!-- simple_pd/MyPage.html -->

{{ block title }} 
    意志決定画面 
{{ endblock }} 

{{ block content }}
    <p>どちらかを選んでください.</p>
    {{ formfields }} 
    {{ next_button }} 
{{ endblock }}

補足説明

oTree でよく使うテンプレートタグ:

  • {{ formfields }}: Python 側で指定した form_fields の入力フォームが生成される部分
  • {{ next_button }}: 次のページへ進むボタン

6.2 Results.html の解説

次に,Results.html を開いてください.以下のようなコードが記述されているはずです.

1741584945156.png

こちらのコードを以下のように編集してください.

<!-- simple_pd/Results.html -->

{{ block title }} 
    結果画面 
{{ endblock }} 

{{ block content }}
    <p>あなたの選択: {{ player.decision }}</p>
    <p>パートナーの選択: {{ other_player.decision }}</p>
    <p>あなたの獲得ポイント: {{ player.payoff }}</p>
    {{ next_button }} 
{{ endblock }}

これで,HTML テンプレートの編集も完了です!
最後に,このアプリケーションを実際に動かすために必要な手順 (settings.py への追加)と実行方法について説明します.

補足説明

  • {{ player.decision }}{{ other_player.decision }}{{ player.payoff }} は Python 側の変数から取得した内容を表示しています.

7. アプリの実行

7.1 settings.py への追加

/otree-template/setting.py を開いてください.
すると,以下のようなコードが記述されているはずです.

image-3.png

この画像のオレンジ色の部分に以下のコードを追加してください.

# settings.py

dict(
    name="simple_pd",
    app_sequence=["simple_pd"],
    num_demo_participants=2,
),

下の画像のような状態になれば成功です!

image-4.png

7.2 otree devserver でサーバーを起動

コードの編集が終わったら,コマンドプロンプトやターミナルで:

otree devserver

を実行してください.
成功すると,以下のような画面になるはずです.

1741585332187.png

成功したら,http://localhost:8000 (または表示された URL)にアクセスできるはずです.
アクセス後に以下のような画面になれば,成功です!

1741585412135.png

7.3 簡単な動作確認

  1. ブラウザで http://localhost:8000/ を開く(上の画像のような画面にになっていれば OK!).
  2. 今回のアプリ(simple_pd)をクリックする.
  3. 画面中央にある「Play in split screen mode」(オレンジ色の枠)をクリックする.

1741585488516.png

  1. 画面上部が管理者画面,下部がプレイヤー画面になります.画面を操作して,どんな動きをするか確認してみましょう!

image-5.png

以上で,実験の実装と実行が完了しました!
ここまで完走した皆さんはとても素晴らしいです!!!

8. 拡張のアイデア

このようなシンプルなひな形があれば,様々な実験を作ることができます.以下は,このサンプルを拡張するアイデアですので,ぜひ参考にしてください!

  • ラウンド数を増やす
    例えば C.NUM_ROUNDS = 5 に変更すると,全 5 ラウンド分の選択と結果表示を行えます.
  • 利得行列の変更
    例えば裏切りがもっと得になるように調整したり,相互協力のインセンティブを大きくするなど,協力を促進するように設計することもできる.
  • WaitPage の改良
    結果表示前に,チャットページ(Chat クラスを使用)や追加の質問ページを挟むなど,ユーザーインタラクションを強化できます.
  • 連続的な協力の導入
    今回は「協力」か「非協力」かの 2 択でしたが,スライダーを使って連続的な協力度を選択できるようにすると,よりリアルな囚人のジレンマを実装できます.

9. まとめ

ここまで読んでいただきありがとうございます!
今回は「囚人のジレンマゲーム」を題材に,oTree で最小限の機能を持つサンプル実験を作ってみました.oTree は「Python を使った Web 実験」というと一見難しそうですが,シンプルなプロジェクト構成とテンプレートのおかげで,初めての人でも比較的スムーズに始められます.

押さえておきたいポイント

  • __init__.py にロジックが集中している
  • HTML テンプレートを使って画面を自由にデザインできる
  • WaitPage を使って全プレイヤーが入力を完了するのを待ち,共通の利得計算を行う

このあたりを理解しておけば,応用で色々な実験を作りやすくなります.

以上が,今回のサンプル実験の解説です.
ぜひ,記事の構成やコードをもとに,いろんな形の社会実験を作ってみてください!もし分からないところがあれば,公式ドキュメントをチェックしたり,コミュニティに質問してみたりするとよいですよ.皆さんの研究や学習に役立てば嬉しいです!

Next Step

次にやるおすすめの記事はこちら!今回よりもちょっとだけ複雑なアプリを作りますが,oTree の雰囲気を知るには最適なアプリの難易度です!

【初心者向け】oTree で簡単な公共財ゲームを実装する【オンライン実験】 #Python - Qiita

もっと発展的で難しいアプリを作りたい場合はこちら!ロジックもコードの量も多いですが,これが実装できると飛躍的にコードが書けるようになります!

【初心者向け】oTree で簡単な信頼ゲームを実装する【オンライン実験】 #Python - Qiita

謝辞

本記事は,ChatGPT の協力を得ながら作成しました.(ChatGPT さん,いつもありがとうございます)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?