문제2 지뢰찾기

알고리즘.데이터구조 2011. 2. 18. 11:40


윈도우의 지뢰찾기 게임을 기억할 것이다. M x N 크기 지뢰밭 각 셀은 인접한 셀에 몇개의 지뢰가 존재하는지

나타내는 수를 가지고 있다.  *를 지뢰하고 하면...

 

 * . . .

  . . . . 

 . * . .

  . . . .

 

와 같은 지뢰밭은 다음과 같은 값을 가지게 된다.

 

* 1 0 0

2 2 1 0

1 * 1  0

1 1 1 0

 

입력 : 행의 개수 n, 열의 개수 m /   n행 m열의 지뢰밭 

출력 : 인접한 8개의 이웃에 있는 지뢰의 개수가 계산된 지뢰밭  출력

 

ex) 

입력  

4 4

* . . . 

. . . . 

. . . .

. * . .

 

출력

* 1 0 0

2 2 1 0

1 * 1 0

1 1 1 0

 

문제해결

지뢰가 아닌 모든 셀에 대해서 이웃하는 지뢰의 개수를 카운팅한다. 카운팅은 상 하 좌 우 인덱스를 변화시켜 지뢰의 개수를 

카운팅하되 행과 열에 대한 바운더리를 초과하지 않도록 검사를 수행한다.


mine_sweeper.c


/*
	입력 : 행과 열의 개수 n m / 지뢰밭 
	출력 : 이웃하는 지뢰개수가 계산된 지뢰밭 
*/

#include <stdio.h>
#include <stdlib.h>

#define MINE '*'
#define EMPTY '.'
#define MAX_BUF 200

typedef struct _Mine {
	int n, m;
	char *mines;
} Mine;


Mine *input();
void construct_mine(Mine *_mine);
void destruct_mine(Mine *_mine);

int count_mines(Mine *mine, int r, int c);
void output();


int main (int argc, char const* argv[])
{
	Mine *mine;
	
	while (mine = input()) {
		construct_mine(mine);
		output(mine);
		destruct_mine(mine);
	} 
	
	return 0;
}

Mine *input() {
	int m, n, i, j;
	Mine *mine;
	char buf[MAX_BUF];
	char *p_buf = buf;
	
	scanf("%d %d", &m, &n);
	getchar(); // 개행 문제를 버림 
		
	if (m == 0 && n == 0) {
		return 0;
	}
	
	mine = (Mine*)malloc(sizeof(Mine));
	mine->m = m;
	mine->n = n;
	mine->mines = (char*)malloc(m * n + 1);
	
	for (i = 0; i < m; i++) {
		p_buf = buf;
		fgets(buf, MAX_BUF, stdin);
		j = 0;
		while (*p_buf != '\0') {
			if (*p_buf == '*' || *p_buf == '.') {
				mine->mines[n*i + j] = *p_buf;
				j++;
			}
			p_buf++;
		}
	}	
	return mine;
}

// 모든 셀에 지뢰 개수를 카운팅 
void construct_mine(Mine *_mine) {
	int i, j;
	Mine *mine = _mine;
	int m = mine->m, n = mine->n;
	
	for (i = 0; i < m; i++) {
		for (j = 0; j < n; j++) {
			if (mine->mines[i*n + j] != '*') {
				mine->mines[i*n + j] = count_mines(mine, i, j);
			}
		}
	}
}

void destruct_mine(Mine *_mine) {
	free(_mine->mines);
	free(_mine);
}


//  특정 셀의 인접한 이웃의 지뢰의 개수를 카운팅 
int count_mines(Mine *mine, int r, int c) {
	int index, count = 0;
	int m = mine->m, n = mine->n;
	char *cell = mine->mines;
	
	if (r - 1 >= 0 && c - 1 >= 0) {
		index = (r - 1)*n + c - 1;
		if (*(cell + index) == '*') {
			count++;
		}
	}
	if (r - 1 >= 0) {
		index = (r - 1)*n + c;
		if (*(cell + index) == '*') {
			count++;
		}
	}
	if (r - 1 >= 0 && c + 1 < n) {
		index = (r - 1)*n + c + 1;
		if (*(cell + index) == '*') {
			count++;
		}
	}
	if (c - 1 >= 0) {
		index = r*n + c - 1;
		if (*(cell + index) == '*') {
			count++;
		}
	}
	if (c + 1 < n) {
		index = r*n + c + 1;
		if (*(cell + index) == '*') {
			count++;
		}
	}
	if (r + 1 < m && c - 1 >= 0) {
		index = (r + 1)*n + c - 1;
		if (*(cell + index) == '*') {
			count++;
		}
	}
	if (r + 1 < m) {
		index = (r + 1)*n + c;
		if (*(cell + index) == '*') {
			count++;
		}
	}
	if (r + 1 < m && c + 1 < n) {
		index = (r + 1)*n + c + 1;
		if (*(cell + index) == '*') {
			count++;
		}
	}
	return count;
}


// 결과 출력 
void output(Mine *mine) {
	int i;
	printf("Field #:");
	for (i = 0; i < mine->m * mine->n; i++) {
		if (*(mine->mines + i) == '*') {
			printf("%c ", *(mine->mines + i));
		} else {
			printf("%d ", *(mine->mines + i));
		}
		if (i % mine->n == mine->n - 1) {
			printf("\n");
		}
	}
	printf("\n");
}


'알고리즘.데이터구조' 카테고리의 다른 글

HMAC-SHA1  (0) 2011.03.11
문제5 그래픽편집기  (0) 2011.02.18
문제4 LCD디스플레이  (0) 2011.02.18
문제3 여행  (0) 2011.02.18
문제2 지뢰찾기  (0) 2011.02.18
문제1 3n+1문제  (0) 2011.02.18