Go: package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

var (
	sc = bufio.NewScanner(os.Stdin)
)

type Color int

const (
	ColorBlack Color = iota
	ColorRed
)

type Node struct {
	ID    int
	X, Y  int
	Color Color
	Nexts []*Node
}

func main() {
	for sc.Scan() {
		if sc.Text() == "0 0" {
			break
		}
		chunks := strings.Split(sc.Text(), " ")
		w, _ := strconv.Atoi(chunks[0])
		h, _ := strconv.Atoi(chunks[1])

		// Initialize map
		m := map[int]map[int]*Node{}
		for x := 1; x <= w; x++ {
			m[x] = map[int]*Node{}
			for y := 1; y <= h; y++ {
				m[x][y] = &Node{ID: x + y*w, X: x, Y: y}
			}
		}
		for x := 1; x <= w; x++ {
			for y := 1; y <= h; y++ {
				nexts := []*Node{}
				if n, ok := m[x-1][y]; ok {
					nexts = append(nexts, n)
				}
				if n, ok := m[x][y-1]; ok {
					nexts = append(nexts, n)
				}
				if n, ok := m[x+1][y]; ok {
					nexts = append(nexts, n)
				}
				if n, ok := m[x][y+1]; ok {
					nexts = append(nexts, n)
				}
				m[x][y].Nexts = nexts
			}
		}

		// Set colors
		queue := []*Node{}
		touchedIDs := map[int]struct{}{}
		for y := 1; y <= h; y++ {
			sc.Scan()
			for i, c := range sc.Text() {
				switch c {
				case '.', '@':
					n := m[i+1][y]
					n.Color = ColorBlack
					if c == '@' {
						queue = append(queue, n)
						touchedIDs[n.ID] = struct{}{}
					}
				case '#':
					m[i+1][y].Color = ColorRed
				}
			}
		}

		// Search
		visitedIDs := map[int]struct{}{}
		for {
			if len(queue) == 0 {
				break
			}
			n := queue[0]
			queue = queue[1:]
			visitedIDs[n.ID] = struct{}{}
			for _, next := range n.Nexts {
				if next.Color == ColorRed {
					continue
				}
				if _, ok := touchedIDs[next.ID]; !ok {
					queue = append(queue, next)
					touchedIDs[n.ID] = struct{}{}
				}
			}
		}
		fmt.Println(len(visitedIDs))
	}
}

C++: #include <iostream>
#include <queue>

#define REP(i, n) for (int i = 0; i < n; i++)
#define debug(x) cerr << #x << " = " << (x) << endl;

using namespace std;

int map[21][21], w, h;

bool check(int j, int k) {
	return (j >= 0 && j < h && k >= 0 && k < w && map[j][k] >= 1);
}

int main() {
	while (1) {
		int sj, sk, j, k, diff[] = {-1, 0, 1, 0, -1}, ans;
		string input;
		queue<pair<int, int> > bfs;

		cin >> w >> h;
		if (w==0 && h==0) break;

		REP(j, h) { REP(k, w) map[j][k] = -1; }
		ans = 0;

		REP(j, h) {
			cin >> input;
			REP(k, w) {
				map[j][k] = (input[k] == '#') ? 0 : 1;
				if (input[k] == '@') {
					sj = j;
					sk = k;
				}
			}
		}

		bfs.push(make_pair(sj, sk));
		map[sj][sk] = -1;
		ans++;

		while (!bfs.empty()) {
			j = bfs.front().first;
			k = bfs.front().second;
			bfs.pop();
			REP(i, 4) {
				if (check(j + diff[i], k + diff[i + 1])) {
					/*debug(j);
					debug(k);
					debug(j+diff[i]);
					debug(k+diff[i+1]);*/
					bfs.push(make_pair(j + diff[i], k + diff[i + 1]));
					map[j + diff[i]][k + diff[i + 1]] = -1;
					ans++;
				}
			}
		}

		cout << ans << endl;
	}
	return 0;
}

C++: #include <iostream>
#include <vector>
#include <string>
using namespace std;

typedef  vector< vector<int> > vector2d;

int main() {
  
    int H,W,count=0,kaisuu=0,kosuu,sum,judge;
    char map[20][20];
    vector2d nextx,nexty; //nextx[回数][個数]
    nextx.reserve(1000);
    nexty.reserve(1000);

  while(1){
    cin >>W>>H;
    if (W==0&&H==0)break;
    
    //マップの入力
    for(int cH=0;cH<H;cH++){
	for(int cW=0;cW<W;cW++){
	  cin >> map[cW][cH];
	  if (map[cW][cH]=='@'){
	    nextx[kaisuu].push_back(cW);
	    nexty[kaisuu].push_back(cH);
	  }
	}
    }
    sum = 1;
    while(1){
      judge = 0;
      for(kosuu=0;kosuu<nextx[kaisuu].size();kosuu++){
	if (nextx[kaisuu][kosuu]-1!=-1){
	  if(map[ nextx[kaisuu][kosuu]-1 ][ nexty[kaisuu][kosuu] ]=='.'){  //@の左側をチェック
	    //もし'@'だったらその座標を保存しそれを@に！
	    nextx[kaisuu+1].push_back(nextx[kaisuu][kosuu]-1);
	    nexty[kaisuu+1].push_back(nexty[kaisuu][kosuu]);
	    map[ nextx[kaisuu][kosuu]-1 ][ nexty[kaisuu][kosuu] ]='@';
	    sum++;
	    judge++;
	  }
	}
	if (nexty[kaisuu][kosuu]-1!=-1){
	  if(map[ nextx[kaisuu][kosuu] ][ nexty[kaisuu][kosuu]-1 ]=='.'){  //@の上側をチェック
	    //もし'@'だったらその座標を保存しそれを@に！
	    nextx[kaisuu+1].push_back(nextx[kaisuu][kosuu]);
	    nexty[kaisuu+1].push_back(nexty[kaisuu][kosuu]-1);
	    map[ nextx[kaisuu][kosuu] ][ nexty[kaisuu][kosuu]-1 ]='@';
	    sum++;
	    judge++;
	  }
	}
	if (nextx[kaisuu][kosuu]+1!=W){
	  if(map[ nextx[kaisuu][kosuu]+1 ][ nexty[kaisuu][kosuu] ]=='.'){  //@の右側をチェック
	    //もし'@'だったらその座標を保存しそれを@に！
	    nextx[kaisuu+1].push_back(nextx[kaisuu][kosuu]+1);
	    nexty[kaisuu+1].push_back(nexty[kaisuu][kosuu]);
	    map[ nextx[kaisuu][kosuu]+1 ][ nexty[kaisuu][kosuu] ]='@';
	    sum++;
	    judge++;
	  }
	}
	if (nexty[kaisuu][kosuu]+1!=H){
	  if(map[ nextx[kaisuu][kosuu] ][ nexty[kaisuu][kosuu]+1 ]=='.'){  //@の下側をチェック
	    //もし'@'だったらその座標を保存しそれを@に！
	    nextx[kaisuu+1].push_back(nextx[kaisuu][kosuu]);
	    nexty[kaisuu+1].push_back(nexty[kaisuu][kosuu]+1);
	    map[ nextx[kaisuu][kosuu] ][ nexty[kaisuu][kosuu]+1 ]='@';
	    sum++;
	    judge++;
	  }
	}
      }
      if (judge==0)break;
      kaisuu++;
    }
    kaisuu++;
    cout << sum <<endl;
  }
  
  return 0;
  
}

C++: #include <iostream>
#include <string>
#define MAX 30
#define rep(i,p) for(int i=0;i<p;i++)
using namespace std;
int W,H,count,yoko,tate;
int person_now_x,person_now_y;
char input;
bool masu[MAX][MAX];
bool visit[MAX][MAX];
// ?§???? {?????????????????????}
const int dx[] = {1,0,-1,0};
const int dy[] = {0,-1,0,1};
void dfs (int x, int y) {
  // start : (x y)
  visit[x][y] = true;
  count++;
  rep(i,4) {
    yoko = x+dx[i];
    tate = y+dy[i];
    if ( masu[yoko][tate] and !visit[yoko][tate] ) dfs(yoko,tate);
  }
}
int main(){
  while(1) {
    // W ?¨?
    // H ???
    cin >> W >> H;
    if (W==0 and H==0) break;
    // ?????????
    count = 0;
    rep(i,MAX) rep(j,MAX) masu[i][j] = false;
    rep(i,MAX) rep(j,MAX) visit[i][j] = false;
    // . true  black
    // # false red
    // @ true  person on black
    // ????????????????????????????????????????????´????????????????????¨????????±???
    for (int i=1; i<=H; i++)
      for (int j=1; j<=W; j++) {
        cin >> input;
        if (input == '.') masu[i][j] = true;
        else if (input == '#') masu[i][j] = false;
        else {
          person_now_x = i;
          person_now_y = j;
          masu[i][j] = true;
        }
      }
    dfs(person_now_x,person_now_y);
    cout << count << endl;
  }
  return 0;
}

C++: #include<cstdio>
#include <iostream>
#include<stack>

using namespace std;

struct Coord {
  int row;
  int col;
};

int solve (int W, int H);
  
int main () {
  int W, H;

  while(W!=0 && H!=0)
    {
      scanf("%d%d", &W, &H);
      if(W!=0 && H!=0)
	{
          printf("%d\n", solve(W,H));
	}
    }
  return 0;
}

int solve (int W, int H) {
  int n=0;
  char M[H+2][W+2];
  Coord start;
  for (int i=0; i<=W+1; i++) { M[0][i] = '#'; M[H+1][i] = '#'; }
  for (int i=1; i<=H; i++) { M[i][0] = '#'; M[i][W+1] = '#'; } 
  for (int i=1; i<=H; i++) {
    for (int j=1; j<=W; j++) {
      scanf(" %c", &M[i][j]);
      if (M[i][j]=='@') {
	start.row = i;
	start.col = j;
      }
    }
  }

  
  stack<Coord> S;
  S.push(start);
  while (!S.empty()) {
    Coord current = S.top(); S.pop();
    n++;
    int D1[]={1,0,-1,0}; int D2[]={0,-1,0,1};
    for (int d=0; d<4; d++) {
      Coord nc = current;
      nc.row += D1[d];
      nc.col += D2[d];
      if(M[nc.row][nc.col] != '*' && M[nc.row][nc.col] != '#' && M[nc.row][nc.col] != '@')
	{
	  S.push(nc);
	  M[nc.row][nc.col] = '*';
	}
    } 
    
  }
  return n;
}