본문 바로가기
알고리즘

[알고리즘] 2048 (Easy)

by keel_im 2020. 10. 15.
반응형

포인트

1. dfs를 통해 4가지 방향으로 진행한다.

2. 2048에서 구현은 생각보다 까다롭다. 

(맵 입력) -> (재귀를 통한 방향 정하기 중복 순열) ->(2048 로직 구하기) -> (최댓값)

🧶문서는 항상 수정 될 수 있습니다. 비판은 환영합니다. 

#include <iostream>
#include <algorithm>
#include <cstring>

#define MAX 20
using namespace std;

int n, answer;
int map[MAX][MAX];
int cmap[MAX][MAX];
int visited[5];

void moveLeft() {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n - 1; j++) {
            bool check = false;
            if (cmap[i][j] == 0) {
                int k = j + 1;
                while (k <= n - 1) {
                    if (cmap[i][k] != 0) {
                        check = true;
                        break;
                    }
                    k++;
                }
                if (check == true) {
                    cmap[i][j] = cmap[i][k];
                    cmap[i][k] = 0;
                }
            }
        }
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n - 1; j++) {
            if (cmap[i][j] == cmap[i][j + 1]) {
                cmap[i][j] = cmap[i][j] * 2;
                cmap[i][j + 1] = 0;
            }
        }
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n - 1; j++) {
            bool check = false;
            if (cmap[i][j] == 0) {
                int k = j + 1;
                while (k <= n - 1) {
                    if (cmap[i][k] != 0) {
                        check = true;
                        break;
                    }
                    k++;
                }
                if (check == true) {
                    cmap[i][j] = cmap[i][k];
                    cmap[i][k] = 0;
                }
            }
        }
    }
}

void moveRight() {
    for (int i = 0; i < n; i++) {
        for (int j = n - 1; j > 0; j--) {
            bool check = false;
            if (cmap[i][j] == 0) {
                int k = j - 1;
                while (k >= 0) {
                    if (cmap[i][k] != 0) {
                        check = true;
                        break;
                    }
                    k--;
                }
                if (check == true) {
                    cmap[i][j] = cmap[i][k];
                    cmap[i][k] = 0;
                }
            }
        }
    }

    for (int i = 0; i < n; i++) {
        for (int j = n - 1; j > 0; j--) {
            if (cmap[i][j] == cmap[i][j - 1]) {
                cmap[i][j] = cmap[i][j] * 2;
                cmap[i][j - 1] = 0;
            }
        }
    }

    for (int i = 0; i < n; i++) {
        for (int j = n - 1; j > 0; j--) {
            bool check = false;
            if (cmap[i][j] == 0) {
                int k = j - 1;
                while (k >= 0) {
                    if (cmap[i][k] != 0) {
                        check = true;
                        break;
                    }
                    k--;
                }
                if (check == true) {
                    cmap[i][j] = cmap[i][k];
                    cmap[i][k] = 0;
                }
            }
        }
    }
}

void moveUp() {
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n; j++) {
            bool Check = false;
            if (cmap[i][j] == 0) {
                int k = i + 1;
                while (k <= n - 1) {
                    if (cmap[k][j] != 0) {
                        Check = true;
                        break;
                    }
                    k++;
                }

                if (Check == true) {
                    cmap[i][j] = cmap[k][j];
                    cmap[k][j] = 0;
                }
            }
        }
    }

    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n; j++) {
            if (cmap[i][j] == cmap[i + 1][j]) {
                cmap[i][j] = cmap[i][j] * 2;
                cmap[i + 1][j] = 0;
            }
        }
    }

    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n; j++) {
            bool Check = false;
            if (cmap[i][j] == 0) {
                int k = i + 1;
                while (k <= n - 1) {
                    if (cmap[k][j] != 0) {
                        Check = true;
                        break;
                    }
                    k++;
                }

                if (Check == true) {
                    cmap[i][j] = cmap[k][j];
                    cmap[k][j] = 0;
                }
            }
        }
    }
}

void moveDown() {
    for (int i = n - 1; i > 0; i--) {
        for (int j = 0; j < n; j++) {
            bool Check = false;
            if (cmap[i][j] == 0) {
                int k = i - 1;
                while (k >= 0) {
                    if (cmap[k][j] != 0) {
                        Check = true;
                        break;
                    }
                    k--;
                }
                if (Check == true) {
                    cmap[i][j] = cmap[k][j];
                    cmap[k][j] = 0;
                }
            }
        }
    }

    for (int i = n - 1; i > 0; i--) {
        for (int j = 0; j < n; j++) {
            if (cmap[i - 1][j] == cmap[i][j]) {
                cmap[i][j] = cmap[i][j] * 2;
                cmap[i - 1][j] = 0;
            }
        }
    }
    for (int i = n - 1; i > 0; i--) {
        for (int j = 0; j < n; j++) {
            bool Check = false;
            if (cmap[i][j] == 0) {
                int k = i - 1;
                while (k >= 0) {
                    if (cmap[k][j] != 0) {
                        Check = true;
                        break;
                    }
                    k--;
                }
                if (Check == true) {
                    cmap[i][j] = cmap[k][j];
                    cmap[k][j] = 0;
                }
            }
        }
    }
}

int findMax() { // 복사된 맵에서 최댓값을 구해준다 .
    int value = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            value = max(value, cmap[i][j]);
        }
    }

    return value;
}

void game() {
    for (int i = 0; i < 4; i++) {
        if (visited[i] == 0)moveRight();
        else if (visited[i] == 1)moveLeft();
        else if (visited[i] == 2)moveDown();
        else if (visited[i] == 3)moveUp();
    }

    answer = max(answer, findMax());
}

void go(int cnt) { //방향을 정한다. 방향을 정하는 방법은 (1, 2, 3, 4, 5) 를 각 자릿수 마다 반복을 할수 있으며
    //중복 순열을 사용한다.
    if (cnt == 5) {
        memcpy(cmap, map, sizeof(map)); // 맵을 복사한다.
        game();
        return;
    }

    for (int i = 0; i < 4; i++) { // 중복 순열을 구하는 방법
        visited[cnt] = i;
        go(cnt + 1);
    }
}

int main() {

    cin >> n;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cin >> map[i][j];
        }
    }
    //입력을 받는다.

    go(0);
    cout << answer << '\n';
}

python

from collections import deque
from copy import deepcopy


def get(i: int, j: int) -> None:
	if data[i][j]:  
		q.append(data[i][j])
		data[i][j] = 0  


def merge(x: int, y: int, dx: int, dy: int) -> None:
	while q:
		block = q.popleft()  
		if not data[x][y]:  
			data[x][y] = block
		elif data[x][y] == block: 
			data[x][y] = block * 2  
			x, y = x + dx, y + dy
		else:  
			x, y = x + dx, y + dy
			data[x][y] = block


def move(k: int) -> None:
	if k == 0:  
		for j in range(n):
			for i in range(n):
				get(i, j)
			merge(0, j, 1, 0)
	elif k == 1:  
		for j in range(n):
			for i in range(n - 1, -1, -1):
				get(i, j)
			merge(n - 1, j, -1, 0)
	elif k == 2:
		for i in range(n):
			for j in range(n):
				get(i, j)
			merge(i, 0, 0, 1)  
	else:  
		for i in range(n):
			for j in range(n - 1, -1, -1):
				get(i, j)
			merge(i, n - 1, 0, -1)  


def go(cnt: int) -> None:
	global data, answer
	if cnt == 5:  
		for i in range(n):
			answer = max(answer, max(data[i]))  
		return
	
	cdata = deepcopy(data)
	
	for dir in range(4):  
		move(dir)  
		go(cnt + 1)  
		data = deepcopy(cdata)


n = int(input())
data = [list(map(int, input().split())) for _ in range(n)]
answer, q = 0, deque()

go(0)
print(answer)

 

반응형

'알고리즘' 카테고리의 다른 글

[알고리즘] c++ cpp 봄버맨  (0) 2020.10.16
[알고리즘] 퇴사  (0) 2020.10.15
[알고리즘] cpp c++ 다리 만들기2  (0) 2020.10.14
[알고리즘] 낚시왕  (0) 2020.10.14
[알고리즘] c++ cpp 새로운게임 2  (0) 2020.10.14

댓글