应用&轮次

应用

一个oTree应用就是一个包含Python与HTML代码的文件夹。一个项目包含多个应用。一个会话基本上就是一个接一个被游玩的应用序列。

组合应用

你可以通过设置session config的 'app_sequence' 来组合应用。

在应用之间传递数据

参考 participant fieldssession fields

轮次

你可以通过设置 C.NUM_ROUNDS 来使一个游戏进行多轮。举例来说,如果你的session config中的 app_sequence['app1', 'app2'],同时 app1NUM_ROUNDS = 3app2NUM_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对象的列表,其中代表了同一参与人第 mn 轮的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)可能会导致性能问题,所以请仔细测试你的程序。