You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-dev@xmlgraphics.apache.org by de...@apache.org on 2002/03/20 17:17:01 UTC

cvs commit: xml-batik/samples mines.svg

deweese     02/03/20 08:17:01

  Added:       samples  mines.svg
  Log:
  SVG implementation of mine sweeper.
  
  Revision  Changes    Path
  1.1                  xml-batik/samples/mines.svg
  
  Index: mines.svg
  ===================================================================
  <?xml version="1.0" standalone="no"?>
  <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
  "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
  
  <!-- ====================================================================== -->
  <!-- Copyright (C) The Apache Software Foundation. All rights reserved.     -->
  <!--                                                                        -->
  <!-- This software is published under the terms of the Apache Software      -->
  <!-- License version 1.1, a copy of which has been included with this       -->
  <!-- distribution in the LICENSE file.                                      -->
  <!-- ====================================================================== -->
  
  <!-- ====================================================================== -->
  <!-- Defines the Batik Logo using an SVG font.                              -->
  <!--                                                                        -->
  <!-- @author thomas.deweese@kodak.com                                       -->
  <!-- @version $Id: mines.svg,v 1.1 2002/03/20 16:17:01 deweese Exp $    -->
  <!-- ====================================================================== -->
  
  <svg id="body" width="450" height="500" viewBox="0 0 450 500"
       xmlns="http://www.w3.org/2000/svg" 
       xmlns:xlink="http://www.w3.org/1999/xlink">
  
      <script type="text/ecmascript">
        <![CDATA[
          //
          // Global declarations
          //
  	var mines0    =  8;
  	var mines1    = 40;
  	var mines2    = 99;
  
  	var boardSize =  1;
  	var numAcross = 16;
  	var numDown   = 16;
  	var numMines  = 40;
  
  	var correctFlags   = 0;
  	var incorrectFlags = 0;
  	var minesLeft;
          var board      = document.getElementById("board")
          var cover      = document.getElementById("cover")
  
  	var boardArray = new Array(numAcross*numDown);
  	var shownArray = new Array(numAcross*numDown);
  	var flagArray  = new Array(numAcross*numDown);
  	var isGameOver = true;
  	var xlinkNS    = "http://www.w3.org/1999/xlink";
  	var svgNS      = "http://www.w3.org/2000/svg";
  
  	function initBoard(evt) {
  	  isGameOver = false;
  	  minesLeft = numMines;
            correctFlags = 0;
  
  	  updateText("mines", "Mines Left: "+minesLeft);
  	  updateText("boardsz", "Board Size: "+numAcross+"x"+numDown);
  	  updateText("title", "");
  	  updateText("working", "Working");
  
  	  for(var y=0; y<numDown; y++) {
  	     for(var x=0; x<numAcross; x++) {
  	       boardArray[x+y*numAcross] = 0;
  	       shownArray[x+y*numAcross] = false;
  	       flagArray [x+y*numAcross] = false;
  	     }
            }
  	  while (cover.lastChild != null) {
               cover.removeChild(cover.lastChild);
  	  }
  	  while (board.lastChild != null) {
               board.removeChild(board.lastChild);
  	  }
  
  	  for (var i=0; i<numMines; i++) {
  	    var index = new Integer(Math.random()*(numDown*numAcross)).intValue();
  	    if ((index >= (numDown*numAcross)) ||
  	        (boardArray[index]!=0)) {
  	       i--;
  	    } else {
  	      boardArray[index] = -1;
              }
            }
  
  	  for(var y=0; y<numDown; y++) {
  
               var coverRow = document.createElementNS(svgNS, "g");
  	     var boardRow = document.createElementNS(svgNS, "g");
  
  	     var sum=0;
  	     for (y1=y-1; y1<=y+1; y1++) {
  	       if ((y1 >= 0) &&
  	           (y1 < numDown) &&
  	           (boardArray[y1*numAcross] == -1))
  		   sum++;
  	     }
  
  	     for(var x=0; x<numAcross; x++) {
  	     	if (x-2 >= 0) {
  	     	   for (y1=y-1; y1<=y+1; y1++) {
  	     	     if ((y1 >= 0) &&
  	     		 (y1 < numDown) &&
  	     		 (boardArray[x-2+y1*numAcross] == -1))
  	   		 sum--;
  	     	   }
  	     	}  
  	     	if (x+1 < numAcross) {
  	     	   for (y1=y-1; y1<=y+1; y1++) {
  	     	     if ((y1 >= 0) &&
  	     		 (y1 < numDown) &&
  	     		 (boardArray[x+1+y1*numAcross] == -1))
  	   		 sum++;
  	     	   }
  	     	}
  
  	       if (boardArray[x+y*numAcross] == 0)
  	          boardArray[x+y*numAcross] = sum;
  
  	       var square = document.createElementNS(svgNS, "use");
                 square.setAttributeNS(null, "x", ""+(x*10));
                 square.setAttributeNS(null, "y", ""+(y*10));
                 square.setAttributeNS(null, "onclick", 
  	                             "handleClick(evt, "+x+","+y+")");
  
                 var cov = square.cloneNode(true);
                 cov.setAttributeNS(null, "id", "cover"+x+"-"+y);
  	       cov.setAttributeNS(xlinkNS, "href", "#blank");
  	       var g = document.createElementNS(svgNS, "g");
  	       g.appendChild(cov);
  	       coverRow.appendChild(g);
  
                 square.setAttributeNS(null, "id", "square"+x+"-"+y);
  	       if (boardArray[x+y*numAcross] == -1)
  	   	  square.setAttributeNS(xlinkNS, "href", "#bomb");
  	       else
  	   	  square.setAttributeNS(xlinkNS, "href", "#square"+sum);
  	       var g = document.createElementNS(svgNS, "g");
  	       g.appendChild(square);
  	       boardRow.appendChild(g);
  	     }
               cover.appendChild(coverRow);
               board.appendChild(boardRow);
  	  }
  
  	  updateText("working", "");
  	  updateText("title", "SVG Mines");
  	}
  
  	function handleClick(evt, x, y) {
  	   if (isGameOver) return;
  	   if ((evt.button == 1) ||
  	       (evt.shiftKey)) {
  	       placeFlag(x, y);
  	   }
  	   else if ((evt.button == 2) ||
  	            (evt.ctrlKey)) {
  	       showConnected(x, y);
  	   }
  	   else if (evt.button == 0) {
  	       showSpot(x, y)
  	   }
          }
  
  	function placeFlag(x ,y) {
  	   var idx = x + y*numAcross;
  	   if (shownArray[idx]) return;
  	   var elt = document.getElementById("cover"+x+"-"+y);
  	   var nelt = elt.cloneNode(true);
  	   if (flagArray[idx]) {
  	      nelt.setAttributeNS(xlinkNS, "href", "#blank");
  	      flagArray[idx] = false;
  	      if (boardArray[idx] == -1) correctFlags--;
  	      else                       incorrectFlags--;
  	      minesLeft++;
  	   } else {
  	      nelt.setAttributeNS(xlinkNS, "href", "#flag");
  	      flagArray[idx] = true;
  	      if (boardArray[idx] == -1) correctFlags++;
  	      else                       incorrectFlags++;
  	      minesLeft--;
             }
  
  	   elt.parentNode.replaceChild(nelt, elt);
  	   updateText("mines", "Mines Left: "+minesLeft);
  
  	   if ((correctFlags == numMines) && (incorrectFlags == 0)) {
  	      youWin();
  	   }
  	}
  
          function showSpot(x, y) {
  	   var idx = x + y*numAcross;
  	   if (shownArray[idx]) return;
  
  	   var elt = document.getElementById("cover"+x+"-"+y);
  	   elt.parentNode.parentNode.removeChild(elt.parentNode);
             shownArray[idx] = true;
  
             var val = boardArray[idx];
  	   if (val == -1) {
  	      gameOver();
  	   } else if (val == 0) {
  	     showConnected(x, y);
  	   }
  	}	
  
  	function showConnected(x, y) {
  	   for (var dy=-1; dy<=1; dy++) {
  	      if (y+dy <  0)        continue;
  	      if (y+dy >= numDown ) continue;
  	      for (var dx=-1; dx<=1; dx++) {
  	      	 if (x+dx <  0)        continue;
  	      	 if (x+dx >= numDown ) continue;
  		 var idx = x+dx + (y+dy)*numAcross;
  		 if (shownArray[idx]) continue;
  		 if (flagArray[idx]) continue;
  
  	         var elt = document.getElementById("cover"+(x+dx)+"-"+(y+dy));
  	         elt.parentNode.parentNode.removeChild(elt.parentNode);
  		 shownArray[idx] = true;
  
             	 var val = boardArray[idx];
  	  	 if (val == -1) {
  	  	    gameOver();
  	  	 } else if (val == 0) {
  		    showConnected(x+dx, y+dy);
  		 }
  	      }
  	   }
  	}
  
  	function gameOver() {
  	  isGameOver=true;
  	  updateText("title", "Game Over");
  	  showBoard();
  	}
  
  	function showBoard() {
  	  while (cover.lastChild != null) {
               cover.removeChild(cover.lastChild);
  	  }
  	  var nc = numAcross*numDown;
  	  for (var i=0; i<nc; i++)
  	    shownArray[i] = true;
  	}
  
  	function youWin() {
  	  isGameOver=true;
  	  updateText("title", "You Win");
  	}
  
          function updateText(id, lbl) {
              var elt = document.getElementById(id)
              var grp = elt.parentNode;
              var newelt = elt.cloneNode(true)
  
              if (newelt.firstChild == null) {
                  newelt.appendChild(document.createTextNode(lbl))
              } else {
                  newelt.replaceChild(document.createTextNode(lbl), newelt.firstChild)
              }
              grp.replaceChild(newelt, elt)
          }
  
  	function largerBoard(evt) {
  	   if (boardSize == 1) return;
  	   boardSize++;
  	   if (boardSize == 1) {
  	      numAcross = 16;
  	      numDown   = 16;
  	      numMines = mines1;
  	   }
  	   else if (boardSize == 2) {
  	      numAcross = 30;
  	      numDown   = 16;
  	      numMines = mines2;
  	   }
  	   updateText("boardsz", "Board Size: "+numAcross+"x"+numDown);
  	   updateText("title", "");
  	   updateText("working", "Working");
  	   setTimeout("initBoard()", 50);
  	}
  
  	function smallerBoard(evt) {
  	   if (boardSize == 0) return;
  	   boardSize--;
  	   if (boardSize == 0) {
  	      numAcross = 8;
  	      numDown   = 8;
  	      numMines = mines0;
  	   }
  	   else if (boardSize == 1) {
  	      numAcross = 16;
  	      numDown   = 16;
  	      numMines = mines1;
  	   }
  	   updateText("boardsz", "Board Size: "+numAcross+"x"+numDown);
  	   updateText("title", "");
  	   updateText("working", "Working");
  	   setTimeout("initBoard()", 50);
  	}
  
          function newGame(evt) {
  	   updateText("title", "");
  	   updateText("working", "Working");
  	   setTimeout("initBoard()", 50);
          }
  
        ]]>
      </script>
  
     <title>Implementation of Minesweeper in SVG</title>
     	
     <defs>
           <radialGradient id="bombGrad" gradientUnits="userSpaceOnUse" 
  	                 cx="5" cy="6.5" fx="4" fy="5" r="2.5">
  	    <stop offset="0%" stop-color="#FFF"/>
  	    <stop offset="20%" stop-color="#888"/>
  	    <stop offset="100%" stop-color="#000"/>
  	 </radialGradient>
        <g id="empty">
           <path fill="#AAA" stroke="#DDD" stroke-width="0.5" 
  	       d="M0.25,0.25 h9.5 v9.5 h-9.5 v-9.5"/>
        </g>
        <g id="blank">
           <rect fill="#AAA" stroke="none" width="10" height="10"/>
   	 <path fill="#DDD" stroke="none"
   	       d="M0,0 h10 l-1,1 h-8 v8 l-1,1 v-10"/>
   	 <path fill="#888" stroke="none"
   	       d="M10,10 h-10 l1,-1 h8 v-8 l1,-1 v10"/>
        </g>
        <g id="square0">/
           <use xlink:href="#empty"/>
        </g>
        <g id="square1">/
           <use xlink:href="#empty"/>
  	 <text x="5" y="8" text-anchor="middle" font-size="8" fill="#008"
  	 >1</text>
        </g>
        <g id="square2">
           <use xlink:href="#empty"/>
  	 <text x="5" y="8" text-anchor="middle" font-size="8" fill="#00C"
  	 >2</text>
        </g>
        <g id="square3">
           <use xlink:href="#empty"/>
  	 <text x="5" y="8" text-anchor="middle" font-size="8" fill="#40F"
  	 >3</text>
        </g>
        <g id="square4">
           <use xlink:href="#empty"/>
  	 <text x="5" y="8" text-anchor="middle" font-size="8" fill="#80C"
  	 >4</text>
        </g>
        <g id="square5">
           <use xlink:href="#empty"/>
  	 <text x="5" y="8" text-anchor="middle" font-size="8" fill="#C0C"
  	 >5</text>
        </g>
        <g id="square6">
           <use xlink:href="#empty"/>
  	 <text x="5" y="8" text-anchor="middle" font-size="8" fill="#F08"
  	 >6</text>
        </g>
        <g id="square7">
           <use xlink:href="#empty"/>
  	 <text x="5" y="8" text-anchor="middle" font-size="8" fill="#F04"
  	 >7</text>
        </g>
        <g id="square8">
           <use xlink:href="#empty"/>
  	 <text x="5" y="8" text-anchor="middle" font-size="8" fill="#F00"
  	 >8</text>
        </g>
  
        <g id="bomb">
           <use xlink:href="#empty"/>
  	 <rect fill="#000" x="4" y="3" width="2" height="2"/>
  	 <circle fill="url(#bombGrad)" cx="5" cy="6.5" r="2.5"/>
  	 <path fill="none" stroke="#000" stroke-width="0.3"
  	       d="M5,3 c0,-1.5 1.5,-1.5 1.5,0 c0,1.5 1.5,1.5  1.5,0"/>
        </g>
  
        <g id="flag">
           <use xlink:href="#blank"/>
  	 <path d="M3.5,2 h.5 v6.5 h-1 l.5,-6.5"/>
  	 <path fill="crimson" d="M4,2 l4,1.5 l-4,1.5 z"/>
        </g>
        
     </defs>   
  
     <g id="body">
        <text id="title" x="25" y="60" font-size="40">SVG Mines</text>
        <text id="mines" x="250" y="30" font-size="20">Mines Left: </text>
  
        <text id="boardsz" x="250" y="54" font-size="20">Board Size: </text>
        <g transform="translate(242, 38)" fill="black">
        	 <path onclick="largerBoard(evt)" 
        	       d="M2.5,0 l-2.5,7 h5 z"/>
        	 <path onclick="smallerBoard(evt)" 
        	       d="M0,9 h5 l-2.5,7 z"/>
        </g>
  
        <g text-anchor="middle" >
           <g id="help" >
              <desc xml:space="preserve"
  >Left:    show
  Right    or Shift: place flag
  Middle    or Control: show surround</desc>
              <circle cx="430" cy="18" r="12"
                      fill="grey" stroke="lightgrey" stroke-width="2" />
              <text font-size="15" fill="blue" x="430" y="25" >?</text>
           </g>
     
           <g onclick="newGame()">
              <desc xml:space="preserve">Start new game</desc>
              <circle cx="430" cy="48" r="12"
                      fill="grey" stroke="lightgrey" stroke-width="2" />
              <text font-size="10" fill="blue" x="430" y="53" >NG</text>
           </g>
        </g>
  
        <g id="field" transform="translate(25,75) scale(2)"
     	  onload="initBoard(evt)">
     	 <g id="board">
     	 </g>
        
     	 <g id="cover">
     	 </g>
        </g>
        <text id="working" fill="green" x="25" y="60" font-size="40"
        >Working</text>
     </g>
  
      <!-- ============================================================= -->
      <!-- Batik sample mark                                             -->
      <!-- ============================================================= -->
      <use xlink:href="batikLogo.svg#Batik_Tag_Box" />
  </svg>
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: batik-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-dev-help@xml.apache.org