문제
지뢰찾기는 n × n 격자 위에서 이루어진다. m개의 지뢰가 각각 서로 다른 격자 위에 숨겨져 있다. 플레이어는 격자판의 어느 지점을 건드리기를 계속한다. 지뢰가 있는 지점을 건드리면 플레이어가 진다. 지뢰가 없는 지점을 건드리면, 그곳의 상하좌우 혹은 대각선으로 인접한 8개의 칸에 지뢰가 몇 개 있는지 알려주는 0과 8 사이의 숫자가 나타난다. 완전히 플레이되지 않은 게임에서 일련의 동작이 아래에 나타나 있다.
여기서, n은 8이고, m은 10이며, 빈 칸은 숫자 0을 의미하고, 올라가 있는 칸은 아직 플레이되지 않은 위치이며, 별표 모양(*)과 닮은 그림은 지뢰를 의미한다. 맨 왼쪽의 그림은 일부만이 플레이된 게임을 나타낸다. 첫 번째 그림에서 두 번째 그림으로 오면서, 플레이어는 두 번의 이동을 시행해서, 두 번 다 안전한 곳을 골랐다. 세 번째 그림을 볼 때 플레이어는 운이 썩 좋지는 않았다. 지뢰가 있는 곳을 골라서 게임에서 졌다. 플레이어는 m개의 열리지 않은 칸을 남길 때까지 계속해서 안전한 곳을 고르면 이긴다. 그 m개의 칸은 반드시 지뢰이다.
당신이 할 일은 일부가 플레이된 게임의 정보를 읽어 해당하는 격자를 출력하는 것이다.
입력
첫 번째 줄에는 10보다 작거나 같은 양의 정수 n이 입력된다. 다음 n개의 줄은 지뢰의 위치를 나타낸다. 각각의 줄은 n개의 문자를 사용하여 한 행을 나타낸다. 온점(.)은 지뢰가 없는 지점이며 별표(*)는 지뢰가 있는 지점이다. 다음 n개의 줄에는 길이가 n인 문자열이 입력된다. 이미 열린 칸은 영소문자 x로, 열리지 않은 칸은 온점(.)으로 표시된다. 예제 입력은 문제 설명에서의 가운데 그림과 상응한다.
출력
출력은 각각의 위치가 정확하게 채워진 판을 표현해야 한다. 지뢰가 없으면서 열린 칸에는 0과 8 사이의 숫자가 있어야 한다. 지뢰가 있는 칸이 열렸다면 지뢰가 있는 모든 칸이 별표(*)로 표시되어야 한다. 다른 모든 지점은 온점(.)이어야 한다.
일단 조건이 상당히 까다로워서 집중을 잘 해야 한다.
우선 입력과 필요한 변수로
1. n
2. 지뢰 위치 문자열 배열 (가명:a)
3.열렸는지 여부 문자열(가명:b)
4.출력용 판 배열(output)
풀이 키워드로는
1 지뢰가 없으면서 열릴경우 : 어느 한 위치에서 a가 *이 아니고 b가 x일때 숫자를 입력한다.
숫자입력 : 현재위치의 a배열에서 상하좌우대각선의 *개수만큼 output의 동일한 위치에 입력한다.
2.지뢰가 있는칸이 열리면 지뢰있는 모든칸에 별표를 표시한다.
a배열의 *위치마다 output의 동일한 위치에 입력한다.
3. 나머지는 온점으로 표시. -> 이부분은 초기화할때 아예 온점으로 초기화 했다.
함수는 숫자입력함수, 지뢰 입력함수 2가지를 사용했다.
숫자입력은 총 8가지 경우를 다 계산해야 했는데 일일이 조건문을 쓰기 싫었다.
그래서 범위 배열인 [-1,0,1] 값으로 이중 for문을 돌려 값이 배열내에 존재하면 내부 값이 *인지
확인하고, 아니면 넘어가도록 해서 개수를 구했다.
지뢰입력함수는 쉬워서 보면 이해가능하다.
뼈대로는
for i in range(n):
for j in range(n):
1번경우
숫자 입력
2번경우
지뢰 입력
이런식으로 갔다.
실수한 부분은 일단 숫자를 str으로 저장을 안하니까 출력시 join을 사용해도 작동하지 않았다.
리스트 내의 모든값이 문자열이어야 작동한다.
#n입력 받기
n=int(input())
#출력할 배열
output=[ ['.'] * n for _ in range(n) ]
#지뢰 위치 문자열 배열 입력받기
bomb=[]
open=[]
for i in range(n):
bomb.append(list(input()) )
# 열린여부 배열 입력
for i in range(n):
open.append(list(input()) )
#숫자 입력하기.
def insertNum(a,b):
global n
cnt=0
arr=[-1,0,1]
for i in arr:
for j in arr:
if 0<=a+i<n and 0<=b+j<n:
if i==0 and j==0:
continue
if bomb[a+i][b+j]=='*':
cnt+=1
return cnt
def insertbomb():
for i in range(n):
for j in range(n):
if bomb[i][j]=='*':
output[i][j]='*'
for i in range(n):
for j in range(n):
#1. 지뢰가 없고, 열린경우
if bomb[i][j]!='*' and open[i][j]=='x':
output[i][j]=str(insertNum(i,j))
if bomb[i][j]=='*' and open[i][j]=='x':
insertbomb()
for i in range(n):
test="".join(output[i])
print(test)
'코딩테스트 파이썬 > 구현' 카테고리의 다른 글
20291 파일 정리 (0) | 2021.07.20 |
---|---|
1244 스위치 켜고 끄기 (0) | 2021.07.20 |
2578 빙고 (0) | 2021.07.19 |
1913 달팽이 백준 (구현문제) (0) | 2021.07.15 |
게임개발 (동빈북 구현 실전문제) (0) | 2021.07.14 |