Working Minesweeper

Javascript, 978 bytes (824 without CSS)

http://jsbin.com/otayez/6/

Checklist:

Randomized mine generation - yes
8x8 field with 10 mines - yes
Mine flags - Yes
"unknown" flags - no
Reveal nearby blank spaces when a blank space has been revealed. - yes
Input and output code: It must be playable. - yes

JS:

(function(){
    f=Math.floor;r=Math.random;b=8,s=[-1,0,1],o='',m='*',l=0;

    for(g=[i=b];i;)g[--i]=[0,0,0,0,0,0,0,0];
    for(i=10,a=f(r()*64);i--;g[f(a/b)][a%b]=m)while(g[f(a/b)][a%b])a=f(r()*64);
    for(i=64;i--;z.id='b'+(63-i),c.appendChild(z))z=document.createElement('button');
    for(d=b;d--;)
      for(r=b;r--;)
        s.map(function(y){
          s.map(function(x){
            if(g[d][r]!=m&&g[d+y]&&g[d+y][r+x]==m)g[d][r]++;
          });
        });

    c.onclick=function(e){
        var t=e.target,
            i=t.id.slice(1),
            x=i%b,
            y=f(i/b),
            n=t.className=='b';

      if(t.innerHTML||(n&&!e.ctrlKey))return;
      if(e.ctrlKey)return t.className=(n?'':'b')

      if(q(x,y))alert('boom')
      if(l==54)alert('win')
    };
  function q(x,y){
    if(x<0||x>7||y<0||y>7)return;

    var p=y*b+x,
        v=g[y][x],
        t=document.all['b'+p];

    if(v!=m&&!t.innerHTML){
      t.innerHTML=g[y][x];
      t.className='f';
      l++;
      if(!v){t.className='z';s.map(function(d){s.map(function(r){q(x+r,y+d)})})}
    }
    return v==m
  }
})();

MiniJS 812 bytes:

f=Math.floor;r=Math.random;b=8,s=[-1,0,1],o='',m='*',l=0,h='b';for(g=[i=b];i;)g[--i]=[0,0,0,0,0,0,0,0];for(i=10,a=f(r()*64);i--;g[f(a/b)][a%b]=m)while(g[f(a/b)][a%b])a=f(r()*64);for(i=64;i--;z.id=h+(63-i),c.appendChild(z))z=document.createElement('button');for(d=b;d--;)for(r=b;r--;)s.map(function(y){s.map(function(x){if(g[d][r]!=m&&g[d+y]&&g[d+y][r+x]==m)g[d][r]++})});c.onclick=function(e){var t=e.target,i=t.id.slice(1),n=t.className==h;if(t.innerHTML||(n&&!e.ctrlKey))return;if(e.ctrlKey)return t.className=(n?'':h);if(q(i%b,f(i/b)))alert('boom');if(l==54)alert('win')};function q(x,y){if(x<0||x>7||y<0||y>7)return;var p=y*b+x,v=g[y][x],t=document.all[h+p];if(v!=m&&!t.innerHTML){t.innerHTML=g[y][x];t.className='f';l++;if(!v){t.className='z';s.map(function(d){s.map(function(r){q(x+r,y+d)})})}}return v==m}

HTML 12 bytes

<div id="c">

The CSS isn't necessary from a functionality standpoint, but is from a usability standpoint:

#c{
  width:300px;
  height:300px;
}
button{
  width:12.5%;
  height:12.5%;
  line-height:30px;
}
.f,.z{
  background:#fff;
  border:solid 1px #fff;
}
.z{
  color:#fff;
}
.b{background:#f00}

Mini CSS 154 bytes:

#c{width:300px;height:300px}button{width:12.5%;height:12.5%;line-height:30px}.f,.z{background:#fff;border:solid 1px #fff}.z{color:#fff}.b{background:#f00}

C, 568, 557, 537

Checklist:
  Randomized mine generation - yes
  8x8 field with 10 mines - yes
  Mine and "unknown" flags - yes
  Reveal nearby blank spaces when a blank space has been revealed. - yes
  Input and output code: It must be playable. - yes

Further to playable: 
  Win detection (found all mines, or revealed all empties)
  Bang detection (hit a mine)
  Game terminates.

Output format:
  # - unrevealed
  ! - a flagged mine
  * - a mine
  (number) - number of neighbouring mines
  ? - unknown flag

Input format:
  x y f 
  - where x is 0..7, y is 0..7 (origin upper-left)
  - f is 0 to open up, 1 to flag a mine, and 2 to flag a unknown

example game:

./a.out
5 5 0
# 1 0 0 0 2 # #
# 1 0 0 0 2 # #
# 1 0 0 0 1 1 1
# 1 0 0 0 0 0 0
# # 1 0 0 0 1 1
# # 1 0 0 0 1 #
# # # 1 2 1 # #
# # # # # # # #
6 1 1
# 1 0 0 0 2 # #
# 1 0 0 0 2 ! #
# 1 0 0 0 1 1 1
# 1 0 0 0 0 0 0
# # 1 0 0 0 1 1
# # 1 0 0 0 1 #
# # # 1 2 1 # #
# # # # # # # #
7 5 0
# 1 0 0 0 2 # #
# 1 0 0 0 2 ! #
# 1 0 0 0 1 1 1
# 1 0 0 0 0 0 0
# # 1 0 0 0 1 1
# # 1 0 0 0 1 *
# # # 1 2 1 # 1
# # # # # # # #
bang!

code:

// 8x8 grid but with padding before first row, after last row, and after last column, i.e. its 9x10
m[99]; // 0=empty,1=mine
u[99]; // 0=revealed,1=unrevealed,2=flag,3=unknown

// count neighbouring mines (8way)
c(i){return m[i-8]+m[i-9]+m[i-10]+m[i+8]+m[i+9]+m[i+10]+m[i-1]+m[i+1];}

// reveal (4way)
r(i){
    if(u[i]){
        u[i]=0;
        if(!c(i))r(i-9),r(i+9),r(i+1),r(i-1);
    }
}

i,x,y,f,e;
main(){
    // place 10 mines
    for(srand(time(0));i<10;){
        x=rand()%64;
        x+=9+x/8;
        if(!m[x]){
            m[x]=1;
            i++;
        }
    }
    for(;y<64;y++)u[y+9+y/8]=1; // mark visible grid as being unrevealed

    while(!e){
        // read input 0..7 0..7 0..2
        scanf("%d%d%d",&x,&y,&f);
        i=x+9+y*9;
        if(f)u[i]=f==1?2:u[i]==3?1:3;else r(i); // flag, toggle unknown/unrevealed, open

        // show grid and calc score
        for(y=f=x=0;x<64;x++){
            i=x+9+x/8;
            putchar(u[i]?" #!?"[u[i]]:m[i]?42:48+c(i)); // 42='*', 48='0'
            putchar(x%8==7?10:32);
            if(!u[i])y+=m[i]?-99:1;   // y = number of correctly open
            if(u[i]==2)f+=m[i]?1:-99; // f = number of correct mines
        }
        if(y<0||y==54||f==10)e=puts(y<0?"bang!":"win!"); // 54 = 64-10
    }
}

Mathematica 566 548 1056

Edit: This is a complete rewrite. I gave up trying to obtain the shortest code and decided instead to build in the features that made most sense.

r indicates the number of rows in the grid. c indicates the number of columns in the grid. m: number of mines.

The game is played by mouse-clicking on the buttons. If the player clicks on a mine, the cell turns black and the program prints "You Lose!"

The checkbox "u" allows the player to peek at the complete solution at any time. The flags, "?" and "!" can be placed in any cell as desired.

DynamicModule[{s, x, f, l},
Manipulate[
Column[{
Grid[s],
If[u, Grid@f, Null]
}],
Grid[{{Control@{{r, 8}, 4, 16, 1, PopupMenu}, 
 Control@{{c, 8}, 4, 16, 1, PopupMenu},
 Control@{{m, 10}, 1, 50, 1, PopupMenu}},
{Button["New", i], 
 Control@{{e, 0}, {0 -> "play", 1 -> "?", 2 -> "!"}, SetterBar}, 
 Control@{{u, False}, {True, False}}}}],
 Deployed -> True,

 Initialization :>
 (p = ReplacePart;
  q = ConstantArray;
  z = Yellow;
  w = White;    
  b := Array[Button["  ", v[{#, #2}], Background -> z] &, {r, c}];
  a := RandomSample[l = Flatten[Array[List, {r, c}], 1], m];
  d[m1_] := 
   p[ListConvolve[BoxMatrix@1, p[q[0, {r, c}], (# -> 1) & /@ m1], 2,
    0], (# -> "*") & /@ (x)];
  n[y_] := Complement[Select[l, ChessboardDistance[y, #] == 1 &], x];
  d[m1_] := 
  p[ListConvolve[BoxMatrix@1, p[q[0, {r, c}], (# -> 1) & /@ m1], 2,
    0], (# -> "*") & /@ (x)];

  v[{r_, c_}] :=
   Switch[e,
    1, If[s[[r, c, 3, 2]] == z, 
     s = p[s, {{r, c, 1} -> If[s[[r, c, 1]] == "?", "  ", "?"]}], 
     Null],
  
    2, If[s[[r, c, 3, 2]] == z, 
    s = p[s, {{r, c, 1} -> If[s[[r, c, 1]] == "!", "  ", "!"]}], 
    Null],
    3, Null,
  
  
    0, Switch[f[[r, c]],
     "*", (Print["You lose!"]; (s = p[s, {r, c, 3, 2} -> Black])),
     0, (s = p[s, {{r, c, 1} -> "  ", {r, c, 3, 2} -> w}]; 
      f = p[f, {{r, c} -> ""}]; v /@ n[{r, c}]),
     "  ", Null,
     _, (s = p[s, {{r, c, 1} -> f[[r, c]], {r, c, 3, 2} -> w}])]];
  
   i :=
   (x = a;s = b;f = d[x]);i) ] ]

Initial State

pic1

At a later point...

pic2