I'm transforming a linear sequence of moves into the state of a rectangular
board (initially in HTML, images to come, maybe in SVG later). The game I'm
modelling is the game of, played with black and white stones on a rectangular
grid. Stones can be added and rarely removed. An empty state is sometimes in a
transient state called "ko."
The attached xml2xhtml.xslt file transforms test1.go.xml into html, with the
board in a table and calculates the number of moves and captures for black and
white. By passing in different values of $moves, you can step through the moves
in the game.
I'm aiming for maximum portability and maximum inter-operability. The XML file
format is still flexible.
I have some questions about where to go from here:
(*) In real games $size is normally 19 (but potentially unbounded), and there
are approximately 1/2 (size*size) moves per game. My recursive solution has a
max depth of (2*size)+(1/2 (size*size)) ~= 200, is this likely to be a problem
for any implementations? I'm particular thinking of transformations in
browsers.
(*) Maybe it's because I'm used to the gracefully recursion of scheme/lisp, but
the recursion here feels rather clunky. Am I doing something wrong?
(*) I'd like to define calculate a value for $moves (commented out) and use it
if no value is passed in on the command line/url, but I can't work out how.
This doesn't work:
<xsl:if test="$moves = ''">
<xsl:variable name="moves" select="count(//move) -1"/>
</xsl:if>
as the variable has the wrong scope, and $move access is an error if undefined.
So how do I make it robust in the face of bad/missing input from the
commandline or url?
(*) Currently I'm using explicit "order" attribute. The attribute seems
redundant (and potentially error prone), is there a better way to do this?
(*) I would like to represent variations, moving from a linear sequence to a
sparse tree, as shown in test2.go.xml and test3.go.xml. The desired behavour
would be to display at each moves the possible moves following and provide a
way to generate the board state for that move, much as incrementing $move does
currently. I'm not sure whether restructuring the XML (which is not yet fixed)
format would help.
Looking at other code and the manuals I have access to the ancestor axis seems
like it should be the solution, but I can't quite seem to join up the dots. I
can can see that one approach could be to transform test3.go.xml into a format
like test1.go.xml, and then to html, but I'm not sure how portable two step
transformations are.
(*) There are some rather obscure Unicode characters for representing go stones
(on the same code-page as the chess pieces). I'm extremely doubtful about their
support in a range of browsers, is there a good way to find out how widely
they're used? I'm particularly interested in support for them amoung far-east
localised windows versions, since this is where most go players are.
cheers
stuart
---------
<?xml version='1.0'?>
<!-- xml2xhtml.xslt -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="size" select="//@dimensiony"/>
<!--<xsl:variable name="moves" select="count(//move) -1"/>-->
<!-- do the rows -->
<xsl:template name="tablerow">
<xsl:param name="rownumber"/>
<tr>
<xsl:call-template name="tablecolumn">
<xsl:with-param name="columnnumber" select="$size -1"/>
<xsl:with-param name="rownumber" select="$rownumber"/>
</xsl:call-template>
</tr>
<xsl:if test="$rownumber > 0">
<xsl:call-template name="tablerow">
<xsl:with-param name="rownumber">
<xsl:value-of select="$rownumber - 1"/>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>
<!-- do the columns -->
<xsl:template name="tablecolumn">
<xsl:param name="rownumber"/>
<xsl:param name="columnnumber"/>
<td>
<xsl:call-template name="tablecell">
<xsl:with-param name="rownumber">
<xsl:value-of select="$rownumber"/>
</xsl:with-param>
<xsl:with-param name="columnnumber">
<xsl:value-of select="$columnnumber"/>
</xsl:with-param>
</xsl:call-template>
</td>
<xsl:if test="$columnnumber > 0">
<xsl:call-template name="tablecolumn">
<xsl:with-param name="rownumber">
<xsl:value-of select="$rownumber"/>
</xsl:with-param>
<xsl:with-param name="columnnumber">
<xsl:value-of select="$columnnumber - 1"/>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>
<!-- do a single cell -->
<xsl:template name="tablecell">
<xsl:param name="rownumber"/>
<xsl:param name="columnnumber"/>
<xsl:call-template name="tablecellmove">
<xsl:with-param name="rownumber">
<xsl:value-of select="$rownumber"/>
</xsl:with-param>
<xsl:with-param name="columnnumber">
<xsl:value-of select="$columnnumber"/>
</xsl:with-param>
<xsl:with-param name="status">empty</xsl:with-param>
<xsl:with-param name="move">
<xsl:value-of select="0"/>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
<xsl:template name="tablecellmove">
<xsl:param name="rownumber"/>
<xsl:param name="columnnumber"/>
<xsl:param name="status"/>
<xsl:param name="move"/>
<!-- <xsl:value-of select="$status"/> -->
<xsl:choose>
<xsl:when test="$move = $moves">
<xsl:value-of select="$status"/>
</xsl:when>
<xsl:when
test="//move[(_at_)order=$move]/ko/vertex[(_at_)x=$rownumber][@y=$columnnumber]">
<xsl:call-template name="tablecellmove">
<xsl:with-param name="rownumber">
<xsl:value-of select="$rownumber"/>
</xsl:with-param>
<xsl:with-param name="columnnumber">
<xsl:value-of select="$columnnumber"/>
</xsl:with-param>
<xsl:with-param name="status">ko</xsl:with-param>
<xsl:with-param name="move">
<xsl:value-of select="$move + 1"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:when
test="//move[(_at_)order=$move]/remove/vertex[(_at_)x=$rownumber][@y=$columnnumber]">
<xsl:call-template name="tablecellmove">
<xsl:with-param name="rownumber">
<xsl:value-of select="$rownumber"/>
</xsl:with-param>
<xsl:with-param name="columnnumber">
<xsl:value-of select="$columnnumber"/>
</xsl:with-param>
<xsl:with-param name="status">empty</xsl:with-param>
<xsl:with-param name="move">
<xsl:value-of select="$move + 1"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:when
test="//move[(_at_)order=$move]/vertex[(_at_)x=$rownumber][@y=$columnnumber]">
<xsl:call-template name="tablecellmove">
<xsl:with-param name="rownumber">
<xsl:value-of select="$rownumber"/>
</xsl:with-param>
<xsl:with-param name="columnnumber">
<xsl:value-of select="$columnnumber"/>
</xsl:with-param>
<xsl:with-param name="status">
<xsl:value-of select="//move[(_at_)order=$move]/@colour"/>
</xsl:with-param>
<xsl:with-param name="move">
<xsl:value-of select="$move + 1"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:when test="$status = 'ko'">
<xsl:call-template name="tablecellmove">
<xsl:with-param name="rownumber">
<xsl:value-of select="$rownumber"/>
</xsl:with-param>
<xsl:with-param name="columnnumber">
<xsl:value-of select="$columnnumber"/>
</xsl:with-param>
<xsl:with-param name="status">empty</xsl:with-param>
<xsl:with-param name="move">
<xsl:value-of select="$move + 1"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:when test="//move[(_at_)order=$move]">
<xsl:call-template name="tablecellmove">
<xsl:with-param name="rownumber">
<xsl:value-of select="$rownumber"/>
</xsl:with-param>
<xsl:with-param name="columnnumber">
<xsl:value-of select="$columnnumber"/>
</xsl:with-param>
<xsl:with-param name="status">
<xsl:value-of select="$status"/>
</xsl:with-param>
<xsl:with-param name="move">
<xsl:value-of select="$move + 1"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$status"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="game">
<html>
<xsl:apply-templates/>
<body>
<p>Board size: <xsl:value-of select="$size"/></p>
<p>Moves: <xsl:value-of select="$moves"/></p>
<p>Black captures: <xsl:value-of select="count(//move[(_at_)colour =
'black'][(_at_)order < $moves]/remove/vertex)"/></p>
<p>White captures: <xsl:value-of select="count(//move[(_at_)colour =
'white'][(_at_)order < $moves]/remove/vertex)"/></p>
<table>
<xsl:call-template name="tablerow">
<xsl:with-param name="rownumber" select="$size - 1"/>
</xsl:call-template>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
---------
<!-- test1.go.xml -->
<?xml version="1.0"?>
<?xml-stylesheet type="text/xml" href="xml2xhtml.xslt"?>
<game>
<board type="rectangular" dimensiony="3" dimensionx="3" />
<move colour="black" order="0" >
<vertex x="0" y="1" />
</move>
<annotate>
<text></text>
</annotate>
<move colour="white" order="1">
<vertex x="0" y="0" />
</move>
<move colour="black" order="2">
<vertex x="1" y="0" />
<remove>
<vertex x="0" y="0" />
</remove>
<ko>
<vertex x="0" y="0" />
</ko>
</move>
<annotate>
<score type="estimated" estimator="gnugo" version="9.7"/>
</annotate>
<move colour="white" order="3">
<vertex x="1" y="1" />
</move>
<move colour="black" order="4">
<vertex x="0" y="0" />
</move>
</game>
---------
<!-- test2.go.xml -->
<?xml version="1.0"?>
<?xml-stylesheet type="text/xml" href="./xml2xhtml.xslt"?>
<game>
<board type="rectangular" dimensiony="4" dimensionx="4" />
<annotation>
<text> this is a comment at the start of the file</text>
</annotation>
<move colour="black" order="0" id="00001">
<vertex x="0" y="1" />
</move>
<move colour="white" order="1" id="00002">
<vertex x="0" y="0" />
</move>
<move colour="black" order="2" id="00003">
<vertex x="1" y="0" />
<remove>
<vertex x="0" y="0" />
</remove>
</move>
<variation>
<move colour="white" order="3" id="00004">
<vertex x="2" y="1" />
</move>
<move colour="black" order="4" id="00005">
<vertex x="1" y="1" />
</move>
</variation>
<variation>
<move colour="white" order="3" id="00006">
<vertex x="1" y="1" />
</move>
<move colour="black" order="4" id="00007">
<vertex x="0" y="0" />
</move>
</variation>
</game>
---------
<!-- test3.go.xml -->
<?xml version="1.0"?>
<?xml-stylesheet type="text/xml" href="./xml2xhtml.xslt"?>
<game>
<board type="rectangular" dimensiony="4" dimensionx="4" />
<annotation>
<text> this is a comment at the start of the file</text>
</annotation>
<move colour="black" order="0" id="00001">
<vertex x="0" y="1" />
</move>
<move colour="white" order="1" id="00002">
<vertex x="0" y="0" />
</move>
<move colour="black" order="2" id="00003">
<vertex x="1" y="0" />
<remove>
<vertex x="0" y="0" />
</remove>
</move>
<variation>
<move colour="white" order="3" id="00004">
<vertex x="2" y="1" />
</move>
<variation>
<move colour="black" order="4" id="00005">
<vertex x="1" y="1" />
</move>
</variation>
<variation>
<move colour="black" order="4" id="00006">
<vertex x="1" y="2" />
</move>
</variation>
</variation>
<variation>
<move colour="white" order="3" id="00007">
<vertex x="1" y="1" />
</move>
<move colour="black" order="4" id="00008">
<vertex x="0" y="0" />
</move>
</variation>
</game>
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--