<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xsl:stylesheet [
  <!ENTITY f  "http://xmlns.4suite.org/ext">
  <!ENTITY fres "http://xmlns.4suite.org/reserved">
]>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:cext="http://xmlns.4suite.org/demos/cards"
  xmlns:exslt="http://exslt.org/common"
  xmlns:exslt-str="http://exslt.org/strings"
  xmlns:f="&f;"
  xmlns:fcore="http://xmlns.4suite.org/4ss/score"
  xmlns:fhttp="http://xmlns.4suite.org/4ss/http"
  xmlns:fres="&fres;"
  xmlns:xupdate="http://www.xmldb.org/xupdate"
  extension-element-prefixes="cext exslt exslt-str f fcore fhttp fres"
  exclude-result-prefixes="xupdate"
>

  <!--

    4Suite repository demo application: Cribbage

    Computer's play processing

    Copyright 2004 Fourthought, Inc. (USA)
    http://4suite.org/

  -->

  <xsl:import href='count-util.xslt'/>
  <xsl:import href='../common/cards.xslt'/>

  <!--
    NOTE:
    We need to get state passed into us because we have no way of getting the latest
    possible values.  This means played stack and cur-count.
  -->

  <xsl:template name='move-computer'>
    <xsl:param name='played'/>
    <xsl:param name='cur-count'/>
    <xsl:param name='discarded'/>
    <xsl:param name='human-in-go'/>

    <xsl:if test='$debug="debug"'>
      <xsl:comment>
      Moving the computer START
      Discards:
      <xsl:for-each select='exslt:node-set($discarded)/discarded/Card'>
        Discard: <xsl:value-of select='@short-name'/>,
      </xsl:for-each>
      Played:
      <xsl:for-each select='exslt:node-set($played)/played/Card'>
        Played: <xsl:value-of select='@short-name'/>,
      </xsl:for-each>
      </xsl:comment>
    </xsl:if>

    <!-- Determine what human can play only if the skill level is hard -->
    <xsl:variable name='human-available-plays'>
      <xsl:if test='key("players",1)/@level="hard"'>
        <xsl:for-each select='key("players",2)/playing-cards/Card'>
          <!-- some of these cards may have already been played!!!!-->
          <xsl:if test='not(exslt:node-set($played)/played/Card[@short-name = current()/@short-name])'>
            <xsl:if test='not(exslt:node-set($discarded)/discarded/Card[@short-name = current()/@short-name])'>
              <xsl:copy-of select='.'/>
            </xsl:if>
          </xsl:if>
        </xsl:for-each>
      </xsl:if>
    </xsl:variable>

    <!--Perform the next computer move -->
    <xsl:variable name='moves'>
      <xsl:for-each select='key("players",1)/playing-cards/Card'>
        <!-- some of these cards may have already been played!!!!-->
        <xsl:if test='not(exslt:node-set($played)/played/Card[@short-name = current()/@short-name])'>
          <xsl:if test='not(exslt:node-set($discarded)/discarded/Card[@short-name = current()/@short-name])'>
            <xsl:variable name='cur-hand-count'>
              <xsl:call-template name='count-stack'>
                <xsl:with-param name='played' select='exslt:node-set($played)/played/Card'/>
                <xsl:with-param name='next-card' select='.'/>
                <xsl:with-param name='cur-count' select='$cur-count'/>
              </xsl:call-template>
            </xsl:variable>
            <xsl:choose>
              <xsl:when test='key("players",1)/@level="hard"'>
                <!--
                  Do more processing here, see which of the cards give the human player the
                  least likely hood of getting points on the stack.

                  If, we play a card that puts the player into GO, then add 2 to the total (unless he already is in GO

                  If, we play a card that allows the human to get 15, 31, pair or run, then subtract these points
                   from the total
                -->
                <xsl:variable name='human-to-go'>
                  <xsl:choose>
                    <!--
                      See if the human is already in GO
                    -->
                    <xsl:when test='$human-in-go'>0</xsl:when>
                    <!--
                      See if there are any cards, that when played make it so the human must go
                    -->
                    <xsl:when test='count(exslt:node-set($human-available-plays)/Card[(@point + number(exslt:node-set($cur-hand-count)/StackCountResults/NextCard/Card/@point) + $cur-count) &gt; 31]) = count(exslt:node-set($human-available-plays)/Card)'>2</xsl:when>
                    <!--
                      If this card is played, then every card that the human has will put him into GO
                    -->
                    <xsl:otherwise>0</xsl:otherwise>
                  </xsl:choose>
                </xsl:variable>

                <!--
                  Next see if this card will allow the human to get points from the stack
                -->
                <xsl:variable name='temp-played'>
                  <xsl:copy-of select='exslt:node-set($played)/played/Card'/>
                  <xsl:copy-of select='.'/>
                </xsl:variable>

                <xsl:variable name='human-max-points'>
                  <xsl:choose>
                    <xsl:when test='count(exslt:node-set($human-available-plays)/Card[@point + $cur-count + number(exslt:node-set($cur-hand-count)/StackCountResults/NextCard/Card/@point) &lt; 32])'>

                      <xsl:variable name='human-count-res'>
                        <xsl:for-each select='exslt:node-set($human-available-plays)/Card[@point + $cur-count + number(exslt:node-set($cur-hand-count)/StackCountResults/NextCard/Card/@point) &lt; 32]'>
                          <xsl:call-template name='count-stack'>
                            <xsl:with-param name='played' select='exslt:node-set($temp-played)/Card'/>
                            <xsl:with-param name='next-card' select='.'/>
                            <xsl:with-param name='cur-count' select='$cur-count + number(exslt:node-set($cur-hand-count)/StackCountResults/NextCard/Card/@point)'/>
                          </xsl:call-template>
                        </xsl:for-each>
                      </xsl:variable>

                      <!-- Just look at the top one -->
                      <xsl:variable name='sorted-human-count-res'>
                        <xsl:for-each select='exslt:node-set($human-count-res)/StackCountResults'>
                          <xsl:sort select='@total' order='ascending'/>
                          <xsl:copy-of select='.'/>
                        </xsl:for-each>
                      </xsl:variable>

                      <xsl:if test='$debug="debug"'>
                        <xsl:message>
                          Human Count Results:
                          <xsl:apply-templates select='exslt:node-set($sorted-human-count-res)/StackCountResults' mode='serialize'/>
                        </xsl:message>
                      </xsl:if>

                      <xsl:value-of select='number(exslt:node-set($sorted-human-count-res)/StackCountResults[last()]/@total)'/>
                    </xsl:when>
                    <xsl:otherwise>0</xsl:otherwise>
                  </xsl:choose>
                </xsl:variable>

                <xsl:variable name='new-total' select='number(exslt:node-set($cur-hand-count)/StackCountResults/@total) + number($human-to-go) - number($human-max-points)'/>

                <StackCountResults original-total='{number(exslt:node-set($cur-hand-count)/StackCountResults/@total)}' total='{number($new-total)}'>
                  <xsl:copy-of select='exslt:node-set($cur-hand-count)/StackCountResults/@*[local-name() != "total"]'/>
                  <xsl:copy-of select='exslt:node-set($cur-hand-count)/StackCountResults/node()'/>
                </StackCountResults>
              </xsl:when>
              <xsl:otherwise>
                <xsl:copy-of select='exslt:node-set($cur-hand-count)'/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:if>
        </xsl:if>
      </xsl:for-each>
    </xsl:variable>

    <xsl:if test='$debug="debug"'>
      <xsl:comment>
        Computer counting results:
        <xsl:for-each select='exslt:node-set($moves)/StackCountResults'>
          <xsl:value-of select='NextCard/Card/@short-name'/>
          <xsl:text> gives </xsl:text>
          <xsl:choose>
            <xsl:when test='@original-total'>
              <xsl:value-of select='@total'/><xsl:text> points (</xsl:text>
              <xsl:value-of select='@original-total'/>
              <xsl:text> originally) and a count of </xsl:text>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select='@total'/><xsl:text> points and a count of </xsl:text>
            </xsl:otherwise>
          </xsl:choose>
          <xsl:value-of select='number(NextCard/Card/@point) + $cur-count'/>,
        </xsl:for-each>
      </xsl:comment>
    </xsl:if>

    <!-- Sort them by the total/biggest and remove any that don't make it under 31-->
    <xsl:variable name='order'>
      <xsl:choose>
        <xsl:when test='/cribbage/game-info/@type="normal"'>
          <xsl:text>descending</xsl:text>
        </xsl:when>
        <xsl:otherwise>
          <xsl:text>ascending</xsl:text>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:variable name='sorted-moves'>
      <xsl:for-each select='exslt:node-set($moves)/StackCountResults[NextCard/Card/@point + $cur-count &lt; 32]'>
        <xsl:sort select='@total' data-type='number' order='{$order}'/>
        <xsl:copy-of select='.'/>
      </xsl:for-each>
    </xsl:variable>

    <xsl:comment>
      Computer has <xsl:value-of select='count(exslt:node-set($sorted-moves)/StackCountResults)'/><xsl:text> moves.</xsl:text>
    </xsl:comment>

    <xsl:choose>
      <xsl:when test='count(exslt:node-set($sorted-moves)/StackCountResults)'>
        <xsl:variable name='index'>
          <xsl:choose>
            <xsl:when test='key("players",1)/@level="easy"'>
              <!-- easy a random number between 1 and count/2 -->
              <xsl:value-of select='f:random((count(exslt:node-set($sorted-moves)/StackCountResults) div 2)-1,1)+1'/>
            </xsl:when>
            <xsl:otherwise>
              <!-- (normal|hard) = 1 -->
              <xsl:value-of select='1'/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>
        <xsl:call-template name='play-card'>
          <xsl:with-param name='player' select='1'/>
          <xsl:with-param name='card' select='exslt:node-set($sorted-moves)/StackCountResults[position() = number($index)]/NextCard/Card'/>
          <xsl:with-param name='played' select='exslt:node-set($played)/played/Card'/>
          <xsl:with-param name='cur-count' select='$cur-count'/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:call-template name='make-go'>
          <xsl:with-param name='player' select='1'/>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>

    <xsl:comment>
      Moving the computer END
    </xsl:comment>

  </xsl:template>


</xsl:stylesheet>
