Creating a new Application from Scratch

We will walk through creating a Volunteer Science application from scratch. In this case we will create Tick Tack Toe. This tutorial assumes you are already familiar with html, css, javascript, and jQuery.

To use this tutorial, I recommend using 2 browser windows. The first with this page, and the second to do your work.


Create a new blank experiment

You can always get to your research team page by clicking Research at the top of any Volunteer Science page, then choosing your team. In another tab, go there now.

Near the bottom you see Add New Experiment. Type Tick Tack Toe, choose the Blank template and press Add.

You have created a new experiment. You can return to your experiment page at any time from your Research Team Page then choosing your new experiment from the list.

Your new application is In Development which means it won't yet show up for Volunteer Science users until it is written and tested.

A blank application already comes with several options. We will discuss these later in the tutorial. Let's begin by launching a demonstration of your new app.

Under Launch Demonstration click Launch.

After a few seconds you get to a blank template.


Add HTML File

Let's add some content to your new experiment. Click Quit to return to your experiment page. Near the bottom of your test page you will find Add New Empty File. Create a new blank file called tick_tack_toe.html and click Add.

This brings you to Volunteer Science's built-in file editor.

Insert your new file text here.

Press save when you are finished.

Let's replace the default text with some instructions and our new game-board. The board is a 3x3 table. The contents of each cell is a div with the class square and an id which corresponds to a letter of the alphabet a, b, c....

Paste this text into tick_tack_toe.html and press Save.

    
Please wait for the other player.

Volunteer Science automatically sets your first .html file to the application's main file. Launch your app again. Note that the content has changed to "Please wait for the other player." and has our empty table.


Add CSS File

Let's make the table bigger by adding a .css file. Click Quit to return to your experiment page. Add a new file called tick_tack_toe.css.

Let's make each square 100x100 px, a gray background, and a large centered font. Let's also give the table a grid. The additional parameters are browser specific parameters to disable selection of the contents.

.square {
  width: 100px;
  height: 100px;
  background: #eee;
  font-size: 800%;
  line-height:1em;
  text-align:center;

  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -o-user-select: none;
  user-select: none;
}

#ticktacktoe table, th, td {
  border: 1px solid black;
}

Save tick_tack_toe.css, then Launch your app again. Now you have a proper tick tack toe board.


Add a JavaScript file

Let's make the program do something with javascript. Click Quit to return to your experiment page, and a new file called tick_tack_toe.js.

initialize() is called when your Volunteer Science application is loaded and all players have joined the game. Let's add some code to draw an X and submit your move to the server when you click on a square.

submit() is a Volunteer Science function that takes a string corresponding to a subject's action. You should call it every time a user takes an action that you would like to record for your experiment. Recall that in our .html file, we set the id of each square to a letter a, b, c.... We will submit the cell's id as our move each time the subject clicks a square.

This jQuery code adds a click function to each square which sets the value to X and calls submit().

function initialize() {
  $('.square').click(function() {
     $(this).html('X');
     submit($(this).attr('id'));
  });
}

Save and Launch. Click a few squares, but try to remember the order you clicked. Currently you can click a square more than once -- we'll fix that later.


View Results

Let's see what data we've collected for this session. Quit to return to your experiment page. At the bottom, you will see Results. Click the most recent Test to expand the results. The results are displayed as XML.

I clicked on 3 different squares which called submit() 3 times, resulting in 3 <submit> tags. There is various metadata in the XML, but let's focus on 2 parameters in each <submit> tag. We have a subject identifier, in this case "1" for Player 1. Also, the contents of each <submit> was what we delivered in tick_tack_toe.js when we called submit(). As you can see I clicked squares a,b, then e.


Make your Experiment Multiplayer

Let's make the game multiplayer. Volunteer Science allows you to create an experiment with a range on the number of subjects. Contingent on the population of active subjects, Volunteer Science will attempt to get the maximum number in your experiment. Tick Tack Toe is always 2 players. So let's set both the Minimum Participants and Maximum Participants to 2 then press Update.

In Launch Demonstration the Number of Participants has updated to 2 based on our Minimum Participants. Click Launch.

This time rather than beginning our experiment, we are taken to a waiting room. You can invite other users to play by sending them the provided link. Or you can join and control multiple players from the same web browser. When you click Subject 2 it will bring up the second player in another tab. You should probably move this to its own browser window (right click on the tab).

Look at your browser's address bar up top. You can determine which subject you are from the contents.

For each player, click on a square. Sadly, the X doesn't show up in the other window. Let's fix that now. For each player click Quit.


Fetch New Moves

Edit tick_tack_toe.js (near the bottom of your experiment page).

Volunteer Science notifies your application every time any subject called submit() by calling newMove(participant, moveIndex) with the participant number and their move index. Note that the first index for each subject is 0.

For example, the first time Player 1 calls submit(), Volunteer Science will call newMove(1,0).

If Player 1 calls submit() again, Volunteer Science will call newMove(1,1).

If Player 2 calls submit(), Volunteer Science will call newMove(2,0) indicating that this is Player 2's first submission even though Player 1 has already submitted 2 moves.

newMove() only contains the participant and the index to the move. For any moves that you want to display to the current subject, you must call fetchMove(participant, round, moveIndex, callback). We will discuss rounds later, for now you can use a Volunteer Science JavaScript variable called currentRound.

For Tick Tack Toe, we want to respond every time a player makes a move. Let's call fetchMove() every time newMove() is called.

function newMove(participant, index) {
  fetchMove(participant, currentRound, index, function(val) {
    ...
  });
}

val will contain the string that the other subject submitted, in this case a, b, c.....

Use val to mark the square that the subject submitted. Let's create a variable called mark and set it to X or O based on the participant.

Now use mark in a jQuery statement. It takes the square with the id contained in val and sets the contents to the value of mark.

function newMove(participant, index) {
  fetchMove(participant, currentRound, index, function(val) {
    var mark = 'X';
    if (participant == 2) mark = 'O';
    $('#'+val).html(mark);
  });
}

Also, take out the redundant statement $(this).html('X');in .square.click().

function initialize() {
  $('.square').click(function() {
     submit($(this).attr('id'));
  });
}

Make the above changes to tick_tack_toe.js then call Save.

Launch your application and join as both subjects.

Now you can see the other player's mark when they click.


Final Game Logic

Let's put in the rest of the rules for Tick Tack Toe.

First we will give the player some better instructions. Volunteer Science keeps an array called moves[] with the number of moves each player has submitted in the current round.

Write a function called updateUI().

At the top, let's write the win condition. It is out of the scope of this tutorial to calculate all Tick Tack Toe win conditions. Let's just make it when all the squares are full -- the total moves is 9.

When the win condition is met, we update #instruction with a message.

WAITING_ROOM_URL is a URL that lets the subject choose another experiment. experimentComplete() tells Volunteer Science that you are done with the current test. -- This enables feedback, removes the warning on the quit button, requests an IRB signature etc.

function updateUI() {
  if (moves[1] + moves[2] == 9) { // move 0 for each
    $('#instruction').html('Game Over Return to waiting room');
    experimentComplete();
    return;  
  }

  ...
}

Now let's indicate who's turn it is. The variable myid tells you which subject you are. If I am Player 1 (myid == 1) then it is my turn when the number of moves are equal (moves[1] == moves[2]). We update #instruction accordingly.

function updateUI() {
  if (moves[1] + moves[2] == 9) { // move 0 for each
    $('#instruction').html('Game Over Return to waiting room');
    experimentComplete();
    return;  
  }
  if (myid == 1) {
    if (moves[1] == moves[2]) {
      $('#instruction').html('Your move.');
    } else {
      $('#instruction').html('Please wait for the other player.');
    }
  } else {
    if (moves[1] == moves[2]+1) {
      $('#instruction').html('Your move.');
    } else {
      $('#instruction').html('Please wait for the other player.');
    }
  }
}

Let's also prevent a player from moving out of turn, or overwriting an existing move in .square.click().

Also, call updateUI() whenever we submit a move, fetch a move and in initialize().

function initialize() {
  $('.square').click(function() {
    if ($(this).html() == '') { // prevent overwriting
      if (myid == 1) { // which player am I?
        if (moves[1] > moves[2]) return; // abort if I'm Player 1 have made more moves
      } else {
        if (moves[1] <= moves[2]) return; // abort if I'm Player 2 and have the same number of moves 
      }
      submit($(this).attr('id')); // submit my move
    }
  });
  updateUI();
}

function newMove(participant, index) {
  fetchMove(participant, currentRound, index, function(val) {
    var mark = 'X';
    if (participant == 2) mark = 'O';
    $('#'+val).html(mark);
    updateUI();
  });
}

Congratulations! You have created your first Volunteer Science app. You can read about additional features in the API Reference.