xsl-list
[Top] [All Lists]

Linear sequence of moves to rectangular board

2005-05-12 13:40:37
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 &gt; 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  &gt; 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 &lt; $moves]/remove/vertex)"/></p>

    <p>White captures: <xsl:value-of select="count(//move[(_at_)colour = 
'white'][(_at_)order &lt; $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>
--~--



<Prev in Thread] Current Thread [Next in Thread>