Click to return Home

  Newsreel
  Products & Services
  Web Watch
  Software Update
  Events Diary
  Articles
  The Magazine
  Subscribe
  Contact Us

 
  Seconds since 
  this page loaded
 
    Counting down
    
 
These counters are updated via the setInterval() method, a variation on setTimeout() (see main text)  which automatically repeats the specified timer event. 
See the page source for details.


DOING TIME IN DNJ DILEMMA!

Q: How does the game allow its left and right-hand players to play their cards independently of each other?

A: A small helping of asynchronous (parallel) processing, achieved via JScript timer events.

In DNJ Dilemma I use JScript's setTimeout() timer events to create parallel (asychronous) processes for the left and right hand players' card-selection routines. This allows either player (human or computer strategy) to play first in each round, and lets me add 'thinking time' delays to make the computer strategies appear more 'human'. 

For details of timer events in JScript, see the scripting section in MSDN Web Workshop. Also, click here for a special note about parameter-passing in setTimeout().

Here's a flow diagram of the playing sequence for a round of DNJ Dilemma standard edition:

initRound() - splitting things into two 
initRound() does some start-of-round housekeeping, then spawns asynchronous left- and right-hand player processes. It then terminates, and the browser sits back and waits for the two player processes to complete.

Here's how initRound() spawns the process for the right-hand player:

var xdelay = genRandNum(1, 3) * 1000
timer1 = setTimeout("processCard('r', rplay(rplayer, 'play'))", xdelay)

First it generates a random delay period of between one and three seconds (in milliseconds). Then it calls JScript's setTimeout() method, telling it to execute the function processCard() after the specified delay period, using the value returned by the vectored right-hand strategy function rplay() as a parameter (see vectored functions for more details). 

In DNJ Dilemma standard edition the left-hand player can be human. If so, initRound() enables the on-screen Cooperate/Defect buttons, which call processCard() in response to their onclick events. If the left-hand player is a computer strategy, initRound() generates a timer-delayed call to the vectored left-hand strategy function.

processCard() - terminating each player's process.
The browser now has two asynchronous processes running, one of which may consist of waiting for a human player to press a card-select button. Both processes will terminate with a call to processCard(), which has two jobs:

  • Respond to the selection of a card by storing 'c' or 'd' in an xTEMP variable (see below) and displaying a back-of-card image;

  • Check if both cards have now been played, and if so, call the end-of-round function processRound().

Here's how processCard() decides whether or not to call processRound():

if (LTEMP != " " & RTEMP != " ") { 
    processRound() 
}


LTEMP and RTEMP are global variables, initialised to " " by initRound() and updated with the players' current-round options at the start of processCard(). When neither have a value of " ", then both cards must have been played - it's as simple as that!

processRound() - bringing it back together again
processRound() has a lot to do, including:

  • Turning the cards over to show each player's option;

  • Calculating the scores for that round based on the two players' options (i.e. using data returned by the two asynchronous play processes);

  • Updating the 'electronic scoreboard' displays;

  • Updating the game history displays and analysis arrays;

  • Deciding whether to initiate another round, or end the game.

Here's how it decides whether to play another round or end the game: 

if (game.roundnum < sysroundlimit ) {
  timer1 = setTimeout("initRound()", delayafterround)
} else {
  timer1 = setTimeout("endGame()", delayafterround)
}


game.roundnum is incremented by initRound(). processRound() compares it to sysroundlimit (a random value between six and 16, generated at the start of each game), and acts accordingly.

As you can see, initRound() and endGame() are called via timer events, rather than directly. This is to improve the game's interface, by leaving the end-of-round displays on screen for a second or so before clearing them for the next round or end of game. Instead of a literal value, I've used a variable (delayafterround) for the delay, so that the game's 'high-speed play' option can set its value to zero, and thus speed up the play. 

In the DNJ Dilemma source files (dnjdmstd.htm and dnjdmtourn.htm), you'll see timer events used in place of direct calls in many of the play stages.

Special note - parameter passing in SetTimeout(),
JScript's setTimeout method takes two parameters - the function call to be executed, and the delay (in milliseconds) before executing it. The first parameter is a string expression, not a direct function reference, so you might say:

handleVar = setTimeout("initRound()", 500)

There's no problem passing the names of objects and global variables as parameters to the function call, for example:

handleVar = setTimeout("showMessage(game.message)", 500)

However, when calling setTimeout() from within a function, you can't specify one of the function's local variables as a parameter, for example:

function myfunc() {
var localvar = "Hello World"
handleVar = setTimeout("showMessage(localvar)", 500)

This will fail, because the actual timer event (the call to showMessage()) is executed outside the context of the function that called setTimeout(), so the original function's local variables aren't accessible.

One way of getting round this is to generate setTimeout()'s function-call parameter's dynamically, like this:

handleVar = setTimeout("showMessage('"+localvar+"')", 500)

If the value of localvar was "Hello World", then the above code would evaluate to:

handleVar = setTimeout("showMessage('Hello World')", 500)

-  and don't forget to switch between " and ' quote-marks when generating embedded literal values!


 

 

 

 

 

DNJ Dilemma
The Inside Story

Inside DNJ Dilemma

Overview of the game's processes

Indirectly-called strategy functions

Graphical scoreboards

Animated buttons

Dynamically-loaded list boxes

Asynchronous left/right players

Where are the strategy functions?

Play DNJ Dilemma