본문 바로가기
Algorithm(CodeTree, Python)/Simulation

[코드트리] 핀볼게임 Python

by kurooru 2023. 1. 23.
# n 입력
n = int(input())
# grid 입력
grid = [
    list(map(int, input().split()))
    for _ in range(n)
]

# 함수들
# in_range(x, y)
def in_range(x, y):
    return 0<= x < n and 0 <= y < n

# simulate(sx, sy, sd)
def simulate(sx, sy, sd):

    # curr_x, curr_y, curr_d, t
    curr_x, curr_y, curr_d, t = sx, sy, sd, 1

    # 시뮬레이션 시작
    while True:

        # 현재 위치가 / 모양이면
        if grid[curr_x][curr_y] == 1:
            # curr_d가 북 또는 남이면
            if curr_d == 0 or curr_d == 2:
                # curr_d를 시계방향으로 90도 회전
                curr_d = (curr_d + 1) % 4
                # nx, ny
                nx, ny = curr_x + dxs[curr_d], curr_y + dys[curr_d]
                # nx, ny가 격자 밖이라면
                if not in_range(nx, ny):
                    # t 올려주고
                    t += 1
                    # 반환
                    return t
                # 격자 안이라면
                else:
                    # t 올려주고
                    t += 1
                    # curr_x, curr_y 바꿔주기
                    curr_x, curr_y = nx, ny
            
            # curr_d가 동 또는 서이면
            else:
                # curr_d를 시계 반대방향으로 90도 회전
                curr_d = (curr_d - 1 + 4) % 4
                # nx, ny
                nx, ny = curr_x + dxs[curr_d], curr_y + dys[curr_d]
                # nx, ny가 격자 밖이라면
                if not in_range(nx, ny):
                    # t 올려주고
                    t += 1
                    # 반환
                    return t
                # 격자 안이라면
                else:
                    # t 올려주고
                    t += 1
                    # curr_x, curr_y 바꿔주기
                    curr_x, curr_y = nx, ny
        
        # 현재 위치가 \ 모양이면
        elif grid[curr_x][curr_y] == 2:
            # curr_d가 북 또는 남이면
            if curr_d == 0 or curr_d == 2:
                # curr_d를 시계반대방향으로 90도 회전
                curr_d = (curr_d - 1 + 4) % 4
                # nx, ny
                nx, ny = curr_x + dxs[curr_d], curr_y + dys[curr_d]
                # nx, ny가 격자 밖이라면
                if not in_range(nx, ny):
                    # t 올려주고
                    t += 1
                    # 반환
                    return t
                # 격자 안이라면
                else:
                    # t 올려주고
                    t += 1
                    # curr_x, curr_y 바꿔주기
                    curr_x, curr_y = nx, ny
            
            # curr_d가 동 또는 서라면
            else:
                # curr_d를 시계방향으로 90도 회전
                curr_d = (curr_d + 1) % 4
                # nx, ny
                nx, ny = curr_x + dxs[curr_d], curr_y + dys[curr_d]
                # nx, ny가 격자 밖이라면
                if not in_range(nx, ny):
                    # t 올려주고
                    t += 1
                    # 반환
                    return t
                # 격자 안이라면
                else:
                    # t 올려주고
                    t += 1
                    # curr_x, curr_y 바꿔주기
                    curr_x, curr_y = nx, ny
    
        # 현재 위치가 비어있다면
        else:
            # nx, ny
            nx, ny = curr_x + dxs[curr_d], curr_y + dys[curr_d]
            # nx, ny가 격자 밖이라면
            if not in_range(nx, ny):
                # t 올려주고
                t += 1
                # 반환
                return t
            # 격자 안이라면
            else:
                # t 올려주고
                t += 1
                # curr_x, curr_y 바꿔주기
                curr_x, curr_y = nx, ny

# 설계
# max_dist
max_dist = 0

# dxs, dys
dxs, dys = [-1, 0, 1, 0], [0, 1, 0, -1]

# 완전탐색
for i in range(n):
    # max_dist update * simulate(x, y, dir)
    max_dist = max(max_dist, simulate(0, i, 2), simulate(i, 0, 1), simulate(n-1, i, 0), simulate(i, n-1, 3))

# 출력
print(max_dist)