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