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>
using namespace std;

int serch(int,int);
char tile[20][20];
int W,H;

int main(){
	int posx,posy;

	while(1){
		cin >> W >> H;
		if(W==0&&H==0) break;

		//^CÇÝÝ
		for(int j=0;j<H;j++){
			for(int i=0;i<W;i++){
				cin >> tile[i][j];
			}
		}

		for(int i=0;i<W;i++){
			for(int j=0;j<H;j++){
				if(tile[i][j]=='@'){
					posx=i,posy=j;
				}
			}
		}

		cout << serch(posx,posy)+1 << endl;
		for(int j=0;j<H;j++){
			for(int i=0;i<W;i++){
				tile[i][j]='#';
			}
		}

	}

	return 0;
}

int serch(int x,int y){
	//cout << "x=" << x << " " << "y=" << y << endl;
	int cnt=0;
	if(x==0&&y==0){
		if(tile[x+1][y]=='.'){
			tile[x+1][y]='@';
			cnt++;
			cnt = cnt + serch(x+1,y);
		}
		if(tile[x][y+1]=='.'){
			tile[x][y+1]='@';
			cnt++;
			cnt = cnt + serch(x,y+1);
		}
		//cout << "x==y==0" << endl;
	}else if(x==W&&y==0){
		if(tile[x-1][y]=='.'){
			tile[x-1][y]='@';
			cnt++;
			cnt = cnt + serch(x-1,y);
		}
		if(tile[x][y+1]=='.'){
			tile[x][y+1]='@';
			cnt++;
			cnt = cnt + serch(x,y+1);
		}
		//cout << "x==W&&y==0" << endl;
	}else if(x==0&&y==H){
		if(tile[x+1][y]=='.'){
			tile[x+1][y]='@';
			cnt++;
			cnt = cnt + serch(x+1,y);
		}
		if(tile[x][y-1]=='.'){
			tile[x][y-1]='@';
			cnt++;
			cnt = cnt + serch(x,y-1);
		}
		//cout << "x==0&&y==H" << endl;
	}else if(x==W&&y==H){
		if(tile[x-1][y]=='.'){
			tile[x-1][y]='@';
			cnt++;
			cnt = cnt + serch(x-1,y);
		}
		if(tile[x][y-1]=='.'){
			tile[x][y-1]='@';
			cnt++;
			cnt = cnt + serch(x,y-1);
		}
		//cout << "x==W&&y==H" << endl;
	}else if(x==0){
		if(tile[x][y-1]=='.'){
			tile[x][y-1]='@';
			cnt++;
			cnt = cnt + serch(x,y-1);
		}
		if(tile[x+1][y]=='.'){
			tile[x+1][y]='@';
			cnt++;
			cnt = cnt + serch(x+1,y);
		}
		if(tile[x][y+1]=='.'){
			tile[x][y+1]='@';
			cnt++;
			cnt = cnt + serch(x,y+1);
		}
		//cout << "x==0" << endl;
	}else if(x==W){
		if(tile[x-1][y]=='.'){
			tile[x-1][y]='@';
			cnt++;
			cnt = cnt + serch(x-1,y);
		}
		if(tile[x][y-1]=='.'){
			tile[x][y-1]='@';
			cnt++;
			cnt = cnt + serch(x,y-1);
		}
		if(tile[x][y+1]=='.'){
			tile[x][y+1]='@';
			cnt++;
			cnt = cnt + serch(x,y+1);
		}
		//cout << "x==W" << endl;
	}else if(y==0){
		if(tile[x-1][y]=='.'){
			tile[x-1][y]='@';
			cnt++;
			cnt = cnt + serch(x-1,y);
		}
		if(tile[x+1][y]=='.'){
			tile[x+1][y]='@';
			cnt++;
			cnt = cnt + serch(x+1,y);
		}
		if(tile[x][y+1]=='.'){
			tile[x][y+1]='@';
			cnt++;
			cnt = cnt + serch(x,y+1);
		}
		//cout << "y==0" << endl;
	}else if(y==H){
		if(tile[x-1][y]=='.'){
			tile[x-1][y]='@';
			cnt++;
			cnt = cnt + serch(x-1,y);
		}
		if(tile[x+1][y]=='.'){
			tile[x+1][y]='@';
			cnt++;
			cnt = cnt + serch(x+1,y);
		}
		if(tile[x][y-1]=='.'){
			tile[x][y-1]='@';
			cnt++;
			cnt = cnt + serch(x,y-1);
		}
		//cout << "y==H" << endl;
	}else {
		if(tile[x-1][y]=='.'){
			tile[x-1][y]='@';
			cnt++;
			cnt = cnt + serch(x-1,y);
			//cout << "a---------------a" << endl;
		}
		if(tile[x+1][y]=='.'){
			tile[x+1][y]='@';
			cnt++;
			cnt = cnt + serch(x+1,y);
			//cout << "b---------------b" << endl;
		}
		if(tile[x][y-1]=='.'){
			tile[x][y-1]='@';
			cnt++;
			cnt = cnt + serch(x,y-1);
			//cout << "c---------------c" << endl;
		}
		if(tile[x][y+1]=='.'){
			tile[x][y+1]='@';
			cnt++;
			cnt = cnt + serch(x,y+1);
			//cout << "d---------------d" << endl;
		}
	}
	//cout << endl;
	//for(int j=0;j<H;j++){
	//	for(int i=0;i<W;i++){
	//		cout << tile[i][j];
	//	}
	//	cout << endl;
	//}
	//
	return cnt;
}

C++: #include <iostream>
using namespace std;
int ch[23][23],cnt;
void dfs(int,int);
int main(){
  int w,h,i,j,k,l;
  string in[21];
  while(1){
    cnt=0;
    cin >> w >> h;
    if(w==0&&h==0) break;
    for(i=0;i<h;i++){
      cin >> in[i];
    }
    for(i=0;i<h+2;i++){
      for(j=0;j<w+2;j++){
	ch[i][j]=1;
      }
    }
    for(i=0,k=1;k<h+1;i++,k++){
      for(j=0,l=1;l<w+1;l++,j++){
	if(in[i][j]=='.') ch[k][l]=0;
	else if(in[i][j]=='#') ch[k][l]=1;
	else ch[k][l]=2;
      }
    }
    for(i=1;i<=h;i++){
      for(j=1;j<=w;j++){
	if(ch[i][j]==2) dfs(i,j);
      }
    }
    cout << cnt << endl;
  }
  return 0;
}
void dfs(int i,int j){
  if(ch[i][j]==1) return ;
  ch[i][j]=1;
  cnt++;
  dfs(i+1,j);
  dfs(i-1,j);
  dfs(i,j-1);
  dfs(i,j+1);
}

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

void bfs(std::vector<std::vector<char> > &map, std::pair<int, int> start) {
    int w = map.size();
    int h = map[0].size();
    int dy[4] = {0, 0, 1, -1};
    int dx[4] = {1, -1, 0, 0};
    std::queue<std::pair<int, int> > que; // coord
    int cost = 0;
    std::pair<int, int> coord = start;
    cost++;
    que.push(std::make_pair(coord.first, coord.second));
    map[coord.first][coord.second] = '#';

    while(! que.empty()) {
        coord = que.front(); 
        que.pop();
        for (int i = 0; i < 4; i++) {
            if (map[coord.first + dy[i]][coord.second + dx[i]] == '.') {
                cost++;
                que.push(std::make_pair(coord.first + dy[i], coord.second + dx[i]));
                map[coord.first + dy[i]][coord.second + dx[i]] = '#';
            }
        }
    }
    std::cout << cost << std::endl;
    return;
}

int main(void) {
    int w;
    int h;
    std::pair<int, int> start;

    while (1) {
        std::cin >> w >> h;
        if (w == 0 && h == 0) {
            break;
        }
        std::vector<std::vector<char> > map(h + 2, std::vector<char>(w + 2, '#'));
        for (int i = 1; i <= h; i++) {
            for (int j = 1; j <= w; j++) {
                std::cin >> map[i][j];
                if (map[i][j] == '@') {
                    start.first = i;
                    start.second = j;
                }
            }
        }
        bfs(map, start);
    }
    return 0;
}