코딩테스트/SWExpertAcademy

추억의 2048게임 Python(SW Expert Academy, SWEA)

멍토 2020. 6. 24.

난이도 : D4

문제번호 : 6109

문제 주소 및 출처입니다.

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWbrg9uabZsDFAWQ&categoryId=AWbrg9uabZsDFAWQ&categoryType=CODE

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com


목차

1. 문제 설명

2. 문제 해석

3. 소스 코드


1. 문제 설명

2048이라는 추억의 게임을 아는가? 2048은 한 때 유명했던 1인용 게임으로, 격자 위에서 숫자가 적힌

타일들을 밀어서 합치고 최종적으로 2048을 만들어 내는 것이 목표인 게임이다.

한번 타일을 밀 때는 상하좌우를 정해서 밀어야 한다.

방향을 정하면 격자 위에 있는 모든 타일이 그 방향으로 밀린다.

만약 어떤 타일이 밀리는 방향에 다른 타일이 있고, 두 타일에 적힌 숫자가 같다면 두 타일은 합쳐져

새로운 하나의 타일이 되고 이 타일에 적힌 숫자는 합쳐진 숫자들의 합이 된다.

이렇게 합쳐져서 만들어진 새로운 타일은 숫자가 같은 다른 타일이 밀려와도 합쳐져서는 안 된다.

만약 같은 숫자가 적힌 타일이 세 개 이상 있을 때는 헷갈리는 경우를 없애기 위해 빨리 벽에 닿게 될 타일을 먼저 민다고

생각한다.

예를 들어 “2 2 4 2 2 2”가 적힌 타일들이 있을 때, 이 타일들을 왼쪽으로 밀면 결과는 “4 4 4 2 0 0”이 된다.

0은 타일이 없는 빈 칸을 나타낸다.



위의 그림은 4×4 크기의 격자(일반적인 2048 게임)에서 모든 타일을 오른쪽으로 이동시킨 예이다.

우리는 2048게임을 N×N 크기의 격자에서 하려고 한다.

현재 격자에 어떤 식으로 타일이 있는지 주어지고, 타일들을 이동시킬 방향이 주어질 때,

타일을 모두 이동시키고 나면 격자가 어떻게 변할 지 계산하는 프로그램을 작성하라.

 

입력

각 테스트 케이스의 첫 번째 줄에는 하나의 정수 N(1≤N≤20)과 하나의 문자열 S가 공백 하나로 구분되어 주어진다.

S는 “left”, “right”, “up”, “down”의 넷 중 하나이며 각각 타일들을 왼쪽, 오른쪽, 위쪽, 아래쪽으로 이동시키겠다는 뜻이다.

다음 N개의 줄의 i번째 줄에는 N개의 정수가 공백 하나로 구분되어 주어진다.

이 정수들은 0이거나 2이상 1024이하의 2의 제곱수들이다.

i번째 줄의 j번째 정수는 격자의 위에서 i번째 줄의 왼쪽에서 j번째에 있는 칸에 있는 타일에 어떤 정수가 적혀 있는지 나타내며,

0이면 이 칸에 타일이 없음을 의미한다.

출력

각 테스트 케이스마다 ‘#t’(t는 테스트케이스 번호를 의미하며 1부터 시작한다)를 출력하고 한 줄을 띄운 후,

N줄에 걸쳐 격자의 어떤 위치에 어떤 숫자가 적힌 타일이 있는지 입력 형식과 같은 형식으로 출력한다.

예시

입력 출력
2
5 up
4 8 2 4 0
4 4 2 0 8
8 0 2 4 4
2 2 2 2 8
0 2 2 0 0
2 down
16 2
0 2
#1
8 8 4 8 8
8 4 4 2 4
2 4 2 0 8
0 0 0 0 0
0 0 0 0 0
#2
0 0
16 4

2. 문제풀이

오른쪽으로 민다면 오른쪽부터 합쳐져야 하기때문에 오른쪽의 데이터부터 꺼내서 임시 리스트에 넣었다.

이후 임시리스트를 돌면서 자기 뒤에와 자신의 크기가 일치한다면 자신의 크기를 2배로 늘려주고

뒤에있는 원소를 팝해서 제거했다(병합과정)

같은수가 모두 더 해졌다면 다시 뺏던순서대로 데이터를 넣어준다.


이것을 왼쪽 오른쪽 위 아래 모두 구현해야 하는데 구조가 똑같아서 일반화를 시켜서 코드를 줄였다.



3. 소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#D4 6109 추억의 2048게임
 
#up 혹은 down이면 좌표를 바꿔준다.
def swap(i, j):
    global command
    if command == 'up' or command == 'down':
        return j, i
    return i, j
#명령을 처리해주는 함수이다.
def start(n, command):
    data = dict_lst[command]
    #up down left right에 따라 반복문 조건을 바꾼다.
    for a in range(data[0], data[1], data[2]):
        temp = []
        for j in range(data[3], data[4], data[5]):
            i, j = swap(a, j)
            #데이터가 0이 아닌것들만 더한다.
            if list_2048[i][j]:
                temp.append(list_2048[i][j])
                list_2048[i][j] = 0
        k = 0
        #인근에 있는 값들을 더하고 팝시킨다.
        while len(temp) > k+1:
            if temp[k] == temp[k+1]:
                temp[k] += temp[k+1]
                temp.pop(k+1)
            k+=1
        #데이터를 처리했다면 다시 넣어준다.
        for j in range(data[3], data[4], data[5]):
            i, j = swap(a, j)
            if not temp:
                break
            list_2048[i][j] = temp.pop(0)
 
= int(input())
for t in range(1, T+1):
    list_2048 = []
    n, command = input().split()
    n = int(n)
    dict_lst = {'up': (0, n, 10, n, 1), 'down': (n-1-1-1, n-1-1-1), 'left' : (0, n, 10, n, 1), 'right' : (0, n, 1, n-1-1-1)}
    #들어온 데이터를 리스트에 추가한다.
    for i in range(n):
        list_2048.append(list(map(int, input().split())))
    start(n, command)
    print("#{}".format(t))
    #결과출력
    for k in list_2048:
        print(*k)

 

댓글

💲 광고입니다.