본문 바로가기
알고리즘 문제

[알고리즘 문제] Tetris

by 박연호의 개발 블로그 2019. 4. 3.

import java.util.*;

public class Main {
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);

        int width = sc.nextInt(); // 테트리스 가로
        int height = sc.nextInt(); // 테트리스 세로
        int[][] ary = new int[height][width]; // 현재 테트리스를 저장하는 배열

        boolean depthChecek; // 막대기를 넣었을 때 맵을 벗어나는지 검사
        int depthCheckFailList = 0; // 막대기를 넣었을때 맵상을 벗어나는 경우의 수
        List<Map> mapList = new LinkedList<Map>(); // ㅣ모양 블럭을 넣을 수 있는 경우의 집합
        Map<Integer, Integer> map = new HashMap<Integer, Integer>(); // ㅣ모양 블럭을 넣을 수 있는 경우

        int maxDepth = 0; // 한번에 블록수평선을 없앨 수 있는 최대 개수
        int maxDepthXPosition = 0; // 한번에 블록수평선을 없앨 수 있는 x위치 값

        for (int h = 0; h < height; h++) {
            for (int w = 0; w < width; w++) {
                ary[h][w] = sc.nextInt();
            }
        }

        for (int x = 0; x < width; x++) { // 모든 n번째 x위치를 검사
            depthChecek = true;
            for (int y = 0; y < 4; y++) { // ㅣ모양 블럭 맵을 넣는 경우 맵을 벗어나는지 검사
                if (ary[y][x] == 1) {
                    depthChecek = false;
                    depthCheckFailList++; // 맵을 벗어나는 경우를 체크
                    break;
                }
            }
            if (depthChecek) {
                map = removeBlockCheck(ary, x, height, width); // 벗어나지 않는다면, 얼마나 많은 수평블럭을 없앨 수 있는지 구함
                mapList.add(map);
            } else {
                continue;
            }
        }

        if (depthCheckFailList == width) { // 모든 x에 대하여 ㅣ블럭을 넣어 맵읇 벗어나면 게임 종료
            System.out.println(0 + " " + 0);
            return;
        }

        for (Map m : mapList) {
            Iterator<Integer> keys = m.keySet().iterator();
            while (keys.hasNext()) {

                int key = keys.next();
                int value = (int) m.get(key);

                if (value > maxDepth) { // 맵을 돌면서 가장 많이 수평블럭을 없앨 수 있는 개수와 그때의 x값을 구함
                    maxDepth = value;
                    maxDepthXPosition = key + 1;
                }
            }
        }
        if (maxDepth == 0) {
            System.out.println(0 + " " + 0);
        } else {
            System.out.println(maxDepthXPosition + " " + maxDepth);
        }
    }

    static Map<Integer, Integer> removeBlockCheck(int[][] ary, int x, int height, int width) {

        boolean removableYBlock; // 수평으로 블럭을 지울 수 있는지 체크
        int depthCount = 0; // 얼마나 많은 수평블럭을 없앨 수 있는지 체크
        Map<Integer, Integer> map = new HashMap<Integer, Integer>(); // 수평블럭을 얼마나 없앨 수 있는지와 그때의 x값을 저장한 변수

        for (int y = 0; y < height; y++) {

            if (ary[y][x] == 1) { // y축으로 진행하다, 블럭을 만나는 경우 break
                break;
            }

            removableYBlock = true;

            for (int a = 0; a < x; a++) { // x를 기준으로 왼쪽방향에 모두 블럭이 있는지 검사
                if (ary[y][a] == 0) {
                    removableYBlock = false;
                    break;
                }
            }
            for (int b = x + 1; b < width; b++) { // x를 기준으로 오른쪽방향에 모두 블럭이 있는지 검사
                if (ary[y][b] == 0) {
                    removableYBlock = false;
                    break;
                }
            }

            if (removableYBlock) { // 모두 있는 경우 depthCount++;
                depthCount++;
            }
        }

        map.put(x, depthCount);
        return map;
    }
}

테트리스 게임을할 때, "ㅣ"모양 하나가 들어갈 정도의 구역을 나두고 블럭을 쌓다가 "ㅣ'블럭이 나오면 한번에 블럭을 없애는 방법으로 테트리스 게임을 많이 할 것이다.

 

위의 문제는 "ㅣ"을 블럭(1x4크기)넣었을 때 얼마나 많은 블럭을 없앨 수 있는지, 또 그때의 x값 위치를 구하는 것이다. 출력은 없앨 수 있는 블럭의 최대 개수, 그때의 x위치를 출력한다. 만약 "ㅣ"모양의 블랙을 쌓았는데 맵을 벗어나거나, 없앨 수 있는 블럭이 하나도 없다면 모두 0을 출력한다.

 

아이디어는 먼저 "ㅣ"블럭을 넣었을 때, 맵상을 벗어나는지 검사하고 그렇지 않은 경우  "ㅣ"블럭을 넣었을 때, 얼마나 많은 블럭을 없앨 수 있는지 계산하는 것이다.  계산하는 방법은 y축을 하나씩 증가하면서 x축을 기준으로 왼쪽/오른쪽을 검사하여 모두 블럭이 있는 경우에만 변수에++해주었다. 

 

이렇게 모든 X에 대하여 계산을 한 후, map구조로 return하고 이런 map은 list에 저장된다. 마지막에는 블럭을 없앨 수 있는 최대값을 구하는게 목저이기 때문에 list를 돌면서 최대값을 구해주었다.

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

[알고리즌 문제] BeeHive  (0) 2019.04.06
[알고리즘 문제] Seat  (0) 2019.04.04
[알고리즘 문제] 대푯값  (0) 2019.04.02
[알고리즘] Class President  (0) 2019.04.02
[알고리즘 문제] Mine  (0) 2019.03.31