프로그래머스 프렌즈4블록 JavaScript

2023년 5월 17일

프로그래머스 프렌즈4블록

문제 풀이

카카오프렌즈 블록이 2x2 형태로 4개가 붙어있을 경우 사라지면서 점수를 얻는 게임이다. 4개의 블록이 같은 블록으로 사라지면 위 블록들이 아래로 떨어져 빈 공간을 채운다. 떨어진 후 다시 2x2 형태로 같은 모양의 블록이 모이면 다시 지워지고 떨어지고를 반복한다.

우선 2x2 형태로 같은 모양의 블록을 찾는다. 없는 경우 종료하고, 찾은 경우에는 찾은 블록들을 빈 블록으로 바꿔준다.
이후 빈 블록들의 위에 위치한 블록들을 아래로 내려준다. 2x2 형태의 같은 모양의 블록이 없을 때까지 반복한다.


const board_split = board.map(item => item.split(''));: 매개변수 board는 문자열이 저장되어 있는 배열이므로, 블록의 손쉬운 변경을 위해 split 하여 2차원 배열의 형태로 저장한다.

함수:

  • findBlock(): board_split를 순회하면서 2x2 형태로 같은 모양의 블록을 찾아 해당 블록의 맨 왼쪽, 맨 위의 인덱스들의 배열을 반환하는 함수.
    현재 위치에서 2x2 블록을 확인하기에 m - 1, n - 1 만큼 board_split을 순회한다. 현재 위치의 값이 빈 문자열이면 다음으로 이동하고, 빈 문자열이 아닌 경우에는 현재 위치에서 2x2 블록들의 값이 같은 경우 2x2 형태의 같은 모양의 블록이므로 answer에 [h, w] 형태로 push.
  • lowerBlock(): board_split에 빈 문자열이 있을 때, 해당 위치 위에 위치한 문자열들이 빈 문자열이 아닌 경우 아래로 내려주는 함수.
    board_split의 폭 n을 순회할 때, 조회하는 값 중(높이: m)에 빈 문자열이 있으면 빈 문자열을 맨 위로 이동시킨다.
solution.js
function solution(m, n, board) {
    let answer = 0;
    const board_split = board.map(item => item.split(''));
    
    const findBlock = () => {
        const answer = [];

        for (let h = 0; h < m - 1; h ++) {
            for (let w = 0; w < n - 1; w++) {
                const character = board_split[h][w];
                
                if (character === ' ') continue;
                
                if (board_split[h][w + 1] === character && board_split[h + 1][w] === character && board_split[h + 1][w + 1] === character) {
                    answer.push([h, w]);
                }
            }
        }   
        return answer;
    };
    
    const lowerBlock = () => {
        for (let w = 0; w < n; w++) {
            for (let h = 0; h < m; h++) {
                if (board_split[h][w] === ' ') {
                    for (let k = h; k > 0; k--) {
                        const temp = board_split[k][w];
                        board_split[k][w] = board_split[k - 1][w];
                        board_split[k - 1][w] = temp;
                    }
                }
            }
        }
    };
    
    while (true) {
        const blockIndex = findBlock();

        if (blockIndex.length === 0) break;
        
        blockIndex.forEach(indexs => {
            const [x, y] = indexs;
            for (let dx = 0; dx < 2; dx++) {
                for (let dy = 0; dy < 2; dy++) {
                    answer += board_split[x + dx][y + dy] === ' ' ? 0 : 1;
                    board_split[x + dx][y + dy] = ' ';
                }
            }
        });
        
        lowerBlock();
    }

    return answer;
}

댓글