from otree.api import * c = cu doc = '' class C(BaseConstants): NAME_IN_URL = 'adapted_beer_game' PLAYERS_PER_GROUP = 4 NUM_ROUNDS = 20 OEMA_ROLE = 'OEM A' OEMB_ROLE = 'OEM B' CMA_ROLE = 'CM A' CMB_ROLE = 'CM B' INITIAL_INVENTORY = 120 CUSTOMER_ROUND4 = 40 CUSTOMER_ROUND8 = 80 CUSTOMER_ROUND9 = 90 CUSTOMER_ROUND10 = 30 CUSTOMER_ROUND11 = 100 CUSTOMER_ROUND15= 110 INITIAL_INCOMING_SHIPMENT = 40 treatment = 1 control = 2 class Subsession(BaseSubsession): pass def creating_session(subsession: Subsession): session = subsession.session if subsession.round_number == 1: subsession.group_randomly(fixed_id_in_group=True) else: subsession.group_like_round(1) groups = subsession.get_groups() import itertools treatments = itertools.cycle([True, False]) for group in subsession.get_groups(): group.treatment = next(treatments) def showwinner(subsession: Subsession): session = subsession.session groups = subsession.get_groups() winners = [] for i, g in enumerate(groups): winners.append({ "id": i+1, "cost": teamcost(g) }) return winners def showmax(subsession: Subsession): groups = subsession.get_groups() list = [] for g in groups: list.append(teamcost(g)) print(list) min_value=min(list) max_indices = [] for groupNumber, value in enumerate(list, 1): if min_value == value: max_indices.append(groupNumber) print(max_indices) return max_indices class Group(BaseGroup): currentRound = models.IntegerField(initial=0, max=C.NUM_ROUNDS, min=0) demand = models.IntegerField(min=0) average_order = models.FloatField() average_inventory = models.FloatField() treatment = models.BooleanField() def teamcost(group: Group): tc = 0.0 for p in group.get_players(): tc+=p.in_round(C.NUM_ROUNDS).player_totalcost return tc class Player(BasePlayer): player_inventory = models.IntegerField(initial=120) player_backorder = models.IntegerField(initial=0) player_order = models.IntegerField( blank=False, label='How many chips do you want to order in next round?', max=10000, min=0) player_totalcost = models.FloatField(initial=0.0) player_demand = models.IntegerField(initial=40) player_incomingshipment = models.IntegerField(initial=0) player_outgoingshipment = models.IntegerField(initial=0) q1 = models.StringField(choices=[['Maximum the inventory level', 'Maximum the inventory level'], ['Minimum the Total cost', 'Minimum the Total cost'], ['Forecast accurately', 'Forecast accurately']], label='What is your aim to this game?') q2 = models.StringField(choices=[['The information provided by the third-party platform ', 'The information provided by the third-party platform '], ['downstream player‘s demand', 'downstream player‘s demand'], ['all of the above', 'all of the above']], label='Which decision support is provided to you?') q3 = models.StringField(choices=[['Backorder in this period*1+inventory in this period*0.5+the cumulative cost until last period', 'Backorder in this period*1+inventory in this period*0.5+the cumulative cost until last period'], ['Backorder in this period*0.5+inventory in this period*1+the cumulative cost until last period', 'Backorder in this period*0.5+inventory in this period*1+the cumulative cost until last period'], ['Backorder in this period*1+inventory in this period*0.5', 'Backorder in this period*1+inventory in this period*0.5']], label='Which formula is the correct one for calculating the Total cost/per role?') q4 = models.BooleanField(choices=[[True, 'Customer‘s demand cannot be predicted by the third-platform'], [False, 'Customer‘s demand can be predicted by the third-platform']], label='Please tick the correct statement:') P1 = models.BooleanField(choices=[[True, 'Agree'], [False, 'Disagree']], label=' Please complete this survey as follows. All answers and results are recorded for research and improving the game experience within the framework and Infineon. Thus, they will not be made publicly available, and your identity with your corresponding answers will be private. To guarantee anonymity, this form will not record your name and email. You will be considered for the appreciation only if you answer accordingly.') P2 = models.StringField(choices=[['Always (in 20 rounds)', 'Always (in 20 rounds)'], ['Often (in >13 rounds)', 'Often (in >13 rounds)'], ['About half of the session (in 10 rounds)', 'About half of the session (in 10 rounds)'], ['A few times (in <6 rounds)', 'A few times (in <6 rounds)'], ['Never/rarely (in <2 rounds)', 'Never/rarely (in <2 rounds)']], label='How often did you interact with the historical data showed in the summary page?') p4l = models.StringField(choices=[['Always (in 20 rounds)', 'Always (in 20 rounds)'], ['Often (in >13 rounds)', 'Often (in >13 rounds)'], ['About half of the session (in 10 rounds)', 'About half of the session (in 10 rounds)'], ['A few times (in <6 rounds)', 'A few times (in <6 rounds)'], [' Never/rarely (in <2 rounds)', ' Never/rarely (in <2 rounds)']], label='How often did you interact with the historical inventory level showed in the ordering page? ') p4o = models.StringField( choices=[['Always (in 20 rounds)', 'Always (in 20 rounds)'], ['Often (in >13 rounds)', 'Often (in >13 rounds)'], ['About half of the session (in 10 rounds)', 'About half of the session (in 10 rounds)'], ['A few times (in <6 rounds)', 'A few times (in <6 rounds)'], [' Never/rarely (in <2 rounds)', ' Never/rarely (in <2 rounds)']], label='How often did you interact with the historical order showed in the ordering page? ') p4b = models.StringField( choices=[['Always (in 20 rounds)', 'Always (in 20 rounds)'], ['Often (in >13 rounds)', 'Often (in >13 rounds)'], ['About half of the session (in 10 rounds)', 'About half of the session (in 10 rounds)'], ['A few times (in <6 rounds)', 'A few times (in <6 rounds)'], [' Never/rarely (in <2 rounds)', ' Never/rarely (in <2 rounds)']], label='How often did you interact with the historical backorder showed in the ordering page? ') p3 = models.StringField(choices=[['Always (in 20 rounds)', 'Always (in 20 rounds)'], ['Often (in >13 rounds)', 'Often (in >13 rounds)'], ['About half of the session (in 10 rounds)', 'About half of the session (in 10 rounds)'], ['A few times (in <6 rounds)', 'A few times (in <6 rounds)'], [' Never/rarely (in <2 rounds)', ' Never/rarely (in <2 rounds)']], label='How often did you decide your order depending on the information showed on the anonymous survey platform ') p4123bo = models.StringField(choices=[['Mostly', 'Mostly'], ['Half', 'Half'], ['Slightly', 'Slightly'], ['None', 'None'], ['It confused me and made my decision worse', 'It confused me and made my decision worse']], label='How did the information about inventory level on the anonymous survey platform support your ordering decision?') p4123bo1 = models.StringField( choices=[['Mostly', 'Mostly'], ['Half', 'Half'], ['Slightly', 'Slightly'], ['None', 'None'], ['It confused me and made my decision worse', 'It confused me and made my decision worse']], label='How did the information about order on the anonymous survey platform support your ordering decision?') p4123bo2 = models.StringField( choices=[['Mostly', 'Mostly'], ['Half', 'Half'], ['Slightly', 'Slightly'], ['None', 'None'], ['It confused me and made my decision worse', 'It confused me and made my decision worse']], label='How did the information about backorder on the anonymous survey platform support your ordering decision?') p6 = models.StringField(blank=True, choices=[[' Historical data', ' Historical data'], ['Anonymous survey platform', 'Anonymous survey platform'], ['Both contributed 50:50', 'Both contributed 50:50']], label='What mainly did determine your ordering decision?') p7123 = models.StringField(choices=[['Always (in 20 rounds)', 'Always (in 20 rounds)'], ['Often (in >13 rounds)', 'Often (in >13 rounds)'], ['About half of the session (in 10 rounds)', 'About half of the session (in 10 rounds)'], ['A few times (in <6 rounds)', 'A few times (in <6 rounds)'], ['Never/rarely (in <2 rounds)', 'Never/rarely (in <2 rounds)']], label='How often did you use the round-up strategy when you see the comma value on the anonymous survey platform') p7123d = models.StringField( choices=[['Always (in 20 rounds)', 'Always (in 20 rounds)'], ['Often (in >13 rounds)', 'Often (in >13 rounds)'], ['About half of the session (in 10 rounds)', 'About half of the session (in 10 rounds)'], ['A few times (in <6 rounds)', 'A few times (in <6 rounds)'], ['Never/rarely (in <2 rounds)', 'Never/rarely (in <2 rounds)']], label='How often did you use the round-down strategy when you see the comma value on the anonymous survey platform') p7123r = models.StringField( choices=[['Always (in 20 rounds)', 'Always (in 20 rounds)'], ['Often (in >13 rounds)', 'Often (in >13 rounds)'], ['About half of the session (in 10 rounds)', 'About half of the session (in 10 rounds)'], ['A few times (in <6 rounds)', 'A few times (in <6 rounds)'], ['Never/rarely (in <2 rounds)', 'Never/rarely (in <2 rounds)']], label='How often did you use the round strategy when you see the comma value on the anonymous survey platform') p5 = models.StringField(choices=[['Always (in 20 rounds)', 'Always (in 20 rounds)'], ['Often (in >13 rounds)', 'Often (in >13 rounds)'], ['About half of the session (in 10 rounds)', 'About half of the session (in 10 rounds)'], ['A few times (in <6 rounds)', 'A few times (in <6 rounds)'], ['Never/rarely (in <2 rounds)', 'Never/rarely (in <2 rounds)']], label='How often did you have a detailed look at the summary page, examining the actual value, your order, and the information on the anonymous survey platform') p8 = models.BooleanField(choices=[[True, 'Positive/Optimistic'], [False, ' Negative/Skeptical']], label='what was your stance towards the anonymous survey platform before playing the game?') p9 = models.BooleanField(choices=[[True, 'Positive/Optimistic'], [False, 'Negative/Skeptical']], label='Having played the game, what is your stance towards the anonymous survey platform?') p10 = models.IntegerField(choices=[[5, '5'], [4, '4'], [3, '3'], [2, '2'], [1, '1']], label="On a scale of 1 to 5, How intuitive do you find the game's controls and interface?") p11 = models.IntegerField(choices=[[5, '5'], [4, '4'], [3, '3'], [2, '2'], [1, '1']], label="On a scale of 1 to 5, How satisfied are you with the game's graphics and visual design?") p12 = models.IntegerField(choices=[[5, '5'], [4, '4'], [3, '3'], [2, '2'], [1, '1']], label='On a scale of 1 to 5, how enjoyable do you find the overall gameplay experience Satisfactory?') p13 = models.StringField(blank=True, label='Which aspects of the game do you enjoy the most?') p14 = models.StringField(blank=True, label='Which aspects of the game do you find the least enjoyable? ') p15 = models.StringField(blank=True, label='Have you encountered any technical issues or glitches while playing the game? If yes, please describe them.') p16 = models.StringField(blank=True, label='In case you have further feedback regarding the game session, please write it down here:') gender = models.StringField(choices=[['Female', 'Female'], ['Male', 'Male'], ['Non-binary', 'Non-binary'], ['Other', 'Other'], ['Prefer not to say', 'Prefer not to say']], label=' What is your gender?') age = models.StringField(choices=[['<24 years old', '<24 years old'], ['24-38 years old', '24-38 years old'], ['39-58 years old', '39-58 years old'], ['58-73 years old', '58-73 years old']], label='How old are you?') education = models.StringField(choices=[['Highschool/Abitur', 'Highschool/Abitur'], [' Apprenticeship/Ausbildung', ' Apprenticeship/Ausbildung'], ["Bachelor's degree or equivalent", "Bachelor's degree or equivalent"], ["Master's degree or equivalent", "Master's degree or equivalent"], [' PhD/Doctorate and above', ' PhD/Doctorate and above']], label='What is your highest education?') loc = models.StringField(choices=[['Asia', 'Asia'], ['Africa', 'Africa'], ['North America', 'North America'], ['South America', 'South America'], ['Antarctica', 'Antarctica'], ['Europe', 'Europe'], ['Australia/Oceania', 'Australia/Oceania'], ['Prefer not to say', 'Prefer not to say']], label='Which location do you currently live in?') bk = models.StringField(label='If you study/have studied, what is/was your field of study?') carrer = models.StringField(label='What is your current occupation?') brgame = models.StringField(choices=[['Multiple times', 'Multiple times'], ['Once', 'Once'], ['Never', 'Never']], label='Have you played the semiconductor game before or participated in similar experiments, such as the beer distribution game?') kgscm = models.StringField(choices=[['Excellent (>5 years experience)', 'Excellent (>5 years experience)'], ['Solid (2-5 years experience)', 'Solid (2-5 years experience)'], ['Basic (1-2 years experience)', 'Basic (1-2 years experience)'], ['Limited (<1 year experience)', 'Limited (<1 year experience)'], ['None', 'None']], label='How would you describe your knowledge about supply chain planning?') kgscmhow = models.StringField(choices=[['From courses/training', 'From courses/training'], [' From work', ' From work'], ['From both', 'From both'], ['other', 'other']], label='How did you gain knowledge regarding supply chain planning?') idustry = models.StringField(choices=[['Excellent (>5 years experience)', 'Excellent (>5 years experience)'], ['Solid (2-5 years experience)', 'Solid (2-5 years experience)'], [' Basic (1-2 years experience)', ' Basic (1-2 years experience)'], [' Limited (<1 year experience)', ' Limited (<1 year experience)'], ['None', 'None']], label='How many years have you worked in any industries related to supply chain?') class Welocme(Page): form_model = 'player' form_fields = ['q1', 'q2', 'q3', 'q4'] @staticmethod def is_displayed(player: Player): return player.round_number == 1 @staticmethod def error_message(player: Player, values): solutions = dict( q1="Minimum the Total cost", q2="all of the above", q3="Backorder in this period*1+inventory in this period*0.5+the cumulative cost until last period", q4=True ) error_messages = dict() for field_name in solutions: if values[field_name] != solutions[field_name]: error_messages[field_name] = 'Wrong answer' return error_messages class OEMA(Page): form_model = 'player' form_fields = ['player_order'] @staticmethod def is_displayed(player: Player): return player.role == C.OEMA_ROLE @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group player.player_demand=C.CUSTOMER_ROUND4 player.player_inventory=C.INITIAL_INVENTORY player.player_outgoingshipment=player.player_demand player.player_totalcost=0.0 if player.round_number==1: player.player_incomingshipment = C.INITIAL_INCOMING_SHIPMENT player.player_inventory= player.player_inventory+player.player_incomingshipment-player.player_demand player.player_totalcost=C.INITIAL_INVENTORY*0.5 elif player.round_number>4: prev_player=player.in_round(player.round_number-1) prev_player_4week_OEMA = group.get_player_by_role(C.OEMA_ROLE).in_round( player.round_number - 4).player_order prev_player_4week_OEMB = group.get_player_by_role(C.OEMB_ROLE).in_round( player.round_number - 4).player_order prev_player_2week_CMA = group.get_player_by_role(C.CMA_ROLE).in_round( player.round_number - 2).player_outgoingshipment prev_player_2week_CMB = group.get_player_by_role(C.CMB_ROLE).in_round( player.round_number - 2).player_outgoingshipment ratiofororderA = prev_player_4week_OEMA / (prev_player_4week_OEMB + prev_player_4week_OEMA) ratiofororderb = prev_player_4week_OEMB / (prev_player_4week_OEMB + prev_player_4week_OEMA) incomeshipment = prev_player_2week_CMA * ratiofororderA + prev_player_2week_CMB * ratiofororderA print(prev_player_4week_OEMA) print(prev_player_4week_OEMB) print(prev_player_2week_CMA) print(prev_player_2week_CMB) print(ratiofororderA) print(ratiofororderb) print(incomeshipment) player.player_incomingshipment=int(round(incomeshipment,0)) if player.round_number>4 and player.round_number<8: player.player_demand=C.CUSTOMER_ROUND8 elif player.round_number ==8: player.in_round(8).player_demand=C.CUSTOMER_ROUND8 elif player.round_number == 9: player.in_round(9).player_demand = C.CUSTOMER_ROUND9 elif player.round_number == 10: player.in_round(10).player_demand = C.CUSTOMER_ROUND10 elif player.round_number == 11 or player.round_number ==12 or player.round_number ==13: player.player_demand = C.CUSTOMER_ROUND11 elif player.round_number >13 and player.round_number <19: player.player_demand = C.CUSTOMER_ROUND15 else: player.player_demand = C.CUSTOMER_ROUND11 player.player_inventory=prev_player.player_inventory+ player.player_incomingshipment-player.player_demand if player.player_inventory<0: player.player_backorder=player.player_inventory*-1 player.player_totalcost=player.in_round(player.round_number-1).player_totalcost+player.player_inventory*-1 else: player.player_backorder=0 player.player_totalcost=player.in_round(player.round_number-1).player_totalcost+player.player_inventory*0.5 requirment = player.player_demand + player.player_backorder if player.in_round(player.round_number - 1).player_inventory > 0 and player.player_incomingshipment > 0: capability = player.in_round(player.round_number - 1).player_inventory + player.player_incomingshipment elif player.in_round(player.round_number - 1).player_inventory <= 0 and player.player_incomingshipment > 0: capability = player.player_incomingshipment else: capability = 0 if capability > requirment: player.player_outgoingshipment = requirment else: player.player_outgoingshipment = capability # if player.in_round(player.round_number-1).player_inventory+player.player_incomingshipment >=player.player_demand: # player.player_outgoingshipment =player.player_demand # elif player.player_inventory+player.player_demand>=0: # player.player_outgoingshipment=player.player_incomingshipment+player.in_round(player.round_number-1).player_inventory # else: # player.player_outgoingshipment=0 else: prev_player=player.in_round(player.round_number-1) player.player_incomingshipment = C.INITIAL_INCOMING_SHIPMENT player.player_inventory=prev_player.player_inventory+player.player_incomingshipment-player.player_demand player.player_totalcost=C.INITIAL_INVENTORY*0.5+player.in_round(player.round_number-1).player_totalcost def vars_for_template(player: Player): group = player.group demand =0 if group.get_player_by_role(C.OEMA_ROLE).round_number<=4: demand = C.CUSTOMER_ROUND4 elif player.round_number > 4 and player.round_number < 8: demand = C.CUSTOMER_ROUND8 elif player.round_number == 8: demand = C.CUSTOMER_ROUND8 elif player.round_number == 9: demand = C.CUSTOMER_ROUND9 elif player.round_number == 10: demand = C.CUSTOMER_ROUND10 elif player.round_number == 11 or player.round_number == 12 or player.round_number == 13: demand = C.CUSTOMER_ROUND11 elif player.round_number > 13 and player.round_number < 19: demand = C.CUSTOMER_ROUND15 else: demand = C.CUSTOMER_ROUND11 return { "demand": demand } class OEMB(Page): form_model = 'player' form_fields = ['player_order'] @staticmethod def is_displayed(player: Player): return player.role==C.OEMB_ROLE @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group player.player_demand=C.CUSTOMER_ROUND4 player.player_outgoingshipment=player.player_demand player.player_totalcost=0.0 player.player_inventory=C.INITIAL_INVENTORY if player.round_number==1: player.player_incomingshipment = C.INITIAL_INCOMING_SHIPMENT player.player_inventory= player.player_inventory+player.player_incomingshipment-player.player_demand player.player_totalcost=C.INITIAL_INVENTORY*0.5 elif player.round_number>4: prev_player=player.in_round(player.round_number-1) prev_player_4week_OEMA = group.get_player_by_role(C.OEMA_ROLE).in_round(player.round_number-4).player_order prev_player_4week_OEMB = group.get_player_by_role(C.OEMB_ROLE).in_round(player.round_number-4).player_order prev_player_2week_CMA = group.get_player_by_role(C.CMA_ROLE).in_round(player.round_number-2).player_outgoingshipment prev_player_2week_CMB = group.get_player_by_role(C.CMB_ROLE).in_round(player.round_number-2).player_outgoingshipment ratiofororderA= prev_player_4week_OEMA/(prev_player_4week_OEMB+prev_player_4week_OEMA) ratiofororderb=prev_player_4week_OEMB/(prev_player_4week_OEMB+prev_player_4week_OEMA) incomeshipment=prev_player_2week_CMA*ratiofororderb+prev_player_2week_CMB*ratiofororderb player.player_incomingshipment=int(round(incomeshipment,0)) if player.round_number>4 and player.round_number<8: player.player_demand=C.CUSTOMER_ROUND8 elif player.round_number ==8: player.in_round(8).player_demand=C.CUSTOMER_ROUND8 elif player.round_number == 9: player.in_round(9).player_demand = C.CUSTOMER_ROUND9 elif player.round_number == 10: player.in_round(10).player_demand = C.CUSTOMER_ROUND10 elif player.round_number == 11 or player.round_number ==12 or player.round_number ==13: player.player_demand = C.CUSTOMER_ROUND11 elif player.round_number >13 and player.round_number <19: player.player_demand = C.CUSTOMER_ROUND15 else: player.player_demand = C.CUSTOMER_ROUND11 player.player_inventory=prev_player.player_inventory+ player.player_incomingshipment-player.player_demand if player.player_inventory<0: player.player_backorder=player.player_inventory*-1 player.player_totalcost=player.in_round(player.round_number-1).player_totalcost+player.player_inventory*-1 else: player.player_backorder=0 player.player_totalcost=player.in_round(player.round_number-1).player_totalcost+player.player_inventory*0.5 requirment = player.player_demand + player.player_backorder if player.in_round(player.round_number - 1).player_inventory > 0 and player.player_incomingshipment > 0: capability = player.in_round(player.round_number - 1).player_inventory + player.player_incomingshipment elif player.in_round(player.round_number - 1).player_inventory <= 0 and player.player_incomingshipment > 0: capability = player.player_incomingshipment else: capability = 0 if capability > requirment: player.player_outgoingshipment = requirment else: player.player_outgoingshipment = capability else: prev_player=player.in_round(player.round_number-1) player.player_incomingshipment = C.INITIAL_INCOMING_SHIPMENT player.player_inventory=prev_player.player_inventory+player.player_incomingshipment-player.player_demand player.player_totalcost=C.INITIAL_INVENTORY*0.5+player.in_round(player.round_number-1).player_totalcost def vars_for_template(player: Player): group = player.group demand = 0 if group.get_player_by_role(C.OEMA_ROLE).round_number<= 4: demand = C.CUSTOMER_ROUND4 elif player.round_number > 4 and player.round_number < 8: demand = C.CUSTOMER_ROUND8 elif player.round_number == 8: demand = C.CUSTOMER_ROUND8 elif player.round_number == 9: demand = C.CUSTOMER_ROUND9 elif player.round_number == 10: demand = C.CUSTOMER_ROUND10 elif player.round_number == 11 or player.round_number == 12 or player.round_number == 13: demand = C.CUSTOMER_ROUND11 elif player.round_number > 13 and player.round_number < 19: demand = C.CUSTOMER_ROUND15 else: demand = C.CUSTOMER_ROUND11 return { "demand": demand } class CMA(Page): form_model = 'player' form_fields = ['player_order'] @staticmethod def is_displayed(player: Player): return player.role==C.CMA_ROLE @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group player.player_demand=C.CUSTOMER_ROUND4 player.player_inventory = C.INITIAL_INVENTORY player.player_outgoingshipment=player.player_demand if player.round_number==1: player.player_incomingshipment = C.INITIAL_INCOMING_SHIPMENT player.player_inventory= player.player_inventory+player.player_incomingshipment-player.player_demand player.player_totalcost=0.5*C.INITIAL_INVENTORY player.player_demand = C.CUSTOMER_ROUND4 elif player.round_number == 2: player.player_incomingshipment = C.INITIAL_INCOMING_SHIPMENT player.player_inventory = player.player_inventory + player.player_incomingshipment - player.player_demand player.player_totalcost = 0.5 * C.INITIAL_INVENTORY+player.in_round(player.round_number-1).player_totalcost player.player_demand = C.CUSTOMER_ROUND4 elif player.round_number>=3: prev_player=player.in_round(player.round_number-1) prev_player_2week = player.in_round(player.round_number-2) prev_playerA_2week = group.get_player_by_role(C.OEMA_ROLE).in_round(player.round_number-2) prev_playerB_2week = group.get_player_by_role(C.OEMB_ROLE).in_round(player.round_number-2) player.player_demand = int(round((prev_playerA_2week.player_order*0.6)+(prev_playerB_2week.player_order*0.4),0)) player.player_incomingshipment=prev_player_2week.player_order player.player_inventory=prev_player.player_inventory+ player.player_incomingshipment-player.player_demand requirment = player.player_demand + player.player_backorder if player.in_round(player.round_number - 1).player_inventory > 0 and player.player_incomingshipment>0: capability = player.in_round(player.round_number - 1).player_inventory + player.player_incomingshipment elif player.in_round(player.round_number - 1).player_inventory <= 0 and player.player_incomingshipment>0: capability = player.player_incomingshipment else: capability=0 if capability > requirment: player.player_outgoingshipment = requirment else: player.player_outgoingshipment = capability if player.player_inventory < 0: player.player_backorder = player.player_inventory*-1 player.player_totalcost = player.in_round( player.round_number - 1).player_totalcost + player.player_inventory * -1 else: player.player_backorder = 0 player.player_totalcost = player.in_round( player.round_number - 1).player_totalcost + player.player_inventory * 0.5 else: prev_player=player.in_round(player.round_number-1) player.player_inventory=prev_player.player_inventory+player.player_incomingshipment-player.player_demand # player.player_totalcost=C.INITIAL_INVENTORY*0.5+player.in_round(player.round_number-1).player_totalcost def vars_for_template(player: Player): group = player.group demand=0 if group.get_player_by_role(C.CMA_ROLE).round_number<=2: demand = C.CUSTOMER_ROUND4 else: prev_playerA_2week = group.get_player_by_role(C.OEMA_ROLE).in_round(player.round_number - 2) prev_playerB_2week = group.get_player_by_role(C.OEMB_ROLE).in_round(player.round_number - 2) demand = int( round((prev_playerA_2week.player_order * 0.6) + (prev_playerB_2week.player_order * 0.4), 0)) return { "demand": demand } class CMB(Page): form_model = 'player' form_fields = ['player_order'] @staticmethod def is_displayed(player: Player): return player.role == C.CMB_ROLE @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group player.player_demand=C.CUSTOMER_ROUND4 player.player_inventory = C.INITIAL_INVENTORY player.player_outgoingshipment=player.player_demand if player.round_number == 1: player.player_incomingshipment = C.INITIAL_INCOMING_SHIPMENT player.player_inventory = player.player_inventory + player.player_incomingshipment - player.player_demand player.player_totalcost = 0.5 * C.INITIAL_INVENTORY player.player_demand = C.CUSTOMER_ROUND4 elif player.round_number == 2: player.player_incomingshipment = C.INITIAL_INCOMING_SHIPMENT player.player_inventory = player.player_inventory + player.player_incomingshipment - player.player_demand player.player_totalcost = 0.5 * C.INITIAL_INVENTORY + player.in_round( player.round_number - 1).player_totalcost player.player_demand = C.CUSTOMER_ROUND4 elif player.round_number>=3: prev_player=player.in_round(player.round_number-1) prev_player_2week = player.in_round(player.round_number-2) prev_playerA_2week = group.get_player_by_role(C.OEMA_ROLE).in_round(player.round_number-2) prev_playerB_2week = group.get_player_by_role(C.OEMB_ROLE).in_round(player.round_number-2) player.player_demand = int(round((prev_playerA_2week.player_order*0.4)+(prev_playerB_2week.player_order*0.6),0)) player.player_incomingshipment=prev_player_2week.player_order player.player_inventory=prev_player.player_inventory+ player.player_incomingshipment- player.player_demand requirment = player.player_demand + player.player_backorder if player.in_round(player.round_number - 1).player_inventory > 0 and player.player_incomingshipment>0: capability = player.in_round(player.round_number - 1).player_inventory + player.player_incomingshipment elif player.in_round(player.round_number - 1).player_inventory <= 0 and player.player_incomingshipment>0: capability = player.player_incomingshipment else: capability=0 if capability > requirment: player.player_outgoingshipment = requirment else: player.player_outgoingshipment = capability if player.player_inventory<0: player.player_backorder=player.player_inventory*-1 player.player_totalcost=player.in_round(player.round_number-1).player_totalcost+player.player_inventory*-1 else: player.player_backorder=0 player.player_totalcost=player.in_round(player.round_number-1).player_totalcost+player.player_inventory*0.5 else: prev_player=player.in_round(player.round_number-1) player.player_inventory=prev_player.player_inventory+player.player_incomingshipment-player.player_demand # player.player_totalcost=C.INITIAL_INVENTORY*0.5+player.in_round(player.round_number-1).player_totalcost def vars_for_template(player: Player): group = player.group demand = 0 if group.get_player_by_role(C.CMA_ROLE).round_number <= 2: demand = C.CUSTOMER_ROUND4 else: prev_playerA_2week = group.get_player_by_role(C.OEMA_ROLE).in_round(player.round_number - 2) prev_playerB_2week = group.get_player_by_role(C.OEMB_ROLE).in_round(player.round_number - 2) demand = int( round((prev_playerA_2week.player_order * 0.4) + (prev_playerB_2week.player_order * 0.6), 0)) return { "demand": demand } class Waitpage(WaitPage): title_text = 'Wait for next round...' body_text = 'If you are a component manufacturer, please click "Next button" to go to next round; If you are an OEM, please wait until everyone finish their session to turn into next page. The page will automatically turn into next round.' @staticmethod def is_displayed(player: Player): return True class partialpageforCMA(Page): form_model = 'player' @staticmethod def is_displayed(self): return self.group.treatment == False and self.role == C.CMA_ROLE @staticmethod def vars_for_template(player: Player): group = player.group return dict( OEMAorder = (group.get_player_by_role(C.OEMA_ROLE).in_round(player.round_number).player_order), OEMAinventory = group.get_player_by_role(C.OEMA_ROLE).in_round(player.round_number).player_inventory, OEMAbackorder = group.get_player_by_role(C.OEMA_ROLE).in_round(player.round_number).player_backorder, ) class partialpageforCMB(Page): form_model = 'player' @staticmethod def is_displayed(self): return self.group.treatment == False and self.role == C.CMB_ROLE @staticmethod def vars_for_template(player: Player): group = player.group return dict( OEMBorder = (group.get_player_by_role(C.OEMB_ROLE).in_round(player.round_number).player_order), OEMBinventory = group.get_player_by_role(C.OEMB_ROLE).in_round(player.round_number).player_inventory, OEMBbackorder = group.get_player_by_role(C.OEMB_ROLE).in_round(player.round_number).player_backorder, ) class Anonymous_Survey_Platform(Page): form_model = 'player' @staticmethod def is_displayed(self): return self.group.treatment == True and (self.role == C.CMA_ROLE or self.role == C.CMB_ROLE) @staticmethod def vars_for_template(player: Player): group = player.group oemainventory =group.get_player_by_role(C.OEMA_ROLE).player_inventory oembinventory=group.get_player_by_role(C.OEMA_ROLE).player_inventory if oemainventory>0 and oembinventory >0: avg_inventory= (oembinventory+oemainventory)/2 elif oemainventory<0 and oembinventory>0: avg_inventory = (oembinventory ) / 2 elif oemainventory>0 and oembinventory<0: avg_inventory = (oemainventory ) / 2 else: avg_inventory=0.0 return dict( avg_order=(group.get_player_by_role(C.OEMA_ROLE).player_order+group.get_player_by_role(C.OEMB_ROLE).player_order)/2, avg_inventory=avg_inventory, avg_backorder= (group.get_player_by_role(C.OEMA_ROLE).player_backorder+group.get_player_by_role(C.OEMB_ROLE).player_backorder)/2, ) class Result(Page): form_model = 'player' def before_session_starts(self): # wait for all groups to finish self.group_like_rounds() @staticmethod def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS @staticmethod def vars_for_template(player: Player): session = player.session subsession = player.subsession return { "winners": showwinner(subsession), "max":showmax(subsession) } class Questionnare(Page): form_model = 'player' form_fields = ['P1', 'P2', 'p4l','p4o','p4b', 'p3', 'p4123bo','p4123bo1','p4123bo2', 'p6', 'p7123', 'p7123d','p7123r','p5', 'p8', 'p9', 'p10', 'p11', 'p12', 'p13', 'p14', 'p15', 'p16', 'gender', 'age', 'education', 'loc', 'bk', 'carrer', 'brgame', 'kgscm', 'kgscmhow', 'idustry'] @staticmethod def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS class Waitpage2(WaitPage): wait_for_all_groups = True title_text = 'Wait for others until they finished...' body_text = 'Congragulation! You finished the semiconductor game. Now, please wait for the results.' @staticmethod def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS page_sequence = [Welocme, OEMA, OEMB, CMA, CMB, Waitpage, Anonymous_Survey_Platform, partialpageforCMA,partialpageforCMB,Questionnare,Waitpage2, Result]