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 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) 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) quiz_three = models.IntegerField(blank=True, choices=[1,2,3,4], widget=widgets.RadioSelect) Pass = 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): pass 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 (data and data == 'got_it'): player.guide_step += 1 elif (data and data == 'computer_turn'): 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.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 != 3): error = 'Try to add 3.' else: if (player.guide_step == 2): player.guide_step += 1 number = data player.current_number += number if player.current_number == subsession.target: if subsession.mode == 'last_win': player.is_winner = 1 # player.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', 'quiz_three'] @staticmethod def error_message(player, values): for q in ['quiz_one', 'quiz_two', 'quiz_three']: if values[q] == None: return 'Please answer all the questions' def before_next_page(player, timeout_happened): if player.quiz_one == 4 and player.quiz_two == 2 and player.quiz_three == 1: player.Pass = True class Quiz_result(Page): @staticmethod def app_after_this_page(player, upcoming_apps): if player.Pass == True: return upcoming_apps[0] else: return "payment_info" page_sequence = [Instruction, Game, Results, Quiz, Quiz_result] # page_sequence = [Quiz, Quiz_result]