[이코테] 3.1 구현 실전문제

책 115p ~ 의 예제

왕실의 나이트


cmd = input()
col = ord(cmd[0]) - 96
row = int(cmd[1])

# simulation 유형에서 행동좌표를 배열로 저장해서 풀어보자
steps = [
    (-2, -1), (-1, -2), (1, -2), (2, -1),
    (2, 1), (1, 2), (-1, 2), (-2, 1)
]

answer = 0
for step in steps:
    # 이동하고자 하는 위치 확인
    next_row = row + step[0]
    next_col = col + step[1]
    # 해당 위치로 이동이 가능하다면 카운트 증가
    if 1 <= next_row <= 8 and 1 <= next_col <= 8:
        answer += 1
print(answer)

이동하고자 하는 움직임을 리스트로 만들어서 풀어보는 시도.

게임 개발


시뮬레이션 유형은 문제를 이해하는게 어렵고 구현하는 것도 꽤 빠르게 정교하게 하는 스킬(피지컬)이 필요하다.

해당 문제와 같이 턴마다 이동하는 유형의 문제는 주로 시뮬레이션이나 DFS를 이용하여 구현할 수 있다.

턴마다 이동하는 시뮬레이션 문제는 dx, dy, step등과 같이 방향, 이동하는 크기 정도를 별도의 리스트로 만들어서 풀면 편리하다.

코드는 아래와 같다.

import sys

def turn_left(direction):
    direction -= 1
    if direction == -1:
        direction = 3
    return direction

N, M = map(int, sys.stdin.readline().split())
x, y, di = map(int, sys.stdin.readline().split())
visited = [[0] * M for _ in range(N)]
loc = list()
for i in range(N):
    loc.append(list(map(int, sys.stdin.readline().split())))

# 방향 설정을 해서 이동하는 문제는 별도의 리스트를 만들어서 푸는 습관
dx = [-1, 0, 1, 0]  # L D R U
dy = [0, 1, 0, -1]  # L D R U

visited[x][y] = 1  # 시작 위치 방문 표시
turn_count = 0
answer = 1
while True:
    # Step 1. 회전
    di = turn_left(di)
    next_x = x + dx[di]
    next_y = y + dy[di]
    # Step 2-1. 가보지 않은 육지라면 이동
    if visited[next_x][next_y] == 0 and loc[next_x][next_y] == 0:
        visited[next_x][next_y] = 1
        x = next_x
        y = next_y
        answer += 1
        turn_count = 0
        continue
    # Step 2-2. 가본 육지이거나 바다
    else:
        turn_count += 1
    # Step 3. 종료 조건: 모두 가본 육지
    if turn_count == 4:
        # 3-1 뒤로 가기
        next_x = x - dx[di]
        next_y = y - dy[di]
        if loc[next_x][next_y] == 0:
            x = next_x
            y = next_y
            turn_count = 0
        # 뒤로 못가는 경우
        else:
            break
print(answer)