Billy Poter - I'll Be There


오늘은 빌리 포터의 I'll Be There라는 곡에 대해 포스팅 해보도록 하겠습니다.

사실 빌리 포터는 많은 히트곡을 가진 가수는 아니지만

팝을 좋아하는 사람이라면 한번쯤은 들어보았을 것입니다.



가수 김범수씨가 빌리 포터의  Love is on the way라는 곡을 방송에서

부른 적이 있는데 아마 윤도현의 러브레터였던 것으로 기억합니다.

그 당시에 그 영상을 정말 수도없이 돌려보았고 시간이 조금 지난 후에서야

원곡이 궁금해 찾아보았고, 빌리 포터란 아티스트에 대해 알게되었습니다.


여담이지만 윤도현의 러브레터라는 프로그램이 좋은 노래를 많이 알게 해준 것 같습니다.



I'll Be There라는 곡은 이후 빌리 포터에 관심이 생긴 뒤 몇 곡을 더들어보다 좋아지게된 곡입니다.

좋은 노래 뿐만 아니라 빌리 포터라는 가수는 정말이지 상당한 가창력을 가지고 있습니다.

브라이언 맥나잇, 와냐 모리스 등 많은 흑형분들이 그렇듯.. 빌리 포터 또한 이에 뒤지지 않는 소울을 가지고 있습니다.



빌리 포터에 대해 알아가면서 상당히 아쉬운 점이 있었다면

발매된 곡 수가 상당히 적다는 것입니다. 제가 알기로는 하나의 앨범이 전부인 걸로 알고있습니다.

I'll Be There는 정식 음원으로도 나오지 않아 듣기에 상당한 불편함이 있었습니다 ㅎㅎ


상당한 가창력을 소유하였음에도 불구하고 앨범을 왜 내지 않느냐.. 의아했지만

뮤지컬쪽에서 왕성하게 활동하고 있다고 합니다.


오늘 소개해드린 빌리 포터의 I'll Be There

흑인 특유의 소울풀한 목소리와 잔잔한 R&B를 듣고 싶으시다면 오늘 시간내어 들어볼만한 가치가 있는 곡입니다.


[DFS 알고리즘] 빙산 (정올)


게임 만들랴 자소서쓰랴 정신 없는 7월이 지나가고

한 달만에 풀어보는 알고리즘..


이번에는 정답률 20%대의 DFS 알고리즘을 풀어보았습니다.

정답률이 낮은 문제의 특징은 정말 어렵거나.. 아니면 함정이 많은 문제인데

이 문제는 어려운 문제라기 보다는 함정이 많은 문제가 되겠습니다.


DFS 알고리즘 문제 - 빙산 (정올)


01. 변수 선언 및 초기화


02. 재귀 함수


03. 1년 후 빙산의 변화 예측 함수


함정 1 : 빙산의 모습을 1년 후로 바꿀 때, 녹아 없어질 빙하라도 바로 0으로 바꾸어준다면 인접한 빙하에 영향을 주게 됩니다.

그래서 저는 -9999라는 숫자로 일단 바꾸어주고, 모든 빙하를 다 둘러본 뒤 -9999의 값을 0으로 다시 바꾸어 주었습니다.


04. 메인


함정 2 : 빙하가 아예 없어질 때까지 반복문을 돌려야 합니다.

따라서 while문을 돌려주고 두 동강 났다면 답 출력하고 리턴

더 이상 체크할 빙하가 없다면 반복문 종료. 그리고 0 출력



20%대 문제 치고는 살짝 쉬운 감이 있지만, 문제를 꼼꼼히 읽지 않았다면 또 한참 헤맸을 법한 문제였습니다.


[모바일 퍼즐 게임] 피즈 펑크! Pz Punk! : The Candy Thief


기획/제작 : 김영조

제작 기간 : 3주

제작 툴 : 유니티



유튜브 영상 링크 : https://www.youtube.com/watch?v=YqW_wrVXG44

다운로드 링크 (안드로이드) : https://play.google.com/store/apps/details?id=com.YJ.PZPunk


----------------------------------------------------------------------------------------------------


게임을 만든 방법

1. DFS 알고리즘 (재귀 함수)

화면상의 과일들을 움직여 3개 이상이 되면 미완성 캔디로 만드는 과정이 필요합니다.
그렇다면 이동된 과일의 상하좌우를 탐색하여 3개 이상이면 캔디로, 아니라면 다시 원위치로 돌아가야 합니다.
이동된 과일의 인접한 부분뿐만 아니라 같은 색으로 이어진 모든 과일들의 주변을 탐색해야 하기 때문에
이를 구현하기 위해 두 가지의 선택지를 생각했습니다.

1. BFS 알고리즘    (큐, 넓이 우선 탐색)
2. DFS 알고리즘    (스택, 재귀 함수, 깊이 우선 탐색)

두 가지 중 DFS 알고리즘이 좀 더 직관적으로 구현하기 좋겠다 생각했고
과일의 체크를 담당하는 Checker라는 클래스를 만들어 재귀 함수를 구현했습니다.

아래는 Checker 클래스의 Connect_Check_Recurse() 재귀 함수의 간략한 설명입니다.

1. 매개 변수로 들어온 x와 y는 해당 과일의 배열 내 인덱스 값이기 때문에 배열의 범위를 벗어나면 안 됩니다. (배열이 곧 퍼즐 판의 크기)
2. 이미 이 메서드로 체크가 된 과일인 경우 체크 대상에서 제외합니다. (같은 타입의 과일이 인접해 있다면 무한 호출에 빠지기 때문입니다.)
3. 현재 떨어지고 있는 과일일 경우 바닥에 착지한 시점부터 체크가 진행되어야 합니다.
4. 같은 타입의 과일인지 체크하고, 같은 타입이라면 이 과일을 기준으로 또다시 상하좌우 체크를 떠나게 됩니다.


유저가 선택한 과일이 지정한 방향으로 이동이 완료되면
선택한 과일을 시작으로 Connent_Check_Recurse() 함수가 호출되게 됩니다.



S를 시작으로 재귀 함수의 호출 순서대로 숫자를 표기했습니다.


1. 유저가 선택한 과일 S를 시작으로 상하좌우 순서로 체크를 떠나기 때문에 1번 과일로 가게 됩니다.

2. 1번 과일이 같은 타입이기 때문에 1번 과일을 기준으로 다시 상하좌우 체크를 하게 됩니다.

3. 1번 과일의 상, 좌, 우측에 있는 과일은 같은 타입이 아니고, 밑은 이미 체크된 과일이기 때문에 재귀 함수의 탈출 조건에 걸리게 됩니다.

4. 1번 과일의 재귀 함수가 완전히 종료되고, 최근에 호출되었던 재귀 함수로 돌아가 나머지 작업을 수행하게 됩니다.

5. 14번째 진행과정은 배열의 범위를 초과한 범위이기 때문에 탈출 조건에 걸리게 됩니다.



2. 버킷 릴레이


위 그림의 번호는 배열 내의 x축 인덱스 값을 나타냅니다.

1번 과일과 2번 과일의 위치를 바꾸어 봅니다.

눈으로 보기에는 성공적으로 위치가 바뀌어 보이지만, 메모리상의 위치는 변함이 없습니다.


1) 화면상의 과일들은 유저의 조작에 따라 인접한 과일과 바뀌는 액션이 필요합니다.

--> 이를 구현하기 위해서 선택한 방법은 버킷 릴레이 방식으로 과일들의 오프셋을 계산해 주는 방식입니다.


A) 과일들이 나열되어 있습니다. 이제 1번과 2번 과일의 위치가 바뀌는 과정을 설명하겠습니다.
B) 1번 과일과 2번 과일의 정보를 바꾸어 줍니다. (과일의 타입 또한 교환되기 때문에 타입이 바뀌게 됩니다.)
2) 두 과일의 위치를 체인지 합니다. 

위의 동작은 한 프레임안에 동작하는 것이기 때문에 플레이어의 눈에는 이동하지 않은 것으로 보이게 됩니다.


그 후 여러 프레임에 걸쳐 두 과일의 위치가 원래 자리로 돌아가게 됩니다.

ex)
1번 과일의 position.x - 2번 과일의 position.x = -1 이라면
위 두 과일의 x축 거리는 (절댓 값) 1만 큼 차이 난다는 것을 의미합니다.

따라서 계산된 값을 서서히 0으로 만드는 과정에서 둘의 위치값에 적절한 수를 연산해 준다면
원하는 위치까지 서서히 이동하는 모션을 구현할 수 있습니다.

이 방식을 사용하면 바로 옆의 과일만 스위치 할 수 있는 것이 아니라
멀리 있는 과일과도 위치가 바뀌는 모션을 사용할 수 있습니다.

만약 계산 결과가 (절댓 값) 4만큼 차이가 난다면 1차이가 났을 때보다 더욱 긴 거리를 이동하게 될 것입니다.


2) 캔디로 만들어진 자리는 빈 공간이 되기 때문에 그 자리를 하늘에서 떨어지는 과일로 채우는 액션이 필요합니다.


이 경우에도 버킷 릴레이 방식을 활용하여 과일이 하늘에서 떨어지는 것처럼 구현할 수 있었습니다.


3. 클래스 재활용

DFS 알고리즘으로 연결된 과일이 몇개인지 확인하는 Checker라는 클래스를 만들었습니다.

1) 게임 시작과 동시에 과일의 초기 배치

--> 3개 이상이 되면 과일이 캔디가 되어버리기 때문에 초기 배치에는 3개 이상이 연결되어 있으면 안 됩니다.
--> 난이도를 생각해서 2개씩 뭉쳐있는 것이 좋다고 판단하여 초기 배치에는 같은 과일이 2개씩 붙어있게 만들었습니다.
--> 적절한 난수를 이용한다면 난이도를 유동적으로 바꿀 수 있습니다.


과일의 초기 배치를 담당하는 FruitMaker 클래스에서 Checker 클래스를 활용하여 초기 배치에 성공했습니다.

2) 과일을 인접 과일과 스위치

--> 선택된 과일이 유저가 선택한 방향으로 옮겨졌다면 이동 완료와 동시에 주위 과일들을 탐색하여
캔디로 바꿀 것인지 혹은 원 위치로 다시 돌아갈 것인지 결정해야 합니다.

과일의 이동을 담당하는 FruitCtrl 클래스에서 Checker 클래스를 활용하여 3개 이상이면 변환, 아니라면 다시 스위치 하도록 구현했습니다.

3) 빈 공간을 떨어지는 과일로 채우기

--> 캔디로 바뀐 빈 공간은 다시 다른 과일들로 채워져야 합니다.
--> 하늘에서 과일이 떨어져 빈 공간을 채우는 형식으로 모두 떨어진 뒤에는 인접한 곳에 자신과 같은 과일이 있는지 확인해야 합니다.

이 또한 과일의 이동을 담당하는 FruitCtrl 클래스에서 Checker 클래스를 활용하여 떨어진 과일의 인접 과일을 체크하도록 했습니다.

4) 미완성 캔디가 이어진 수에 따른 Crush

--> 미완성 캔디의 이어진 수가 많을수록 더욱 많은 보너스 점수를 받을 수 있습니다.
--> 때문에 미완성 캔디의 이어진 수를 확인하는 것도 주요 작업 중 하나입니다.


Checker 클래스의 상하좌우로 동일한 객체를 찾는 로직을 이용하여 미완성 캔디의 수를 카운트했습니다.


4. 오브젝트 풀

과일로 만들어진 캔디를 박스에 담는 것이 주요 점수원이기 때문에 캔디를 매번 생성해 주어야 합니다.


1) 게임이 끝날 때까지 많게는 수 천 번의 캔디 생성이 있을 수 있기 때문에 캔디를 게임 시작과 동시에 적정량을 미리 생성했습니다.
2) 생성된 캔디는 캔디 리스트에 저장되어 비활성 상태로 대기하게 됩니다.
3) 캔디가 필요한 위치에 활성 상태로 나타나게 되며, 화면에서 사라진다면 다시 캔디 리스트에 비활성 상태로 대기하게 됩니다.


5. 구글 플레이 게임 서비스


퍼즐 게임의 특성상 점수의 기록이 매우 중요하기 때문에 구글 플레이 게임 서비스와 연동하여 랭킹 시스템을 추가했습니다.
또한 18가지의 업적을 추가하여 게임을 하면서 숨겨진 미션들을 완료할 수 있게 콘텐츠를 추가했습니다.


+ Recent posts