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++: // 金子先生へ
// ITC-LMSの「第9回提出物」の提出期間が6/23までで、期間後の提出が不可になっています。
// しかし月曜までに今回の課題全部は解き終わらないので、いつもの様に7月末までにしてくださると幸いです。
// 多分、今回の課題は全部解けそうです。

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1130&lang=jp
#include <iostream>
#include <algorithm>
#include <queue>
#include <utility> // pair<int,int> xxxx;  make_pair(first,second);
using namespace std;

int W,H;
int X,Y; // 自分の位置
char s[20+10];
char c;
bool tile[20+10][20+10]; // タイルの状態。trueは黒、falseは赤(または壁)。
bool visited[20+10][20+10];
int answer;

// 右、上、左、下
const int dx[4] = { 1, 0, -1, 0 }; 
const int dy[4] = { 0, 1, 0, -1 };

bool valid (int x, int y) {
  return 0 <= x && x < H && 0 <= y && y < W && tile[x][y] ;
}

void init() { // 初期化
  fill(&tile[0][0], &tile[0][0]+20*20, 0);
  fill(&visited[0][0], &visited[0][0]+20*20, 0);
  answer = 0;
}

void make_tile() { // タイル読み込み
  for (int i=0; i<H; i++) {
    scanf("%s", s);
    for (int j=0; j<W; j++) {
      c = s[j];
      if (c == '.') {
	tile[i][j] = true;
      } else if (c == '#') {
	tile[i][j] = false;
      } else if (c == '@') {
	tile[i][j] = true;
	X = i;
	Y = j;
      }
    }
  }
}

void count_tile() {
  queue<pair<int,int>> Q; // 幅優先探索を使う。特に理由はないが、周辺から徐々に探査する感じになるのでイメージしやすい。
  pair<int,int> cur = make_pair(X,Y);
  Q.push(cur);
  while (!Q.empty()) {
    cur = Q.front();
    Q.pop();
    if (visited[cur.first][cur.second]) {
      continue;
    }
    visited[cur.first][cur.second] = true;
    answer++;
    for (int i=0; i<4; i++) {
      int a = cur.first+dx[i];
      int b = cur.second+dy[i];
      if (valid(a, b) && !visited[a][b]) {
	Q.push(make_pair(a, b));
      }
    }
  }
  printf("%d\n", answer);
}

int main() {
  while (scanf("%d%d", &W, &H) && W && H) {
    init();
    make_tile();
    count_tile();
  }
}

C++: #include<iostream>
#include<vector>
#include<utility>
#include<algorithm>
#include<string>
#include<cstdio>
#include<queue>
#include<functional>
#include<tuple>
#include<iomanip>
#include<stack>
#include<cmath>
#define ll long long
using namespace std;
int main() {
	int w, h;
	while (cin >> w >> h && w&&h) {
		int move[4][2] = { {1,0},{0,1},{-1,0},{0,-1} },cnt=0;
		char room[20][20];
		bool flag[20][20] = {};
		queue<pair<int, int>>que;
		pair<int, int>cur;
		for (int i = 0; i < h; ++i)
			for (int j = 0; j < w; ++j) {
				cin >> room[i][j];
				if (room[i][j] == '@') que.push(make_pair(j, i));
			}
		while (!que.empty()) {
			cur = que.front();
			que.pop();
			flag[cur.second][cur.first] = true;
			for (int i = 0; i < 4; ++i) {
				if (cur.first + move[i][0] >= 0 && cur.first + move[i][0] < w&&cur.second + move[i][1] >= 0 && cur.second + move[i][1] < h)
					if (!flag[cur.second + move[i][1]][cur.first + move[i][0]]&& room[cur.second + move[i][1]][cur.first + move[i][0]]=='.') {
						que.push(make_pair(cur.first + move[i][0], cur.second + move[i][1]));
						++cnt;
						flag[cur.second + move[i][1]][cur.first + move[i][0]] = true;
					}
			}
		}
		cout << cnt + 1 << endl;
	}
	return 0;
}

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

using namespace std;

#define rep(i, n) for (int i = 0; i < (int)n; i++)
#define vec vector

int dp[22][22];
int dx[4] = {1, -1, 0,  0};
int dy[4] = {0,  0, 1, -1};
int ans;
vec<string> a;

void solve(int p, int q)
{
    if (dp[p + 1][q + 1]) return;
    dp[p + 1][q + 1] = 1;
    if (a[p][q] != '#') {
        ans++;
    } else return;
    rep(i, 4) solve(p + dx[i], q + dy[i]);
}

int main(void)
{
    while(1) {
        int w, h;
        cin >> w >> h;
        if (w == 0) break;
        rep(i, h + 2) rep(j, w + 2) dp[i][j] = 0;
        rep(i, w + 2) {
            dp[0][i] = -1;
            dp[h + 1][i] = -1;
        }
        rep(i, h + 2) {
            dp[i][0] = -1;
            dp[i][w + 1] = -1;
        }
        a.clear();
        a.resize(h);
        pair<int, int> start;
        rep(i, h) {
            cin >> a[i];
            rep(j, w) if (a[i][j] == '@') start = make_pair(i, j);
        }
        //dp[start.first + 1][start.second + 1] = 1;
        ans = 0;
        solve(start.first, start.second);
        cout << ans << endl;
    }
    return 0;
}

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

using namespace std;

int main(){
    int w,h;
    while(cin >> w >> h && w!=0){
        int t[w+2][h+2];
        int matrix[w*h][w*h];
        int start;
        for(int i=0;i<h;i++){
            for(int j=0;j<w;j++){
                if(i==0 || j==0 || i==w || j==h)
                    t[i][j]=0;
                char tmp; cin >> tmp;
                if(tmp=='.'){
                    t[i+1][j+1] = 1;
                }
                else if(tmp=='#'){
                    t[i+1][j+1] = 0;
                }
                else{
                    t[i+1][j+1] = 1;
                    start = i*w+j;
                }
            }
        }
        for(int i=0;i<w*h;i++){
            for(int j=0;j<w*h;j++){
                matrix[i][j] = 0;
            }
        }
        for(int i=0;i<h;i++){
            for(int j=0;j<w;j++){
                if(i==0 || j==0 || i==w || j==h)
                    continue;
                else{
                    int id = i*w+h;
                    if(t[(id-w)/w][(id-w)%w] == 1)
                        matrix[id][id-w] = 1;
                    if(t[(id+w)/w][(id+w)/w] == 1)
                        matrix[id][id+w] = 1;
                    if(t[(id-1)/w][(id-1)/w] == 1)
                        matrix[id][id-1] = 1;
                    if(t[(id+1)/w][(id+1)/w] == 1)
                        matrix[id][id+1] = 1;
                }
            }
        }
        int count = 1;
        queue<int> Q;
        int came[w*h];
        for(int i=0;i<w*h;i++){
            came[i] = 0;
        }
        Q.push(start);
        came[start] = 1;
        while(Q.size()!=0){
            int cur = Q.front();
            for(int i=0;i<w*h;i++){
                if(matrix[cur][i]==1 && came[i] == 0){
                    Q.push(i);
                    came[i] = 1;
                    count++;
                }
            }
            Q.pop();
        }
        cout << count << endl;
    }
}