from otree.api import * doc = """ Game of Nim. Players take turns adding a number. First to 15 wins. """ class Constants(BaseConstants): import csv import random name_in_url = 'race_game_guide' players_per_group = None num_rounds = 1 win_payoff = cu(10) lose_payoff = cu(0) with open('race_game_guide/target.csv', 'r') as para: para = list(csv.DictReader(para)) num_rounds = len(para) # number of row round_order = list(range(1, num_rounds+1)) class Subsession(BaseSubsession): round_row = models.IntegerField(initial=0) target = models.IntegerField(initial=0) choice = models.IntegerField(initial=0) mode = models.StringField(initial='') class Group(BaseGroup): pass class Player(BasePlayer): is_winner = models.BooleanField(initial=False) temp_payoff = models.CurrencyField(initial=cu(0)) remain = models.IntegerField(initial=100) current_number = models.IntegerField(initial=0) whose_turn = models.IntegerField(initial=1) player_turn = models.IntegerField(initial=1) winner_id = models.IntegerField() game_over = models.BooleanField(initial=False) guide_step = models.IntegerField(initial=0) quiz_one = models.IntegerField(blank=True, choices=[1,2,3,4], widget=widgets.RadioSelect) quiz_two = models.IntegerField(blank=True, choices=[1,2,3,4], widget=widgets.RadioSelect) Pass = models.BooleanField(initial=False) count_player_turn = models.IntegerField(initial=0) count_com_turn = models.IntegerField(initial=0) all_fail = models.BooleanField(initial=False) def creating_session(subsession): round_row = Constants.para[subsession.round_number - 1] print(round_row) subsession.target = int(round_row['target']) subsession.choice = int(round_row['choice']) subsession.mode = round_row['mode'] def get_remain(player: Player): subsession = player.subsession remain = subsession.target - player.current_number return remain def rational_race_game(player: Player, mode): import random subsession = player.subsession if mode == 'last_win': add = player.remain % (subsession.choice + 1) else: if player.remain == 1: add = 1 else: add = (player.remain - 1) % (subsession.choice + 1) if add == 0: add = random.randint(1,subsession.choice) return add # PAGES class Instruction(Page): @staticmethod def is_displayed(player): return player.round_number == 1 class Game(Page): @staticmethod def js_vars(player: Player): subsession = player.subsession return dict(choice = subsession.choice) @staticmethod def live_method(player: Player, data): group = player.group subsession = player.subsession error = '' number = 0 news = None if player.current_number > subsession.target: player.is_winner = 0 player.game_over = True player.payoff = 0 if player.count_player_turn - player.count_com_turn >=2: player.is_winner = 0 player.game_over = True player.payoff = 0 if (data and data == 'got_it'): player.guide_step += 1 elif (data and data == 'computer_turn'): player.count_com_turn += 1 if (player.guide_step == 4): player.guide_step += 1 number = rational_race_game(player, subsession.mode) player.current_number += number if player.current_number == subsession.target: if subsession.mode == 'last_win': player.is_winner = 0 else: player.is_winner = 1 player.temp_payoff = Constants.win_payoff player.game_over = True # else: player.player_turn = 1 - player.player_turn player.remain = get_remain(player) news = dict(player_turn = player.player_turn, number=number) elif (data and isinstance(data, int)): if (player.guide_step == 2 and data != 2): error = 'Try to add 2.' else: if (player.guide_step == 2): player.guide_step += 1 player.count_player_turn += 1 number = data player.current_number += number if player.current_number == subsession.target: if subsession.mode == 'last_win': player.is_winner = 1 player.temp_payoff = Constants.win_payoff else: player.is_winner = 0 player.game_over = True # else: player.player_turn = 1 - player.player_turn player.remain = get_remain(player) news = dict(player_turn = player.player_turn, number=number) else: news = None print(data) print(news) print('guide step: ', player.guide_step) print('error: ' , error) print('====================') return { player.id_in_group: dict( game_over=player.game_over, current_number=player.current_number, player_turn = player.player_turn, news=news, choice = subsession.choice, remain = player.remain, guide_step = player.guide_step, guide_error = error, ) } class ResultsWaitPage(WaitPage): pass class Results(Page): pass class Quiz(Page): form_model = 'player' form_fields = ['quiz_one', 'quiz_two'] @staticmethod def error_message(player, values): for q in ['quiz_one', 'quiz_two']: if values[q] == None: return 'Please answer all the questions' def before_next_page(player: Player, timeout_happened): if player.quiz_one == 2 and player.quiz_two == 2: player.Pass = True participant = player.participant participant.race_pass = player.Pass if participant.race_pass == False and participant.monty_hall_pass == False and participant.monty_hall_t_pass == False and participant.two_PBC_pass == False: participant.all_fail = True player.all_fail = participant.all_fail else: participant.all_fail = False player.all_fail = participant.all_fail class Quiz_result(Page): @staticmethod def app_after_this_page(player, upcoming_apps): if player.Pass == True: return upcoming_apps[0] elif player.all_fail == True: return upcoming_apps[2] else: return upcoming_apps[1] page_sequence = [Instruction, Game, Results, Quiz, Quiz_result] # page_sequence = [Quiz, Quiz_result]