<html>
<head><title>Minesweeper</title>
<style type="text/css">
.st{font-family:Arial,Helvetica,sans-serif;font-size:12px}
</style>
</head>
<body link=#000000 vlink=#000000 alink=#000000>
<form name=f>
<p align=center>
<table border=1 cellspacing=0 bordercolor=#000000 bordercolorlight=#000000 bordercolordark=#C0C0C0><tr><td align=center class=st bgcolor=#000000>
<font size=3 color=#FFFFFF><b>Black &amp; White Minesweeper</b></font>
</td></tr><tr><td align=center>
<select name=s size=1 onChange="javascript:F9()"><option selected value=0810>Beginner (8x8, 10 mines)</option><option value=1640>Intermediate (16x16, 40 mines)</option><option value=2499>Advanced (24x24, 99 mines)</option></select><br>
<table>
<tr>
<script language="JavaScript">
var a,b,c,d,g,o,s,t,u,i,j;
b=new Array();
u=new Array();
t='Are you sure you wish to ';
//t is ugly
g=(navigator.userAgent.indexOf('MSIE')>0);

//FD returns an image link
function FD(z){
  return('<IMG WIDTH='+z+' HEIGHT='+z+' BORDER=0 SRC="javascript:F0(');
}

//F0 uncompresses, caches and draws the requested image
function F0(z){
  if(!u[z]){
    a='';
    c='NB0TMMMMM0fTf0CAf1bf1DJDJD412a4fc7VYA1047e04X4AV9faT25595OO56b5OO5J5acea5J5a8Of8VN07L0cL14LWL7c0WGGGGU0N7NZBZVIfKKKK183eZ1fXfS7FPYPFFPQC8423eI79Zf9ZV83Vf7VeVfIVZVZNI7842CQ1EEEEZfQ7HS0eQ7HHS1S1e3Ze7ZBZ7FHQ3Q';
    d='807f1P1aRRS3UUX3814d3c02ZTfeaaX1Z0YYcZ99ZWff248ZZZ00';
    for(i=0;i<26;i++){
      c=c.replace(new RegExp(String.fromCharCode(i+65),'g'),d.substr(i*2,2));
    }
    for(i=0;i<32;i++){
      a+=(a==''?'':',')+'0x'+c.substr(z*64+i*2,2);
    }
    u[z]="#define x_width 16\n#define x_height 16\nstatic char x_bits[] = {"+a+"};\n";
  }
  return(u[z]);
}

//F1 updates the statusbar
function F1(z){
  window.status=!z?'':z;
  return(true);
}

//F2 draws a hyperlinked XBM graphic or textlink of a toolbar button
function F2(x,y,z){
  c='javascript:';
  if (x==9||g){
    document.write('<TD CLASS=st ALIGN=CENTER><A HREF="'+c+y+'()" onMouseOut="return(F1())" onMouseOver="return(F1(\''+z+' game\'))">'+(x==9?z+' game':FD(32)+x+')" ALT="'+z+' game">')+'</A></TD>');
  }
}

F2(2,'F9','New');
F2(1,'FB','Load');
F2(0,'FA','Save');
document.write('</TR><TR>');
F2(9,'F9','New');
F2(9,'FB','Load');
F2(9,'FA','Save');
</script>
</tr>
</table>
</td></tr><tr><td align=center class=st>
<input type=checkbox name=q> Question mark (or rightclick)<br><br>
<div align=center id=m></div><br>
</td></tr><tr><td class=st align=center><i>Created by <a href="mailto:ward@ward.nu">Ward van Wanrooij</a></i></td></tr></table>
</p>
</form>
<script language="JavaScript">

//b[x][y]=
//-1 covered, bomb
//0 covered, no bomb
//1 uncovered
//2 question, bomb
//3 question, no bomb

//F3 calculates the number to be displayed at b[x][y]
function F3(x,y){
  return(F4(x-1,y)+F4(x+1,y)+F4(x,y-1)+F4(x,y+1)+F4(x-1,y-1)+F4(x+1,y-1)+F4(x-1,y+1)+F4(x+1,y+1));
}

//F4 determines whether b[x][y] is a bomb
function F4(x,y){
  if(F7(x,y)){
    return(0);
  }else{
    return((b[x][y]==-1||b[x][y]==2)?1:0);
  }
}

//F7 determines whether b[x][y] is a valid grid reference
function F7(x,y){
  return(x<0||y<0||x>=s||y>=s);
}

//F5 draws the playing field
function F5(){
  c='BORDERCOLOR';
  a='<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=0 '+c+'=#000000 '+c+'LIGHT=#000000 '+c+'DARK=#C0C0C0>';
  c='<FONT FACE=Arial SIZE=1';
  for(i=0;i<s;i++){
    a+='<TR HEIGHT=20>';
    for(j=0;j<s;j++){
      a+='<TD WIDTH=20 HEIGHT=20 ALIGN=CENTER VALIGN=CENTER BGCOLOR='+(b[i][j]==1?'#C0C0C0>'+c+'>'+(F3(i,j)==0?'&nbsp;':F3(i,j))+'</FONT>':'#808080>'+(o<1?'<A onMouseOver="return(F1(\'Uncover '+(i+1)+','+(j+1)+'\'))" onMouseOut="return(F1())" HREF="javascript:F6('+i+','+j+',0)" onContextMenu="javascript:F6('+i+','+j+',-1);return(false)">':'')+((o<1&&b[i][j]>1)||(o>0&&(b[i][j]==-1||b[i][j]==2))?(g?FD(16)+(o<1?3:4)+')">':c+' COLOR='+(o>0?'#FF0000><B>X</B>':'#000000>??')+'</FONT>'):(g?FD(16)+'5)">':c+' COLOR=#808080>__</FONT>'))+(o<1?'</A>':''))+'</TD>';
    }
    a+='</TR>';
  }
  a+='</TABLE>';
  a+='<BR>'+(o>0?(g?FD(16)+(o<2?4:6)+')">':'')+c+'> '+(o<2?'Game over!':'Congratulations!'):c+'>Game in progress...')+'</FONT>';
  if(document.all&&!document.getElementById){
    m.innerHTML=a;
  }else{
    document.getElementById('m').innerHTML=a;
  }
}

//F6 recursively handles user input, clicking at b[x][y]
//z is zero when called by user, 1 when called recursively, 2 when right clicked
function F6(x,y,z){
  if(o<1&&!F7(x,y)){
    if(z<1&&b[x][y]>1){
      b[x][y]-=3;
    }else if(z<0||document.f.q.checked){
      b[x][y]+=3;
    }else if(z<1&&b[x][y]==-1){
      o=1;
      F5();
      alert('Game over!');
    }else{
      if(b[x][y]==0){
        b[x][y]=1;
        if(F3(x,y)==0){
          F6(x-1,y,1);
          F6(x+1,y,1);
          F6(x,y-1,1);
          F6(x,y+1,1);
          F6(x-1,y-1,1);
          F6(x+1,y-1,1);
          F6(x-1,y+1,1);
          F6(x+1,y+1,1);
        }
      }
    }
    if(z<1){ 
      a=0;
      for(i=0;i<s;i++){
        for(j=0;j<s;j++){
          a+=((b[i][j]==-1||b[i][j]==1||b[i][j]==2)?1:0);
        }
      }
      if(a==s*s){
        o=2;
        F5();
        alert('Congratulations!');
      }
      F5();
    }
  }
}

//F8 generates a new, random playing field
function F8(){
  o=0;
  d=document.f;
  s=d.s.value.substr(0,2);
  for(i=0;i<s;i++){
    b[i]=new Array(s);
    for(j=0;j<s;j++){
      b[i][j]=0;
    }
  }
  for(i=0;i<document.f.s.value.substr(2,2);i++){
    while(true){
      x=Math.floor(Math.random()*s);
      y=Math.floor(Math.random()*s);
      if(b[x][y]==0){
        b[x][y]=-1;
        break;
      }
    }
  }
  d.q.checked=false;
  F5();
}

//F9 starts a new game
function F9(){
  if(o>0||confirm(t+'start a new game?')){F8();}else{FC();}
}

//FA saves a game
function FA(){
  if(o>0){
    alert('Unable to save a finished game.');
    return;
  }
  a='MXS='+s+'|';
  for(i=0;i<s;i++){
    a+=b[i].join(',')+'|';
  }
  document.cookie=a+'; expires='+new Date(2006,5,6).toGMTString()+';';
  alert('Game saved.');
}

//FB loads a game
function FB(){
  d=document.cookie;
  c=d.indexOf('MXS=');
  if(c<0){
    alert('No saved game available.');
    return;
  }
  if(o>0||confirm(t+'load a game, breaking off the current game?')){
    o=0;
    a=d.substring(c+4);
    c=a.indexOf('|');
    s=a.substr(0,c);
    for(i=0;i<s;i++){
      c=a.indexOf('|',c+1);
      b[i]=a.substring(a.lastIndexOf('|',c-1)+1,c).split(',');
      for(j=0;j<s;j++){
        b[i][j]=parseInt(b[i][j]);
      }
    }
    FC();
    document.f.q.checked=false;
    F5();
  }
}

//FC sets dropdownbox to the current game style
function FC(){
  c=document.f.s.options;
//next line is ugly, should be i<c.length-1
  for(i=0;i<3;i++){
    if(c[i].value.substr(0,2)==s){
      c[i].selected=true;
    }
  }
}

F8();
</script>
</body>
</html>