[Python] [SWEA] 추억의 2048게임(6109)

긍정왕·2021년 6월 7일
1

Algorithm

목록 보기
17/69
post-thumbnail

💡 문제 해결

  1. 각 움직임에 대한 회전 수를 지정
  2. 숫자를 이동하기 전 움직임의 기준을 둔 방향으로 회전(이 경우에서는 위쪽으로 합침)
  3. 기준방향으로 회전 뒤 먼저 0을 제외하고 상단으로 정렬
  4. 위 방향부터 숫자 합치기 시작
  5. 계산이 끝난 뒤 다시 0을 제외한 값을 상단으로 정렬


🧾 문제 설명

※ SW Expert 아카데미의 문제를 무단 복제하는 것을 금지합니다.

2048이라는 추억의 게임을 아는가? 2048은 한 때 유명했던 1인용 게임으로, 
격자 위에서 숫자가 적힌 타일들을 밀어서 합치고 최종적으로 2048을 만들어 내는 것이 목표인 게임이다.
한번 타일을 밀 때는 상하좌우를 정해서 밀어야 한다.
방향을 정하면 격자 위에 있는 모든 타일이 그 방향으로 밀린다.
만약 어떤 타일이 밀리는 방향에 다른 타일이 있고, 
두 타일에 적힌 숫자가 같다면 두 타일은 합쳐져 새로운 하나의 타일이 되고 
이 타일에 적힌 숫자는 합쳐진 숫자들의 합이 된다.
이렇게 합쳐져서 만들어진 새로운 타일은 숫자가 같은 다른 타일이 밀려와도 합쳐져서는 안 된다.
만약 같은 숫자가 적힌 타일이 세 개 이상 있을 때는 
헷갈리는 경우를 없애기 위해 빨리 벽에 닿게 될 타일을 먼저 민다고 생각한다.
우리는 2048게임을 N×N 크기의 격자에서 하려고 한다.
현재 격자에 어떤 식으로 타일이 있는지 주어지고, 타일들을 이동시킬 방향이 주어질 때,
타일을 모두 이동시키고 나면 격자가 어떻게 변할 지 계산하는 프로그램을 작성하라.

문제보기



🖨 입출력



📝 풀이

def rotate(tmp_arr):
    return [list(elem) for elem in zip(*tmp_arr[::-1])]


def calc(tmp_arr, N):
    for i in range(N):
        for j in range(N - 1):
            if tmp_arr[j][i]:
                if tmp_arr[j][i] == tmp_arr[j + 1][i]:
                    tmp_arr[j][i] *= 2
                    tmp_arr[j + 1][i] = 0
                elif tmp_arr[j + 1][i] == 0:
                    tmp_j = j + 1
                    while tmp_j < N - 1 and tmp_arr[tmp_j][i] == 0:
                        tmp_j += 1
                    if tmp_arr[j][i] == tmp_arr[tmp_j][i]:
                        tmp_arr[j][i] += 2
                        tmp_arr[tmp_j][i] = 0
    return tmp_arr


def move_zero(tmp_arr, N):
    for i in range(N):
        for j in range(N - 1):
            if tmp_arr[j][i] == 0:
                tmp_j = j + 1
                while tmp_j < N - 1 and tmp_arr[tmp_j][i] == 0:
                    tmp_j += 1
                tmp_arr[j][i] = tmp_arr[tmp_j][i]
                tmp_arr[tmp_j][i] = 0
    return tmp_arr


def move(tmp_arr, N):
    tmp_arr = move_zero(calc(move_zero(tmp_arr, N), N), N)

    return tmp_arr



for tc in range(1, int(input()) + 1):
    N, S = map(str, input().split())
    boards = list(list(map(int, input().split())) for _ in range(int(N)))

    commands = {
        "up": 0,
        "left": 1,
        "down": 2,
        "right": 3,
    }
    for _ in range(commands.get(S)):
        boards = rotate(boards)
    boards = move(boards, int(N))
    for _ in range(4 - commands.get(S)):
        boards = rotate(boards)
    
    print(f'#{tc}')
    for i in range(int(N)):
        for j in range(int(N)):
            print(boards[i][j], end=' ')
        print()

profile
Impossible + 땀 한방울 == I'm possible

0개의 댓글