from otree.api import * doc = """ A game of rock-paper-scissors. If you think about this logically, this is essentially a bi-trix game with 3 decisions. """ class C(BaseConstants): NAME_IN_URL = 'RPS_Chat' PLAYERS_PER_GROUP = 2 NUM_ROUNDS = 5 CHOICES = ['Rock', 'Paper', 'Scissors'] PAYOFF_WIN = 1 PAYOFF_LOSS = -1 class Subsession(BaseSubsession): pass class Group(BaseGroup): is_draw = models.BooleanField() class Player(BasePlayer): hand = models.StringField(choices=C.CHOICES) opponent_hand = models.StringField() result = models.StringField() def set_winner(player: Player): [opponent] = player.get_others_in_group() score = 0 if player.hand == opponent.hand: player.result = 'Draw' elif player.hand + opponent.hand in 'ScissorsPaperRockScissors': player.result = 'Win' score += 1 else: player.result = 'Loss' score -= 1 player.opponent_hand = opponent.hand player.payoff = score class Introduction(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 timeout_seconds = 100 class Shoot(Page): form_model = 'player' form_fields = ['hand'] @staticmethod def vars_for_template(player: Player): return dict(past_players=player.in_previous_rounds(), my_nickname="SKIMmer {}".format(player.id_in_group) ) class WaitForOther(WaitPage): @staticmethod def after_all_players_arrive(group: Group): for p in group.get_players(): set_winner(p) class FinalResults(Page): @staticmethod def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS @staticmethod def vars_for_template(player: Player): tally = player.in_all_rounds() final_score = 0 for t in tally: if t.result == 'Win': final_score += C.PAYOFF_WIN elif t.result == 'Loss': final_score += C.PAYOFF_LOSS else: final_score += 0 return dict( past_players=player.in_all_rounds(), final_payoff=final_score ) page_sequence = [Introduction, Shoot, WaitForOther, FinalResults]