from __future__ import division import random from otree.api import * from .models import C, Player WIN_PROB = 0.40 # 40% chance to win GAME_PARAMS = [ {"multiplier": 1.2, "prob": 0.2969}, # House's Edge = 5% {"multiplier": 1.5, "prob": 0.2714}, # House's Edge = 5% {"multiplier": 2.0, "prob": 0.2375}, # House's Edge = 5% {"multiplier": 1.3, "prob": 0.2879}, # House's Edge = 5% {"multiplier": 1.8, "prob": 0.25}, # House's Edge = 5% ] class a_Instructions(Page): form_model = 'player' form_fields = ['comprehension_check_1', 'comprehension_check_2'] def is_displayed(self): return self.subsession.round_number == 1 def error_message(self, values): errors = {} if values['comprehension_check_1'] != '3': errors['comprehension_check_1'] = ( 'Your answer is not correct. ' 'Please read the game instructions again.' ) if values['comprehension_check_2'] != '3': errors['comprehension_check_2'] = ( 'Your answer is not correct. ' 'Please read the game instructions again.' ) return errors class b1_Pre_Decision(Page): form_model = 'player' form_fields = ['play_round'] def is_displayed(self): player = self.player return (player.participant.vars.get('balance', 0) > 0 and player.participant.vars.get('play_next_round', True)) def before_next_page(self): player = self.player if not player.play_round: player.participant.vars['play_next_round'] = False def vars_for_template(self): index = (self.round_number - 1) % len(GAME_PARAMS) params = GAME_PARAMS[index] return dict( multiplier=params["multiplier"], ) class b3_Decision(Page): form_model = 'player' form_fields = ['bet_amount', 'choice'] def is_displayed(self): player = self.player return player.participant.vars.get('balance', 0) > 0 and player.participant.vars.get('play_next_round', True) def error_message(self, values): balance = self.participant.vars.get('balance', 0) if not values.get('bet_amount'): return 'Please select the amount you want to bet.' if values['bet_amount'] <= 0: return 'The bet amount cannot be negative.' if values['bet_amount'] > balance: return 'You cannot bet more than your available balance.' if not values.get('choice'): return 'Please choose Heads or Tails.' def vars_for_template(self): index = (self.round_number - 1) % len(GAME_PARAMS) params = GAME_PARAMS[index] return dict( multiplier=params["multiplier"], ) class b2_Sure_Pre_Decision(Page): form_model = 'player' form_fields = ['play_round_sure'] def is_displayed(self): player = self.player return not player.participant.vars.get('play_next_round', True) def before_next_page(self): player = self.player if not player.play_round_sure: player.participant.vars['play_next_round'] = True def vars_for_template(self): p = self.player return dict( balance=p.participant.vars['balance'], multiplier=p.multiplier, ) class c_Results(Page): def is_displayed(self): player = self.player return player.participant.vars.get('balance', 0) > 0 and player.participant.vars.get('play_next_round', True) def vars_for_template(self): p = self.player if p.field_maybe_none('coin_result') is None: balance = p.participant.vars.get('balance', 0) # Determine rotating game parameters index = (p.round_number - 1) % len(GAME_PARAMS) params = GAME_PARAMS[index] multiplier = params["multiplier"] win_prob = params["prob"] # Override probability for first 2 rounds if p.round_number <= 2: win_prob = 0.8 p.multiplier = multiplier p.win_probability = win_prob # Draw outcome if random.random() < win_prob: p.round_win = True p.coin_result = p.choice p.round_payoff = p.bet_amount * multiplier else: p.round_win = False p.coin_result = 'T' if p.choice == 'H' else 'H' p.round_payoff = -p.bet_amount balance += p.round_payoff p.participant.vars['balance'] = balance return dict( coin=p.coin_result, win=p.round_win, balance=p.participant.vars['balance'], multiplier=p.multiplier, ) class d_Exit(Page): def is_displayed(self): return ( not self.player.participant.vars.get('play_next_round', True) or self.participant.vars['balance'] <= 0 ) def vars_for_template(self): final_balance = self.participant.vars['balance'] self.player.final_balance = final_balance return dict( final_balance=final_balance ) def app_after_this_page(self, upcoming_apps): return upcoming_apps[0] class f_belief_elicit(Page): form_model = 'player' form_fields = 'belief_elicit_1', 'belief_elicit_2' def is_displayed(self): return (not self.player.play_round) or self.participant.vars['balance'] <= 0 def app_after_this_page(self, upcoming_apps): return upcoming_apps[0] page_sequence = [ a_Instructions, b1_Pre_Decision, b2_Sure_Pre_Decision, b3_Decision, c_Results, d_Exit, ]