재미있는 퍼즐 로직 만들기

네,가능합니다 ㅣ 2024. 11. 7. 20:32

오늘 팀프로젝트가 끝이 났다.

여러가지 재밌는 로직을 만들었는데, 게임에 다양함을 위해 급하게 만들었지만 생각보다 재미있었던

8버튼 로직의 코드를 다시 보고 코드리뷰를 하며 복습하는 시간을 가져보겠다.

 

이 로직은 8개의 버튼이 있고, 각 버튼은 켜고 끌 수 있는 버튼이다.

버튼을 조작하면 양옆의 버튼도 함께 조작된다는 규칙이 있어서, 모두 켜거나 끄기 위해서는 약간의 생각이 필요하다.

 

모두 켠다면 클리어, 모두 끈다면 게임오버로 가정하고 코드를 정리하여 보여주도록 하겠다.

 

원래는 주석을 달았었는데 이제는 코드를 보며 읽는것이 크게 어려움이 없어져서 (나를 위한것이기에...)

코드 예제들을 모두 보여주고 정리를 하는 방식으로 설명하겠다.

 

using UnityEngine;

public class ButtonController : MonoBehaviour
{
    private Light buttonLight;
    private bool isOn = false;
    private int buttonIndex;

    private void Awake()
    {
        buttonLight = GetComponentInChildren<Light>();
    }

    private void Start()
    {
        UpdateLight();
    }

    public void ToggleState()
    {
        isOn = !isOn;
        UpdateLight();
        GameManager.Instance.UpdateButtonCount(isOn);
    }

    public void SetState(bool state)
    {
        isOn = state;
        UpdateLight();
    }

    private void UpdateLight()
    {
        buttonLight.enabled = isOn;
    }

    public void SetIndex(int index)
    {
        buttonIndex = index;
    }

    public void OnButtonInteract()
    {
        GameManager.Instance.ToggleAdjacentButtons(buttonIndex);
    }
}

 

using System.Collections;
using UnityEngine;

public class GameManager : Singleton<GameManager>
{
    public ButtonController[] buttons;
    private int activeButtonCount = 3;
    private bool isCheckingWinOrLose = false;

    private void Start()
    {
        for (int i = 0; i < buttons.Length; i++)
        {
            buttons[i].SetIndex(i);
        }

        buttons[1].SetState(true);
        buttons[2].SetState(true);
        buttons[7].SetState(true);

    }

    public void UpdateButtonCount(bool isActivated)
    {
        activeButtonCount += isActivated ? 1 : -1;

        if (!isCheckingWinOrLose && (activeButtonCount == buttons.Length || activeButtonCount == 0))
        {
            StartCoroutine(CheckWinOrLose());
        }
    }

    private IEnumerator CheckWinOrLose()
    {
        isCheckingWinOrLose = true;
        yield return new WaitForSeconds(0.5f);

        if (activeButtonCount == buttons.Length)
        {
            // 클리어 시 할행동
        }
        else if (activeButtonCount == 0)
        {
            // 게임오버시 할 행동
        }

        isCheckingWinOrLose = false;
    }

    public void ToggleAdjacentButtons(int buttonIndex)
    {
        buttons[buttonIndex].ToggleState();

        int leftIndex = (buttonIndex == 0) ? buttons.Length - 1 : buttonIndex - 1;
        buttons[leftIndex].ToggleState();

        int rightIndex = (buttonIndex == buttons.Length - 1) ? 0 : buttonIndex + 1;
        buttons[rightIndex].ToggleState();
    }
}

 

좋은점은

 

생각보다 코드가 깔끔하게 정리가 잘 되어있어서 가독성이 좋아 코드를 이해하기 어렵지 않을것으로 보인다.

 

버튼컨트롤러에 켜고 껏을때 라이트관련 변수와 메서드들도 모르는 사람도 보면 단어선택때문에 대충 이해할 수 있을것같다.

 

두 코드의 책임 분리가 잘 되어있다.

 

아쉬운 점이라고 생각드는것은 우선 게임매니저에 구현을 했었는데, 관리에 어울리지 않아

게임매니저가 아닌 다른 클래스에 구현을 해서 사용했으면 더 좋았을것같다.

 

뭔가 아쉬운게 느껴지는데 계속 생각해봐도 혼자서는 생각해내지 못하고있는게 지금 너무 아쉽다 ㅠㅠ