DNJ Dilemma's Secret Strategies!
Q: I can't find any strategy functions in
the DNJ Dilemma page sources. Where are they?
A: In the frameset
document that acts as the game pages' parent.

A major design
objective for DNJ Dilemma was to make it easy to develop,
test and install extra strategy functions. The best way to achieve this
was to keep the strategy functions in a separate document - that way there was
no danger of corrupting the source of the game itself, and new functions
could be tested in a separate library before being installed in the
production version. Ideally, it should be possible to add new functions to
strategy files, and switch between files, without making any changes to
the main game pages.
There are
three ways that an HTML document can execute script code held in a
separate file:
-
Put the script in a .js library file, and link it to
the main document via a <script src="libfile.js"></script>
element. The functions in the script are then called as if they were
embedded in the main page, e.g. myFunction().
-
Put the
script in a separate HTML document and have the main page open that
document in a separate browser window. Functions (and properties) are
then accessed via the inter-document object model, e.g. stratwin.myFunction().
-
Put the script in a frameset document, which creates a
frame and opens the main page in it. The main page can then call
functions via the window.parent reference, e.g. window.parent.myFunction().
The first technique is the simplest, but has the
disadvantage that it's impossible to switch to
a different library without physically editing the page source. This is
because you can't use the document.write() method to generate a <script
src= tag.
I used the second technique in the first
version of DNJ Dilemma. However the separate on-screen window which held the
strategy document looked untidy, and I had to program defensively to
handle the situation in which the user closed or overwrote it while the game was still
running. Even then it wasn't bulletproof.
That left the third technique of embedding
the strategy script in the head section of a frameset document. This isn't
a role you normally think of a frameset document playing, but
I'd already used it in another application (a quiz with
selectable question files), and it worked fine.
To launch DNJ Dilemma, you load a frameset document. This
contains the <script> element holding the strategy functions, plus a
<frameset> block defining a single column, 100%-width frame. The
game page is then loaded into the frame.
When the game page loads, an inline script block 'reaches
into' the parent frameset/strategy document, and builds an array of
pointers to the strategy functions it contains. The frameset/strategy
document already contains an array of pointers to its functions, so the
building process is easy, like this:
stratfunctionpointers = new Array()
for (i=0; i<window.parent.stratfunctionpointers.length; i++) {
stratfunctionpointers[i] = window.parent.stratfunctionpointers[i]
}
Later on, the game page's pointer array is used to access
the strategy functions during gameplay, and
when building the strategy selection list boxes
in the game control panel.
(Incidentally, I build the game page array in order to avoid
having to use 'window.parent.' notation elsewhere in the page. As well as
making the source more compact, it also means that if I move the
strategies somewhere else - say back into a child window - I only need to
change the array-building routine)
This technique makes it easy to run the game with a different set of
strategy functions - just create a new frameset/strategy document, and
allow it load the game page.
However one problem remained - I'd ended up with three
different game pages (Standard, MatchPlay and Tournament editions), so how would a frameset/strategy
document know which one to load? The answer was to make the frameset/strategy file accept a game document filename as a parameter
(via the location.search property), then use document.write() to generate
the <frameset> block, with the parameter as the frame's src=
value.
To do this, the frameset document first has to clean up the
location.search parameter, like this:
// Clean up parameter to reconvert '%20' escape strings back to spaces
var gamepagefile =
unescape(location.search.substr(1, location.search.length -1))
Now it can use the value of 'gamepage' to build the <frame> tag for
the specified game document:
<script>
document.write('<frameset cols="100%, *"><frame name="gameframe" src="'+gamepagefile+'"></frameset>')
</script>
This technique requires the hyperlink which calls the frameset/strategy
document to include the name of the game page as a parameter. Here's an
example of a hyperlink which tells the frameset/strategy document dnjdmstrats.htm
to load the standard edition game page dnjdmstd.htm:
<a href="dnjdmstrats.htm?dnjdmstd.htm">Standard Edition</a>
For full details of frameset/strategy documents, see
'writing your own strategies' in DNJ Dilemma Help.
|