Grupos
Puedes dividir a los jugadores en grupos para juegos multijugador. (Si solo necesitas grupos en el sentido de «grupos de tratamiento», donde los jugadores no interactúan entre sí, entonces consulta Tratamientos.)
Para establecer el tamaño del grupo, configura C.PLAYERS_PER_GROUP. Por ejemplo, para un juego de 2 jugadores, establece PLAYERS_PER_GROUP = 2.
Si todos los jugadores deben estar en el mismo grupo, o si es un juego para un solo jugador, configúralo en None:
Cada jugador tiene un atributo id_in_group, que te indicará si es el jugador 1, el jugador 2, etc.
Obteniendo jugadores
Los objetos de grupo tienen los siguientes métodos:
get_players()
Devuelve una lista de los jugadores en el grupo (ordenada por id_in_group).
get_player_by_id(n)
Devuelve el jugador en el grupo con el dado id_in_group.
Obteniendo otros jugadores
Los objetos de jugador tienen los métodos get_others_in_group() y get_others_in_subsession() que devuelven una lista de los otros jugadores en el grupo y la subsesión.
Roles
Si cada grupo tiene múltiples roles, como comprador/vendedor, principal/agente, etc., puedes definirlos en constantes. Haz que sus nombres terminen con _ROLE:
class C(BaseConstants):
...
PRINCIPAL_ROLE = 'Principal'
AGENT_ROLE = 'Agent
oTree asignará automáticamente cada role a un jugador diferente (secuencialmente según id_in_group). Puedes usar esto para mostrar contenido diferente a cada rol, por ejemplo:
class AgentPage(Page):
@staticmethod
def is_displayed(player):
return player.role == C.AGENT_ROLE
En una plantilla:
You are the {{ player.role }}.
También puedes usar group.get_player_by_role(), que es similar a get_player_by_id():
def set_payoffs(group):
principal = group.get_player_by_role(C.PRINCIPAL_ROLE)
agent = group.get_player_by_role(C.AGENT_ROLE)
# ...
Si deseas cambiar los roles de los jugadores, debes reorganizar los grupos, utilizando group.set_players(), subsession.group_randomly(), etc.
Emparejamiento de grupos
Emparejamiento fijo
Por defecto, en cada ronda, los jugadores se dividen en grupos de C.PLAYERS_PER_GROUP. Se agrupan secuencialmente; por ejemplo, si hay 2 jugadores por grupo, entonces P1 y P2 se agruparían juntos, y así lo harían P3 y P4, y así sucesivamente. id_in_group también se asigna secuencialmente dentro de cada grupo.
Esto significa que, por defecto, los grupos son los mismos en cada ronda, e incluso entre aplicaciones que tienen el mismo PLAYERS_PER_GROUP.
Si deseas reorganizar los grupos, puedes usar las técnicas a continuación.
group_randomly()
Las subsesiones tienen un método group_randomly() que baraja a los jugadores aleatoriamente, de modo que pueden terminar en cualquier grupo y en cualquier posición dentro del grupo.
Si deseas barajar a los jugadores entre grupos pero mantener a los jugadores en roles fijos, utiliza group_randomly(fixed_id_in_group=True).
Por ejemplo, esto agrupará a los jugadores aleatoriamente en cada ronda:
def creating_session(subsession):
subsession.group_randomly()
Esto agrupará a los jugadores aleatoriamente en cada ronda, pero mantendrá id_in_group fijo:
def creating_session(subsession):
subsession.group_randomly(fixed_id_in_group=True)
Para el siguiente ejemplo, supongamos que PLAYERS_PER_GROUP = 3 y que hay 12 participantes en la sesión:
def creating_session(subsession):
print(subsession.get_group_matrix()) # outputs the following:
# [[1, 2, 3],
# [4, 5, 6],
# [7, 8, 9],
# [10, 11, 12]]
subsession.group_randomly(fixed_id_in_group=True)
print(subsession.get_group_matrix()) # outputs the following:
# [[1, 8, 12],
# [10, 5, 3],
# [4, 2, 6],
# [7, 11, 9]]
subsession.group_randomly()
print(subsession.get_group_matrix()) # outputs the following:
# [[8, 10, 3],
# [4, 11, 2],
# [9, 1, 6],
# [12, 5, 7]]
group_like_round()
Para copiar la estructura del grupo de una ronda a otra, utiliza el método group_like_round(n). El argumento de este método es el número de ronda cuya estructura de grupo debe ser copiada.
En el siguiente ejemplo, los grupos se barajan en la ronda 1, y luego las rondas subsiguientes copian la estructura de agrupamiento de la ronda 1.
def creating_session(subsession):
if subsession.round_number == 1:
# <some shuffling code here>
else:
subsession.group_like_round(1)
get_group_matrix()
Las subsesiones tienen un método llamado get_group_matrix() que devuelve la estructura de los grupos como una matriz, por ejemplo:
[[1, 3, 5],
[7, 9, 11],
[2, 4, 6],
[8, 10, 12]]
set_group_matrix()
set_group_matrix() te permite modificar la estructura del grupo de la manera que desees. Primero, obtén la lista de jugadores con get_players(), o la matriz de grupo preexistente con get_group_matrix(). Luego, crea tu matriz y pásala a set_group_matrix():
def creating_session(subsession):
matrix = subsession.get_group_matrix()
for row in matrix:
row.reverse()
# now the 'matrix' variable looks like this,
# but it hasn't been saved yet!
# [[3, 2, 1],
# [6, 5, 4],
# [9, 8, 7],
# [12, 11, 10]]
# save it
subsession.set_group_matrix(matrix)
También puedes pasar una matriz de enteros. Debe contener todos los enteros del 1 al número de jugadores en la subsesión. Cada entero representa al jugador que tiene ese id_in_subsession. Por ejemplo:
def creating_session(subsession):
new_structure = [[1,3,5], [7,9,11], [2,4,6], [8,10,12]]
subsession.set_group_matrix(new_structure)
print(subsession.get_group_matrix()) # will output this:
# [[1, 3, 5],
# [7, 9, 11],
# [2, 4, 6],
# [8, 10, 12]]
Para verificar si tu mezcla de grupos funcionó correctamente, abre tu navegador en la pestaña «Resultados» de tu sesión y observa las columnas group y id_in_group en cada ronda.
group.set_players()
Esto es similar a set_group_matrix, pero solo reorganiza a los jugadores dentro de un grupo, por ejemplo, para que puedas darles diferentes roles.
Reorganización durante la sesión
creating_session suele ser un buen lugar para reorganizar grupos, pero recuerda que creating_session se ejecuta cuando se crea la sesión, antes de que los jugadores comiencen a jugar. Así que, si tu lógica de reorganización necesita depender de algo que sucede después de que la sesión comienza, deberías hacer la reorganización en una página de espera en su lugar.
Necesitas crear un WaitPage con wait_for_all_groups=True y poner el código de reorganización en after_all_players_arrive:
class ShuffleWaitPage(WaitPage):
wait_for_all_groups = True
@staticmethod
def after_all_players_arrive(subsession):
subsession.group_randomly()
# etc...
Agrupar por tiempo de llegada
Consulta group_by_arrival_time.