oTree Forum >

How to code a simultaneous + sequential public goods game?

#1 by Thair_Ahmad

Hello!

I am trying to design a public goods game where the first three players play the game simultaneously, and their payoffs are determined together. From the fourth player onwards, the game is sequential; nth player is matched with 2 random player's contributions (n-1 players who have already contributed) for the determination of their payoff. I have changed the constant players_per_group to None and tried to write a payoff function that considers the above condition. However, there are two problems: 1) the payoff for every player is showing zero irrespective of their contribution and 2) I need a add a waiting page only for first three players as the game is sequential from 4th player. Please help me. Thank you. Here is my code: 

from otree.api import *
import random


class C(BaseConstants):
    NAME_IN_URL = 'public_goods_simple'
    PLAYERS_PER_GROUP = None
    NUM_ROUNDS = 1
    ENDOWMENT = cu(100)
    MULTIPLIER = 2


class Subsession(BaseSubsession):
    pass


class Group(BaseGroup):
    total_contribution = models.CurrencyField()
    individual_share = models.CurrencyField()


class Player(BasePlayer):
    contribution = models.CurrencyField(
        choices=[[0, '0'], [50, '50'], [100, '100']], label="How much will you contribute?",
        widget=widgets.RadioSelectHorizontal
    )


# FUNCTIONS
def set_payoffs(player: Player):
    group = player.group
    players = group.get_players()
    contributions = [p.contribution for p in players if p.contribution is not None]
    group.total_contribution = sum(contributions)

    i = len(contributions) - 1
    if i < 3:
        player.payoff = C.ENDOWMENT - player.contribution + (
                    group.total_contribution * C.MULTIPLIER / len(contributions))
    else:
        selected_players = random.sample(players[:i], 2)
        selected_contributions = [sp.contribution for sp in selected_players]
        avg_contribution = (player.contribution + sum(selected_contributions)) / 3
        player.payoff = C.ENDOWMENT - player.contribution + (avg_contribution * C.MULTIPLIER)


# PAGES
class Contribute(Page):
    form_model = 'player'
    form_fields = ['contribution']


class Results(Page):
    form_model = 'player'


page_sequence = [Contribute, Results]

Write a reply

Set forum username