oTree学习教程(六)Multiplayer games
组
oTree的群组系统允许您将玩家分成小组并让玩家与同一组中的其他玩家互动。这通常用于多人游戏。(如果您只需要“治疗组”意义上的团体,其中玩家实际上并不相互交流,那么请参阅处理。)
要设置组大小,请转到应用的models.py并进行设置 Constants.players_per_group
。例如,对于2人游戏:
如果所有玩家都在同一组中,或者如果是单人游戏,请将其设置为None
:
在这种情况下,self.group.get_players()
将返回每个人的subsession。
每个玩家都有一个属性id_in_group
,告诉你它是玩家1
,玩家2
等。
获得玩家
组对象具有以下方法:
get_players()
返回组中的玩家列表(按排序id_in_group
)。
get_player_by_id(n)
返回给定组中的玩家id_in_group
。
get_player_by_role(r)
返回具有给定角色的玩家。如果使用此方法,则必须定义角色方法。例如:
获得其他玩家
Player对象具有get_others_in_group()和get_others_in_subsession()方法,这些方法返回组和子会话中其他玩家的列表。 例如,对于2人组,您可以获得玩家的合作伙伴:
组匹配
固定匹配
默认情况下,在每轮中,玩家被分成几组Constants.players_per_group
。它们按顺序分组 - 例如,如果每组有2个玩家,则P1和P2将组合在一起,P3和P4也是如此,依此类推。id_in_group
也在每个组中按顺序分配。
这意味着默认情况下,每组中的组都相同,甚至在具有相同的应用程序之间也是如此players_per_group
。
如果要重新排列组,可以使用以下技巧。
group_randomly()
子会话有一种group_randomly()
随机分配玩家的方法,因此他们可以在任何组中以及组内的任何位置结束。
如果你想在小组之间洗牌,但让玩家保持固定角色,请使用group_randomly(fixed_id_in_group=True)
。
例如,这将每轮随机分组玩家:
这将每轮随机分组玩家,但保持id_in_group
固定:
下面的示例使用命令行创建一个包含12个玩家的公共产品游戏,然后进行交互式组改组。假设,12人游戏将有4组:otree shell
players_per_group = 3
请注意,在每轮中,玩家最初按固定匹配中的描述顺序分组,即使您在前一轮中进行了一些改组。要抵消这种情况,可以使用group_like_round()。
group_like_round()
要将组结构从一轮复制到另一轮,请使用该group_like_round(n)
方法。此方法的参数是应该复制组结构的整数。
在下面的示例中,组在第1轮中进行混洗,然后后续轮次复制第1轮的分组结构。
get_group_matrix()
子会话有一个方法get_group_matrix()
,它将组的结构作为矩阵返回,即列表列表,每个子列表是一个组中的队列,按顺序排列id_in_group
。
以下几行是等效的。
set_group_matrix()允许您以任何方式修改组结构。 首先,使用get_players()获取玩家列表,或使用get_group_matrix()获取预先存在的组矩阵。 使用Python列表操作构建矩阵,如.extend(),. append(),. pop(),. relverse(),以及列表索引和切片(例如[0],[2:4])。 然后将此修改后的矩阵传递给set_group_matrix():
以下是在creation_session中的外观:
您还可以传递整数矩阵。它必须包含从1到subsession中的玩家数量的所有整数。每个整数代表具有该值的玩家id_in_subsession
。例如:
您甚至可以set_group_matrix
用来制作不均匀尺寸的组。
要检查您的组改组是否正常工作,请将浏览器打开到会话的“结果”选项卡,然后查看每轮中的group
和id_in_group
列。
group.set_players()
如果您只想重新排列组中的玩家,您可以使用该方法group.set_players()
作为参数,按顺序分配给该组的玩家列表。
例如,如果您希望将玩家重新分配到相同的组但是在其组内随机改变角色(例如,因此玩家1将成为玩家2或保持玩家1),您将执行以下操作:
示例:将玩家分配给角色
假设你想根据一些外部标准(如性别)将玩家分配到角色。
此示例显示如何制作3个玩家的组,其中玩家1是男性,玩家2和3是女性。该示例假定您已经设置participant.vars['gender']
了每个参与者(例如,在之前的应用程序中),并且女性玩家的数量是男性玩家的两倍。
creating_session通常是一个改组的好地方,但请记住,在创建会话之前,在玩家开始游戏之前运行creation_session。 因此,如果您的洗牌逻辑需要依赖会话开始后发生的事情,那么您应该在等待页面中进行洗牌。
假设您已在Subsession类上定义了一个名为do_my_shuffle()的方法,该方法使用set_group_matrix等。
您需要使用wait_for_all_groups = True创建WaitPage并将洗牌代码放在after_all_players_arrive中:
在此等待页面之后,玩家将被重新分配给他们的新组。
假设您有一个包含多轮的游戏,并且在开头的等待页面中您想要对组进行随机播放,并将这个新的组结构应用于所有轮次。 您可以将group_like_round()与in_rounds()一起使用。 您还应该使用is_displayed(),以便此方法仅执行一次。 例如:
到达时间分组
请参阅group_by_arrival_time。
示例:可配置组大小
假设您希望每次创建会话时都能够配置每个组的玩家数量。(设置 类型是这样,但仅当所有玩家都在同一组中时。)Constants.players_per_group = None
如配置会话中所述,在会话配置中创建一个密钥(您可以调用它players_per_group
),然后使用此代码将玩家分成这个大小的组:
等待页面
当一个玩家需要等待其他人采取某些行动才能继续之前,等待页面是必要的。例如,在最后通game游戏中,玩家2在看到玩家1的提议之前不能接受或拒绝。
如果你WaitPage
的页面序列中有一个,那么oTree会等到组中的所有玩家都到达序列中的那个点,然后允许所有玩家继续进行。
如果你的subsession有多个组同时演示,并且你想要一个等待所有组的等待页面(即subsession中的所有玩家),你可以在等待页面上设置wait_for_all_groups = True属性,例如:
有关组的更多信息,请参阅组。
等待页面可以定义以下方法:
after_all_players_arrive()
您在此处定义的任何代码都将在所有玩家到达等待页面后执行。例如,这是设置玩家收益或确定胜利者的好地方。
注意,你不能在after_all_players_arrive中引用self.player,因为代码对整个组执行一次,而不是对每个单独的玩家执行。 (但是,您可以在等待页面中使用self.player is_displayed。)
is_displayed()
与常规页面的工作方式相同。如果返回,False
则玩家跳过等待页面。
如果组中的某些或所有玩家跳过等待页面,则after_all_players_arrive()
可能无法运行。
group_by_arrival_time
如果您在WaitPage上设置,则玩家将按照他们到达该等待页面的顺序进行分组:group_by_arrival_time = True
例如,如果players_per_group = 2,则到达等待页面的前2个玩家将被组合在一起,然后是接下来的2个玩家,依此类推。
这在某些参与者可能退出的会话中很有用(例如,在线实验,或允许参与者提前退出的同意页面的实验),或者某些参与者比其他参与者花费更长时间的会话。
使用group_by_arrival_time的典型方法是将其放在过滤掉参与者的应用之后。 例如,如果您的会话有一个同意页面,让参与者有机会选择退出研究,您可以制作一个仅包含同意页面的“同意”应用,然后使用['consent','my_game这样的app_sequence '],其中my_game使用group_by_arrival_time。 这意味着如果有人选择同意,他们将被排除在my_game中的分组之外。
如果游戏有多轮,您可能只想按第1轮的到达时间进行分组:
如果你这样做,那么后续轮次将保持与第1轮相同的组结构。否则,将在每轮中按照到达时间对玩家进行重新分组。 (group_by_arrival_time将组结构复制到未来轮次。)
笔记:
id_in_group不一定按照玩家到达页面的顺序分配。
group_by_arrival_time只能在等待页面是page_sequence中的第一页时使用
如果在具有group_by_arrival_time的页面上使用is_displayed,则它应仅基于轮数。 不要使用is_displayed向某些玩家显示该页面,而不是其他玩家。
如果group_by_arrival_time = True,则在creation_session中,所有玩家最初将在同一组中。 当玩家到达等待页面时,组仅“在运行中”创建。
如果您需要进一步控制将玩家安排到组中,请使用get_players_for_group()。
get_players_for_group()
如果您正在使用group_by_arrival_time并希望更好地控制将哪些玩家分配到一起,则可以使用get_players_for_group()。
假设除了按到达时间进行分组外,您还需要每组人员由1名男子和1名女子(或2名“A”队员和2名“B”队员等)组成。
如果您定义了一个名为get_players_for_group的方法,则只要新玩家到达等待页面,就会调用它。 该方法的参数是等待分组的玩家列表(不是已断开连接或关闭其浏览器的人)。 如果您选择其中一些玩家并将其作为列表返回,那么这些玩家将被分配到一个组,并向前移动。 如果您没有返回任何内容,则不会发生分组。
这是一个例子,每组有2个A球员,2个B球员。
防止玩家卡在等待页面上
一个常见的问题尤其是在线实验时,玩家会等待其组中的其他玩家辍学或太慢。
以下是您可以采取的一些措施来减少此问题:
使用group_by_arrival_time
如上所述,您可以使用,group_by_arrival_time
以便只有在同一时间主动显示的玩家才能组合在一起。
group_by_arrival_time
如果在“锁定”任务之后使用,则效果很好。换句话说,在您的多人游戏之前,您可以进行单人游戏任务。这个想法是参与者努力完成这个初始任务,他们不太可能在那之后辍学。
使用页面超时
在每个页面上使用timeout_seconds,这样如果播放器处于慢速或非活动状态,其页面将自动前进。或者,您可以通过单击管理界面中的“提前最慢参与者”按钮手动强制超时。
自定义等待页面的外观
您可以通过设置title_text
和body_text
属性来自定义等待页面上显示的文本,例如:
您还可以创建自定义等待页面模板。例如,将此保存为my_app/templates/my_app/MyWaitPage.html
(此模板必须扩展'otree / WaitPage.html'):
然后告诉您的等待页面使用此模板:
然后你可以vars_for_template
按照通常的方式使用。实际上,body_text
和title_text
属性只是设置的简写vars_for_template
; 以下2个代码段是等效的:
如果要全局应用自定义等待页面模板,请将其保存到_templates/global/WaitPage.html
。然后,oTree将自动在任何地方使用它而不是内置的等待页面。
CSS和JavaScript在等待页面
等待页面具有相同的块结构,常规页面(global_scripts
,app_scripts
,scripts
,等...),这样你就可以按照所描述的相同的指令JavaScript和CSS 和自定义主题。
例如,要将CSS应用于自定义等待页面_templates/global/WaitPage.html
,请global_scripts
在模板中放置一个块。
你甚至可以让其他自定义页面等待继承_templates/global/WaitPage.html
,现在的样子常规页面继承_templates/global/Page.html
,并且可以限定块app_scripts
和scripts
等。
聊天
您可以在页面中添加聊天室,以便参与者可以相互通信。
以前使用过该otreechat附加组件的人的注意事项:
2017年11月,otreechat附加组件合并为otree。 现在,您不再需要单独安装otreechat,并且您的模板中不需要{%load otreechat}。
用法
基本用法
无论您想在模板中使用聊天框,请使用:
这将在同一组中的玩家之间建立聊天室,其中每个玩家的昵称显示为“玩家1”,“玩家2”等(基于玩家的id_in_group
)。
自定义昵称和聊天室成员
您可以传递可选参数channel
和/或nickname
像这样:
昵称
nickname
是将在聊天中为该用户显示的昵称。典型的用法是。{% chat nickname=player.role %}
频道
channel
是聊天室的名称,这意味着如果2个玩家拥有相同的名字channel
,他们可以互相聊天。 channel
没有显示在用户界面中; 它只是在内部使用。它的默认值是group.id
,意味着组中的所有玩家可以一起聊天。您可以使用channel
以将聊天范围扩展到组的当前页面或子分区等(请参阅下面的示例)。无论channel
参数的价值如何,聊天至少应限定在同一会话和同一应用中的玩家。
示例:按角色聊天¶
这里有一个例子,我们在团队中基于角色进行沟通,而不是群体内的沟通,例如,所有买家可以互相交谈,所有卖家都可以互相交谈。
然后在模板中:
示例:跨轮次聊天¶
如果您需要玩家与当前处于不同轮次游戏中的玩家聊天,您可以:
示例:所有轮次中的所有组之间的聊天¶
如果您希望会话中的每个人都可以自由地互相聊天,那么只需:
(数字1并不重要;重要的是每个人都一样。)
造型
要自定义样式,只需在元素后面加入一些CSS ,例如:{% chat %}
您还可以通过将其置于<div>
父级内部并为其设置样式来自定义外观<div>
。例如,要设置宽度:
页面上的多个聊天
您可以在每个页面上放置多个框,以便玩家可以同时处于多个通道中。{% chat %}
例如,此代码可以与组中的每个其他玩家进行1:1聊天。
导出聊天记录的
聊天记录下载链接将显示在oTree的常规数据导出页面上。
oTree学习教程(六)Multiplayer games相关推荐
- 【STM32】标准库与HAL库对照学习教程六--位带操作
[STM32]标准库与HAL库对照学习教程六--位带操作 一.前言 二.准备工作 三.位带介绍 1.位带操作 2.STM32位带及位带别名区域 四.位带区与位带别名区地址转换 五.GPIO的位带操作 ...
- 【OpenCV图像处理入门学习教程六】基于Python的网络爬虫与OpenCV扩展库中的人脸识别算法比较
OpenCV图像处理入门学习教程系列,上一篇第五篇:基于背景差分法的视频目标运动侦测 一.网络爬虫简介(Python3) 网络爬虫,大家应该不陌生了.接下来援引一些Jack-Cui在专栏<Pyt ...
- oTree学习教程(七)Apps rounds
应用 在oTree(和Django)中,app是一个包含Python和HTML代码的文件夹.当您创建oTree项目时,它会预先加载各种应用程序,例如 public_goods和dictator.会话基 ...
- oTree学习教程(一)概念性概述
概念概述 Sessions 在oTree中,会话是指多个参与者参与一系列任务或游戏的事件.会话的一个例子是: "许多参与者将来到实验室并进行公共产品游戏,然后进行问卷调查.参与者获得的奖金为 ...
- oTree学习教程(二)Models
Models models.py 是您定义应用程序数据模型的位置: Subsession Group Player Player是Group的一部分,这是Subsession的一部分.请参阅概念概述. ...
- oTree学习教程(四)Templates
模板 您应用的templates/文件夹将包含显示给玩家的HTML模板. 模板语法 变量 您可以显示如下变量: 模板中提供以下变量: player:当前正在查看该页面的玩家 group:当前玩家所属的 ...
- oTree学习教程(五)Forms
oTree中的每个页面都可以包含一个表单,玩家应通过单击"下一步"按钮填写并提交该表单.要创建表单,首先需要Player在models.py中的类中使用字段.然后,在您的Page类 ...
- oTree学习教程(八)Bots
您可以编写模拟参与者播放应用程序的"机器人",以便您可以测试它是否正常运行. 很多oTree用户都跳过写机器人,因为他们认为这很复杂,或者因为他们太忙于为他们的应用程序编写代码.但 ...
- oTree学习教程(三)Pages
Pages 玩家看到的每个页面都是由一个Page类定义的pages.py. 您pages.py必须有一个page_sequence 给出页面顺序的变量.例如: 如果您的游戏有多轮,则会重复此顺序.有关 ...
最新文章
- 儿子和女儿——解释器和编译器的区别与联系
- pytorch实现手写数字识别_Paddle和Pytorch实现MNIST手写数字集识别对比
- Win7下使用DbgPrint
- Ubuntu下用eclipse调试caffe code
- scala 去除重复元素_Scala程序从列表中删除重复项
- 【AI视野·今日NLP 自然语言处理论文速览 第十四期】Thu, 24 Jun 2021
- 如何转换为系统应用_如何将AVI转换为GIF
- python代码示例-《Python编程:从入门到实践》DEMO实例代码
- 【书籍推荐】《美国黒室》
- 算法学习:01背包问题求具体方案
- android ijk 播放器,ijkplayer 播放器:在Android端进行native调试
- 系统明文密码加密传输
- 9:中文乱码处理-Java Web
- 【翠花学Vue】每日打卡——vue打卡1
- 秋季天凉易感冒 冷水洗脸来预防
- 夏にありがとう(向夏天致谢)-因幡晃
- SWM32系列教程2-新建工程
- ZooKeeper命令行
- hbase加入数据 java_插入java数据
- 无标注数据是鸡肋还是宝藏?阿里工程师这样用它​
热门文章
- android王者荣耀号苹果可以登陆吗,王者荣耀安卓转苹果什么时候开始 苹果手机可以用安卓账号登录了吗...
- TCP数据发送之TSO/GSO
- 自动巡检网页发送截图至企业微信群
- 专访 | 吴志强院士:CIM与城市未来
- 建立数据库时连接出错_漫画——你还记得原生的JDBC怎么连接数据库吗?
- 关于2020西门子杯工业自动化线上赛总结(初赛过控篇)
- 六问禅道2:需求的状态和研发阶段
- Makecode编程软件打不开
- vs2022报错无法打开源文件(自定义的头文件)
- 计算机项目管理培训课件,工程项目管理培训PPT工程项目信息管理及计算机应用.ppt...