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 <string.h>
#include <queue>

using namespace std;

struct P
{
	int x, y;
};

int W, H;

int field[20][20];

int main()
{
	int x, y;
	char c;
	while( 1 )
	{
		cin >> W >> H;
		if(W==0 && H==0) break;

		memset(field, 0, sizeof(int) * 400);
		for(int j=0; j<H; j++)
		{
			for(int i=0; i<W; i++)
			{
				cin >> c;
				if(c == '.')
	  				field[i][j] = 1;
				else if(c == '#')
					field[i][j] = 2;
				else if(c == '@')
				{
					field[i][j] = 3;
					x = i;
					y = j;
				}
			}
		}

		int offset[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
		int total = 1;
		queue<P> que;
		P init_p = {x, y};
		que.push(init_p);

		while(!que.empty())
		{
			P p = que.front();
			que.pop();

			int cx = p.x;
			int cy = p.y;

			for(int i=0; i<4; i++)
			{
				int xx = cx + offset[i][0];
				int yy = cy + offset[i][1];
				if(xx>=0 && yy>=0 && xx<W && yy<H)
				{
					if(field[xx][yy] == 1)
					{
						P new_p = {xx, yy};
						que.push(new_p);
						field[xx][yy] = 4;
						total++;
					}
				}
			}
		}

		printf("%d\n", total);
	}
}

C++: #include <iostream>
using namespace std;
#define REP(i,n) for (int i = 0; i < n; i++)
#define FORI(i,a,b) for (int i = (a); i <= (b); i++)
const int MAX_W = 20;
const int MAX_H = 20;
int W,H,res;
int dx[4] = {1,0,-1,0},dy[4]= {0,1,0,-1};
char field[MAX_W][MAX_H];
void solve();

int main() {solve(); return 0;}

void dfs(int x, int y) {
  field[x][y] = '#';
  REP(i,4) {
    int X = x + dx[i], Y = y + dy[i];
    if (0 <= X && 0 <= Y && X < W && Y < H && field[X][Y] == '.') {
      dfs(X,Y);
    }
  }
  return ;
}
void solve() {
  while (true) {
    res = 1;
    cin >> W >> H;
    if (W==0&&H==0) break;
    int x0,y0;
    REP(i,H) {REP(j,W) {
      cin >> field[j][i];
      if (field[j][i] == '@') x0=j,y0=i;
    } }


    dfs(x0,y0);
    cout << res << endl;
  }
  return ;
}

C++: #include <iostream>
#include <queue>
using namespace std;
int w,h;
int g[21][21];
bool visited[21][21];
int moves[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int count;
bool legal(int x, int y)
{
  if(visited[x][y]!=true&&0<=x&&x<h&&0<=y&&y<w&&g[x][y]==0)
    return true;
  else
    return false;
}

void dfs(int x,int y)
{
  visited[x][y]=true;
  count++;
  for(int i=0;i<4;i++)
  {
    int newx=x+moves[i][0];
    int newy=y+moves[i][1];
    if(legal(newx,newy))
    {
      dfs(newx,newy);
    }
  }
}

int main()
{
  while(1)
  {
    cin>>w>>h;
    if(w==0&&h==0) break;
    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++)
      {
        g[i][j]=-1;
        visited[i][j]=false;
      }
    int psx,psy;
    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++)
      {
        char s;
        cin>>s;
        switch(s)
        {
          case '.':
            g[i][j]=0;break;
          case '#':
            g[i][j]=1;break;
          case '@':
            g[i][j]=2;psx=i;psy=j;break;
        }
      }
    count=0;
    dfs(psx,psy);
/*    int count=0;
    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++)
      {
        count+=visited[i][j];
      }
*/  cout<<count<<endl;

  }
}

C++: #include <iostream>
#include <vector>
#include <utility>
#include <algorithm>

int solve(int width, int height) {
    std::vector<bool> available((width + 2) * (height + 2));
    std::vector<std::pair<int, int>> fringe;
    auto access = [&](int x, int y){ return available[y * (width + 2) + x]; };

    int current_x = 0, current_y = 0;

    for (int y = 1; y <= height; y++) {
        for (int x = 1; x <= width; x++) {
            char c;
            std::cin >> c;
            access(x,y) = c == '.';
            switch (c){
                case '.':
                    access(x, y) = true;
                    break;
                case '@':
                    access(x, y) = true;
                    current_x = x;
                    current_y = y;
                    break;
            }
        }
    }

    fringe.push_back(std::make_pair(current_x, current_y));

    int num = 0;
    while (!fringe.empty()) {
        auto top = fringe.back();
        fringe.pop_back();
        auto x = top.first, y = top.second;
        if (access(x, y)) {
            num++;
            access(x, y) = false;
            fringe.push_back(std::make_pair(x + 1, y));
            fringe.push_back(std::make_pair(x - 1, y));
            fringe.push_back(std::make_pair(x, y + 1));
            fringe.push_back(std::make_pair(x, y - 1));
        }
    }

    return num;
}

int main() {
    int w, h;
    while (std::cin >> w >> h) {
        if (w == 0 && h == 0) {
            break;
        }
        std::cout << solve(w, h) << std::endl;
    }
}

C++: #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <time.h>
#include <math.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
#include <iterator>
#include <sstream>
#include <string>
#include <bitset>
using namespace std;
#define FOR(I,F,N) for(int I = F; I < (int)(N); I++)
#define rep(i, n) FOR(i, 0, n)
#define FIN(V) cout<<V<<endl
#define pb push_back
#define INF (1 << 28)

template<typename T>
void remove(vector<T>& vector, unsigned int index){
vector.erase(vector.begin() + index);
}

typedef pair<int, int> P;
typedef long long ll;
typedef priority_queue<int> pq;
int StrToInt(string);
string IntToStr(int);
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};

int w, h;
int state[21][21];
bool memo[21][21] = {0};
int ans;
void dfs(int x, int y){
	if(!memo[x][y]){
		memo[x][y] = true;
		ans++;
	}else return;
	int res = 0;
	rep(k,4){
		int nx = x + dx[k];
		int ny = y + dy[k];
		if(nx < 0 || ny < 0 || nx >= w || ny >= h)continue;
		if(state[nx][ny])continue;
		dfs(nx, ny);
	}
}
int main(void){
	while(cin >> w >> h, w|h){
		ans = 0;
		fill_n(*memo, 21*21, false);
		int sx, sy;
		rep(i,h){
			rep(j,w){
				char c;
				cin >> c;
				if(c == '@'){
					sx = j;
					sy = i;
					state[j][i] = 2;
				}else if(c == '.'){
					state[j][i] = 0;
				}else{
					state[j][i] = 1;
				}
			}
		}
		dfs(sx, sy);
		cout << ans << endl;
	}
	return 0;
}



int StrToInt(string s){
	stringstream ss;
	ss << s;
	int val;
	ss >> val;
	return val;
}
string IntToStr(int i){
	stringstream ss;
	ss << i;
	return ss.str();
}