본문 바로가기

Game Make

Block Puzzle 만들기 (2)

어제에 이어서 계속 작업한다. 

오늘은 게임의 백미라고 할수 있는 '라인 제거' 시스템을 만든다.

먼저 작업해야 할것은 9x9 데이터를 검토하여 어떤 블럭을 제거해야 하는지 검사하는 함수를 만드는 것...

일단 로직 자체가 간단하기 때문에 쉽게 만들 수 있을 것 같다.

 ///<summary> _Table에서 없어져야할 블럭을 찾아서 tempState에 표시한다. return clearBlockCount </summary>
public int FindAndMakeClearBlock()
{

    for (int i = 0; i < _tempState.Length; i++)
        _tempState[i] = 0;
    /// 가로 방향으로 제거블럭을 탐색한다.
    for (int i = 0; i < Constants.TableSize; i++)
    {
        int count = 0;
        for (int j = 0; j < Constants.TableSize; j++)
        {
            if (_state[i * Constants.TableSize + j] > 0)
                count++;
        }
        if (count == Constants.TableSize)
        {
            for (int j = 0; j < Constants.TableSize; j++)
                _tempState[i * Constants.TableSize + j] = Constants.ClearCode;
        }
    }

    /// 세로 방향으로 제거블럭을 탐색한다.
    for (int i = 0; i < Constants.TableSize; i++)
    {
        int count = 0;
        for (int j = 0; j < Constants.TableSize; j++)
        {
            if (_state[j * Constants.TableSize + i] > 0)
                count++;
        }
        if (count == Constants.TableSize)
        {
            for (int j = 0; j < Constants.TableSize; j++)
                _tempState[j * Constants.TableSize + i] = Constants.ClearCode;
        }
    }
    int clearCount = 0;
    for (int i = 0; i < _tempState.Length; i++)
        if (_tempState[i] == Constants.ClearCode)
            clearCount++;
    return clearCount;
}

좋다!! 정말 단순하지만 물셀틈 없는 코드다.

이것으로 턴을 종료하고 실행 버튼을 눌러본다!

잘 돌아가나 확인하자.

오오! 된다!

와! 

된다!

드디어 된다!

캬! 이맛에 코딩하는 거 아입니까!!!

자! 진정하자!

아직 끝이 아니다!

프로는 여기서 만족하지 않는 법!

 

이제 다음 단계를 진행한다. 

이 퍼즐은 약간 스도쿠 같은 뉘앙스가 들어있어서 3x3덩어리를 각 구획에 맞게 끼워넣어도 클리어해주는 조건이 있다.

그 부분을 추가해 보자.

기존에 만들었던 함수를 좀더 확장해야 한다.

.
.
.
//// 3x3 클리어 체크
for (int i = 0; i < 3; i++)
{
    for (int j = 0; j < 3; j++)
    {
        int count = 0;
        for (int k = 0; k < 3; k++)
        {
            for (int l = 0; l < 3; l++)
            {
                if (GetValue(_state, l + j * 3, k + i * 3) > 0)
                    count++;
            }
        }
        if(count == Constants.TableSize)
            for (int k = 0; k < 3; k++)
            {
                for (int l = 0; l < 3; l++)
                {
                    SetValue(_tempState, l + j * 3, k + i * 3, Constants.ClearCode);
                }
            }
    }
}
int GetValue(int[] table, int x, int y) => table[y * Constants.TableSize + x];
void SetValue(int[] table, int x, int y, int value) => table[y * Constants.TableSize + x] = value;

좋다!

for를 4번이나 중첩해서 머리에 피마른 이후로는 본 적도 없는 'l'변수까지 소환됐지만 여전히 믿음직스럽게 단순한 코드다.

 

역시.

역시. 문제없이 잘돌아간다.

예상대로군.

그럼 이제 당면한 다음 문제로 바로 넘어간다. 

더이상 맞출 수 있는 블럭이 없다면 Game Over 상태로 게임이 전환되어야 한다.

그래야 게임을 재시작 할수 있으니까.

 

그에 앞서 하단 UI의 각 조각들을 평가할수 있는 함수를 추가 제작해 보자.

평가의 기준은 해당 조각들을 끼워넣을 공간이 테이블에 존재하는가?- 하는 것이다.

 

단순하게 조각을 테이블의 모든 위치에 대해 테스트하면 쉽게 해결되는 일이다.

테이블의 크기는 9x9 = 81칸에 불과하다!

여러 조건을 고려해도 1000여번의 비교연산으로 조각 하나의 상태를 평가해 낼 수 있다.

이 정도면 괜히 최적화해보겠다고 코드를 복잡하게 꼬을 필요도 없어 보인다.

///<summary> 현재의 테이블에 해당 조각을 넣을 공간이 있는지 확인한다. </summary>
public bool CheckAcceptableArea(DokuPiece piece)
{
    if (piece._table == null)
        return false;
    for (int i = 0; i < Constants.TableSize; i++)
        for (int j = 0; j < Constants.TableSize; j++)
            if (IsAcceptablePiece(j, i))
                return true;
    return false;

    ///<summary> piece를 (x,y)위치에 놓을수 있는지 확인한다. </summary>
    bool IsAcceptablePiece(int x, int y)
    {
        for (int i = 0; i < piece._size.y; i++)
            for (int j = 0; j < piece._size.x; j++)
            {
                //// 테이블 경계를 벗어나면 실패.
                if (i + y >= Constants.TableSize || j + x >= Constants.TableSize)
                    return false;
                //// 조각과 테이블의 조각이 겹치면 실패.
                if (piece._table[piece._size.x * i + j] == true && GetValue(_state, j + x, i + y) > 0)
                    return false;
            }
        return true;
    }

    int GetValue(int[] table, int x, int y) => table[y * Constants.TableSize + x];
}

좋다! 단순무식하지만 간결하다!

잘 될것 같은 느낌이 온다.

시험해보자!

OK!

그렇다!

이 정도는 그냥 논스톱 클리어다. 곧바로 다음 단계로 넘어간다.

이제 GameOver 이벤트를 발생시키고 메인 메뉴로 돌아가게 만드는 일을 처리해 보자!

 

조각을 화면에 놓는 시점에 하단부의 조각3개를 모두 체크한다.

체크결과 모두 공간이 없다면 GameOver로 진행하도록 한다.

 

Game over

오케이!

점수도 같이 구현해서 넣었다. (간단히 ClearBlock에 10점을 곱한 것으로 정했다.)

아마 콤보같은 개념을 넣으면 좀더 재미있지 않을까?

 

오늘은 여기까지 내일 계속 진행한다.

'Game Make' 카테고리의 다른 글

Block Puzzle 만들기 (6)  (0) 2023.10.14
Block Puzzle 만들기 (5)  (0) 2023.10.11
Block Puzzle 만들기 (4)  (0) 2023.10.08
Block Puzzle 만들기 (3)  (0) 2023.10.07
Block Puzzle 만들기  (0) 2023.10.05