Code Monkey home page Code Monkey logo

ajiaco's People

Watchers

 avatar  avatar  avatar

ajiaco's Issues

AEP 0001: The ajiaco game definition overview

AEP 0001: The ajiaco game definition overview.

Rationale

This document defines how to define a Model-View-Controller game using the
Ajiaco-Social Experiment Framework. This document only aims the
syntax to be used to define the game and not the internal implementation
details.

Also some definition will be referenced to the oTree
documentation to be used as inspiration.

Game definition

The game is defined as an instance of the class ajiaco.Game. This instance
contains all the configuration utilities to run the game and a series of
constants defined by the user. For example if we wan to define the
Matching Pennies Game from the oTree Tutorial

Example:

# we import the ajiaco module as ajc
import ajiaco as ajc

# we define the game and store it into the
# game variable
game = ajc.Game(
    "mpennies", display="Matching Pennies",
    groups_size=2, rounds=4, demo_participants=2,
    stakes=100)

The Game class only has one required parameter called name. Name is
the unique string that identify the game inside the project. This value will
be prefixed in every database table (in our case the internal name of the
player model will be mpennies_player) and will be used to create the
urls to navigate the experiment.

From the oTree point of view this value replaces the SESSIONS_CONFIG
name key and the Constants.name_in_url value.

Optional parameters

  • display the name to be displayed in the Ajiaco Admin and demo
    interface. By default is the same values as name.

    oTree SESSIONS_CONFIG display_name key

  • group_size The number of player of the groups (default None). If
    The value is None all the players are in only one group, and also
    the programmer can manipulate the players manually to make arbitrary number
    of groups whit arbitrary sizes.

    Equivalent to oTree Constants.players_per_group

  • rounds The number of times to repeat this game (default 1)

    Equivalent to oTree Constants.num_rounds

  • demo_participants How many participants are needed to create a
    game for the demo page. By default is the number needed to fill a group.

Constants

The Game class also accept any another parameter and store it as constant
inside the game instance. For example the stakes=100.

Accessing the parameters and constants

The game configuration is reand only and you can access any value as regular
attribute of any Python object. Example

game.name
game.display
game.stakes

game.name = "foo"  # this will fail
game.nonexistent_constant = "foo"  # this also will fail

Models

Ajiaco offers 4 model to store your data

  1. Game.participants_storage Data about the participant of the game
  2. Game.sessions_storage Data about all the sessions of the game.
  3. Game.rounds_storage Data about the rounds of all the sessions of
    the game.
  4. Game.groups_storage Data about all groups inside every round of
    every session.
  5. Game.players_storage Data about the player of every group.

Defining custom data for the models.

To add attributes to the any of the models you need to call method
add_fields just after the instantiation of the Game class. After this
Ajiaco will prevent any attempt of the modification from inside any "hook"
or "page". The syntax of this method is:

game.model_storage.add_fields(
    field_name1=field_type1,
    field_name2=field_type2,
    ....)

Where field type can be the Python classes:

  • int: integers
  • float: floating point numbers.
  • string: text
  • bool: True or False.
  • list: a sorted sequence
  • dict: a map.
  • ajiaco.binary: binary data.
  • ajiaco.money: currency values.

For example if we want to continue with the oTree tutorial 3, and add the
suggested attributes is_winner, and tails inside the players; and
paying_round inside the session, the code will be:

game.sessions_storage.add_fields(
    paying_round=int)

game.players_storage.add_fields(
    tails=bool,
    is_winner=bool)

Hooks

The hooks are functions to be executed in some special cases. In this
development stage only one hooks are designed the round creation hook

Session round creation hook

Equivalent to oTree Subsession.creating_session method.

Allows you to initialize the round, by setting initial values on fields on
players, groups, participants, or the rounds. For example to replicate
the same of the oTree tutorial 3:

@game.when
def creating_round(session_round):
    if session_round.is_first:
        # ask if this round is the first
        # in this case a random round is selected and stored
        # inside the session paying_round attribute
        paying_round = random.randint(1, game.rounds)
        session_round.session.paying_round = paying_round

    elif session_round.number == game.half_way:
        # if the round number is the first of the second half
        # invert all the roles
        matrix = session_round.get_group_matrix()
        for row in matrix:
            row.reverse()
        session_round.set_group_matrix(matrix)

    elif session_round.number > game.half_way:
        # if the current round is higher than the first
        # of the second half, this simply copy the order of the
        # previous rounds
        session_round.group_like_round(game.half_way)

Pages

The final part of the game is design what the participant will see in their
screen. And this is defined (as before) as functions.

Forms

To create the tutorial requested choice page, Ajiaco suggest the next code:

@game.page.show
def choice(page):
    page.player.tails = page.ask(
        "Choice tails or heads",
        choices={"Tails": True, "Heads": False}
    ).check(
        page.player.number == 1 and page.player.tails == True,
        "player number 1 can only choice 'tails'")
  • The line @game.page.show register the function choice as a page
    inside the game.
  • The function registered as pages only receives one parameter called
    page.
  • The page parameter is utility that allow the user to send and
    and retrieve data from the page HTML code (normally this is all hidden)
    and also can access the current player, group, round and session that
    are asking for the page.
  • The entire code of the function is only 1 line that create a form
    (page.ask) that ask the user to select from a combo box between
    Heads and Tails. Also add to this form a validator that check (only
    for show the functionality) that check if the player number 1 select tails.

Wait Pages

@game.page.wait_for("group")
def wait(page):
    matcher = page.group.player_number(1)
    mismatcher = page.group.player_number(2)

    matcher.is_winner = matcher.tails == mismatcher.tails
    mismatcher.is_winner = not matcher.is_winner

    pround = page.session.paying_round
    for player in [matcher, mismatcher]:
        if group.round.number == pround and player.is_winner:
            player.payoff = game.stakes
        else:
            player.payoff = 0
  • The wait pages are decorated with the code
    @game.page.wait_for(...). The decorator always ask for the players
    to wait. This can be the players of an entire group ("group"), or the
    players of an entire round ("round")

Simple information pages with skip

@game.page.show
def results(page):
    if not page.round.is_last:
        page.skip()
    selections = []
    for p in page.player.in_all_rounds():
        selections.append(p.tails)
    page.set_vars(selections=selections)

In this case the page will be skipped whit page.skip() (equivalent to
oTree Page.is_displayed()) if the current round is not the last one.

Otherwise the page render the list of previous selections.

Future functionalities

Timer

The timer can be implemented as an optional parameter of the decorator
page.show. For example

game.page.show(timeout=60)
def pagename(page):
    ...

Helpers

Maybe we can implement helpers to create tables without using the template
language something like

page.set_vars(
    selections=page.Table(headers="selections", rows=selections))

Accessing common attributes of the page

Functionalities like page.set_title can be easily implemented to the
page.

References

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.