Skip to content

Tutorial: Improving the Estimation Game

Natalya St. Clair edited this page May 2, 2017 · 6 revisions

This guide was originally shared by Tim Erickson of EEPS Media for the Data Science Education Technology 2017 Conference.

Assumptions!

We assume that you have set up your local web server, on your computer, and downloaded the starter files. If you have not, refer to the Getting Started document, here.

You should also know how to edit these files, possibly using TextEdit or NotePad or some other text editor. These instructions assume you are using Chrome on a Mac. Make appropriate adjustments if you are not.

First, play the game

In your browser, go to

http://localhost/dset

to see our start page. Under Session 1, for the “Vanilla” Mac setup, click the link to go to the game, which is at a much longer URL that you don’t want to type.

You will see something like the illustration. Bookmark the link, just in case.

Estimation Game Screenshot

To play the game, press New Game. A black circle will appear in the blue rectangle. Now imagine that the blue rectangle represents the range [0, 1]. Where is the center of the black circle? It will be some decimal between zero and one. Make an estimate of the value, enter it in the text box, and press Submit estimate. Do this ten times to finish the game. You’ll get a score.

As you do this, you can see the data you’re generating. Press the Tables button in the toolbar to make a table, and Graph to make a graph. Drag column headings from the table to graph axes to make your graph. It will not take you long to discover things that would improve this game. And that’s what this session is about. You will change the program that governs the game, and learn about making plugins in CODAP and, by extension, what’s involved in making web-based data experiences for students.

You will mostly work on the file called estim8.js, in the estim8 folder. If you decide to change what appears in the game, you can edit estim8.html.

This document is short! Too short to do anything very elaborate! So pick something commensurate with your comfort and experience. Here are some ideas, roughly in order of complexity. After the ideas come instructions. The instructions might refer to places in the code by letter; you will find them in the code surrounded by vertical bars, like this: |Q|.

Before You Start: Developer Tools

If you’re an experienced programmer, you probably already have Developer Tools open. Good job.

If you’re new to this, believe me, you want these. In Chrome on the Mac, they’re in the View menu, at the bottom, under Developer. Choose Developer Tools.

This means that you can use the debugger, and also write to the console using the console.log( ) function. We display some useful information using that technique.

For example, with the game running, click in the blue bar. You will see a message such as

Click at 271 pixels, or 0.903

Make sure that’s working properly.

Recording the player name

The table has a column for the player name, but it isn’t filled in! There are several ways fix this. Here’s one:

Open the folder called estim8. In it you’ll see a .html file and a .js (JavaScript) file. Open them up in your editor. In the html file, the player name box comes from this line:

<p>Enter your name: <input id="yourName" type="text"></p>

The key part of this is the id, which is yourName. In the JavaScript (estim8.js) file, we want to get the string that’s inside it.

For now, we’ll do that in the function that gets called whenever you press the Submit estimate button, which is called endTurn( ). Find this part of the code:

// |A| set the value of the player name here. var tCaseValues = { truth: this.state.currentTruth, estimate: this.state.lastInputNumber, player: this.state.playerName // |C| ignore this part! It’s for the next task! }; pluginHelper.createItems(tCaseValues);

Here is the magic code you need:

this.state.playerName = document.getElementById('yourName').value

Insert this line in the file right after the comment labeled |A|. Save the file. Reload the web page. Enter your name in the box and play a turn. Does your name show up in the table? If so, yay! If not, see if you can fix it—or get help.

What just happened? You set a variable called playerName (if you care: which is part of state, which is part of this, which, in this context, is the global called estim8). And we’re setting it equal to the value of this thing associated with the document (the actual web document); the thing is the “element” with an id of 'yourName'. And that value is whatever you typed.

Then, in the game code, we create an object called tCaseValues, which already had a line in it for using this.state.playerName. In the next line, we ask a utility called pluginHelper to “createItems” using these case values. And that tells CODAP to make a new case—now with your name as part of it.

Recording the turn number

It would be lovely to have the turn number in the table. You will solve this problem completely by analogy with the previous task, looking at nearby code and copying it with changes.

First, to create the column in the table, find the comment with |B| in it. It’s near the bottom of the file. You can see lines that create columns for truth, estimate, and player. Duplicate one of those lines and alter it to fit your needs. Call the attribute turnNo. It will be numeric, and since it’s an integer, a precision of 0 is fine.

Danger: be careful about the commas at the ends of the lines. Commas separate these JavaScript “properties” from one another. But the last line (of these four) does not have a comma.

That makes the column, but doesn’t put the value in it. To do that, look for |C|. That’s where you add a new line (watching out for commas) that defines the value for turnNo. For the value, use the variable this.state.turnNumber, which we have already defined.

Save the file, reload, make sure it works. Then—for understanding—go back to the code and search for turnNumber. See where it gets initialized (in newGame) and where it gets updated (in newTurn).

Even if you don’t speak JavaScript, this should start to give you a feel for the underlying organization of the game in the code.

You might wonder: What’s the difference between turnNo and turnNumber? The way we have described this, turnNumber, or estim8.state.turnNumber, is the name of the JavaScript variable, in your plugin code. In contrast, turnNo is the name of the attribute in CODAP. They could have the same name.

What is this state thing? We could have just made a variable called estim8.turnNumber, or even just turnNumber (a global). Why include state?

Look for |S|. This is where we initialize this variable. You can see that it’s attached to a call to codapInterface. Basically, this lets us save, for free, any variable we like, in estim8.state. If we restore this page from a file (like from Google Drive) instead of just refreshing, all of these variables take on the last-saved values.

Recording the Error, Plugin Calculates

The user could make a new column in CODAP to calculate the “error,” that is, how far their estimate is from the “truth.” But let’s do it for them. Make a new column in the table, maybe called delta, and have the code save that value as well. Just as in the last task, you need to add lines at |B| and |C|. See if you can spot where we calculated the error. You can use that variable as the value.

Recording the Error, but CODAP Calculates

The user could have made a new column with a formula for the error. In the previous task we calculated the error and put it in the table. But instead, we could have had CODAP make a calculated column. That’s at |B|, but you need to know some additional syntax. Here is the line you want:

{name: "delta", type: 'numeric', precision: 3, formula: "estimate - truth", description: "error"},

That is, you use an additional “property,” called formula, which is a string.

If you want to use a function such as absolute value, you can do that, as in

formula: "abs(estimate - truth)"

The function has to be one CODAP understands. That set is extensive and expanding; the best way to know what’s possible is to try to make the formula in CODAP and see what’s currently available in the formula menu.

Use ^ for exponentiation.

Note that you don’t have to have the plugin save this value (So you don’t need some part of estim8.state.): it’s computed in CODAP. So you only need to make a change near |B|, not |C|.

Recording the Score

Did you realize you get a score? The variable is this.state.currentScore.

If you study the code or look at the console, you will see that your score is the sum of your (absolute) errors. That is, small is good. Still, this is not a very exciting score. See if you can devise a better one and, of course, have your plugin emit the current score into the table.

It’s probably best if the plugin calculates this entirely, so don’t make a computed column in the CODAP table. That means that in addition to calculating the value, you must make changes at |B| and |C| to make the score appear in the table.

More advanced: You might want the score to appear in the plugin as well; for that you need to change the HTML and make an appropriate JavaScript call. You might, for example, have a <div> with an id, and change that object’s innerHTML to be the value of the score. The JavaScript line might be:

document.getElementByID(“theScoreDiv”).innerHTML = "Score: " + this.state.currentScore

Recording the Game Number

Now you’re such an expert we don’t need to tell you much. We have already created the variable this.state.gameNumber. But we have not initialized it properly. You might have to try a few different things to get the correct game number to appear.

Reversing the Game

Okay, hotshot.

Notice that in this game, you type a value that represents your estimate for a value you see as the position of a dot. Suppose you reverse the sense of this, that is, have the plugin display a numerical value, and you show your estimate by clicking in the blue bar.

To facilitate this, we have created another state variable, estim8.state.lastClickPosition, which is set by the view in stripView.click().