应用&轮次¶
应用¶
一个oTree应用就是一个包含Python与HTML代码的文件夹。一个项目包含多个应用。一个会话基本上就是一个接一个被游玩的应用序列。
组合应用¶
你可以通过设置session config的 'app_sequence'
来组合应用。
在应用之间传递数据¶
轮次¶
你可以通过设置 C.NUM_ROUNDS
来使一个游戏进行多轮。举例来说,如果你的session config中的 app_sequence
是 ['app1', 'app2']
,同时 app1
中 NUM_ROUNDS = 3
且 app2
中 NUM_ROUNDS = 1
,那么你的会话中就包含4个子会话。
轮数¶
你可以通过 player.round_number
(目前subsession,group,player 与 page 对象有此属性)来获得当前的轮数。轮数从1开始。
在应用或轮次之间传递数据¶
每一轮都拥有独立的subsession, Group
, 与 Player
对象。举例来说,假定你在第一轮中设定了 player.my_field = True
。在第二轮时,你试图访问 player.my_field
,你会发现它的值是 None
。这是因为第一轮的 Player
对象与第二轮的 Player
对象是独立的。
为了获得之前轮次或者应用的数据,你可以使用下面描述的这些技巧。
in_rounds, in_previous_rounds, in_round, etc.¶
Player,group 与 subsession 对象有下面这些方法:
- in_previous_rounds()
- in_all_rounds()
- in_rounds()
- in_round()
举例来说,如果你在一个10轮游戏的最后一轮, player.in_previous_rounds()
会返回一个由9个player对象组成的列表,就代表了当前参与者在之前轮次的对象。
player.in_all_rounds()
几乎与上面相同,只不过列表中有10个对象,因为它包含了当前轮次的player对象。
player.in_rounds(m, n)
返回一个player对象的列表,其中代表了同一参与人第 m
到 n
轮的player对象。
player.in_round(m)
返回第 m
轮的player对象。举例来说,要获得玩家前一轮的收益,可用:
prev_player = player.in_round(player.round_number - 1)
print(prev_player.payoff)
这些方法对于subsession也是相同的(例如 subsession.in_all_rounds()
)。
这些方法对于group也是相同的,但是如果你在轮次之间重新安排了小组,那么使用这些方法是没有意义的。
参与人字段¶
如果你想要获取一位参与人在之前应用中的数据,你应当将数据存储在参与人对象中,这样数据可以在不同应用间保持。(参考 参与人)。(in_all_rounds()
仅在你需要获取同一应用中的之前轮次的数据时有用。)
设置并定义 PARTICIPANT_FIELDS
,它是一个列表,包含了你想要在参与人上定义的字段名称。
在代码中,你可以取出或设置这些字段上的任何类型的数据:
participant.mylist = [1, 2, 3]
(在内部,所有参与人字段均存储在一个名为 participant.vars
的字典中。participant.xyz
等价于 participant.vars['xyz']
。)
会话字段¶
对于会话中所有参与人都相同的全局变量,可将其添加到 SESSION_FIELDS
中,这与 PARTICIPANT_FIELDS
用法相同。在内部,会话字段储存在 session.vars
中。
可变轮数¶
如果你想要可变的轮数,考虑使用 实时页面。
作为替代方案,你可以将 NUM_ROUNDS
设为一个较大的数,然后在应用中,有条件地隐藏 {{ next_button }}
元素,使得用户无法继续进行到下一页面,或者使用 app_after_this_page。 但是注意轮数较大(例如超过100)可能会导致性能问题,所以请仔细测试你的程序。