새소식

제작/한폭의 그림을 만들리

중복된 퍼즐 조각의 해결

  • -

 

문제점

퍼즐 조각 중 Scale,Sprite값이 동일한 경우 같은 퍼즐 조각으로 서로 다른 위치에 있어도 같음을 판단할 수 있어야 됨
하지만, 각 퍼즐 조각에 대한 "복사"를 통한 퍼즐 배치가 아닌, 직접적인 "참조"를 통해 퍼즐을 배치한다.
 

해결

퍼즐 조각에 대한 공유를 통한 퍼즐을 가져오기 위한 방법을 사용
이에 대해 적용한 패턴은 FlyWeight 패턴을 적용해 보았음
 
중복을 없애려고 했지만, 중복을 허용해야지만 각 퍼즐 조각에 대한 개수를 표시할 수 있다고 생각했음
 
FlyWeighy 는 대량의 데이터를 생성 및 공유하는 개념으로 관리를 하지만, 여기서는 이미 생성이 되어 있는 퍼즐 조각 데이터를 등록하고, 공유하도록 만들어보았다.
하지만, 아직 많이 미흡하다고 생각한다.
 

Pices 공유하는 클래스 
PicesData각 퍼즐 조각이 반드시 소유해야 되는 데이터 정보
Container하위에 모든 퍼즐 조각이 위치해 있으며, 초기에 불러와 등록한다.
PuzzleDirctionary퍼즐 조각에 대한 모든 정보[Pices] 를 저장하고 있으며, 같은 Name 별로 List에 저장된다.

 
 
 

 
 

 
 

 
 

퍼즐 조각 찾기

 
퍼즐조각을 찾을 때는 PuzzleData.Name을 통해 Dictionary에 전달해 Pices 정보를 비교한다.
 

 

using System.Collections.Generic;
using System.Linq;
using UnityEngine;

/// <summary>
/// 모든 퍼즐에 대한 정보를 저장하고 가지고 있는다.
/// 참조할 때 사용된다.
/// </summary>
public class PuzzleDictionary : MonoBehaviour
{
    #region Instance
    static PuzzleDictionary _instance;
    public static PuzzleDictionary Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = FindObjectOfType<PuzzleDictionary>();
                if (_instance == null)
                {
                    GameObject go = new GameObject("PuzzlePieceFactory");
                    _instance = go.AddComponent<PuzzleDictionary>();
                }
            }
            return _instance;
        }
    }
    #endregion

    private Dictionary<string, List<Pices>> dictionary = new Dictionary<string, List<Pices>>();

    public PicesData[] GetAllPicesData()
    {
        return dictionary.SelectMany(kv => kv.Value).Select(x=>x.data).ToArray();
    }

    //중복되지 않은 퍼즐 조각 데이터를 한개씩 반환
    public PicesData[] GetVariablePicesData()
    {
        if (dictionary.Count == 0) return null;

        return dictionary.Values.Select(x => x[0].data).ToArray();
    }

    //해당 이름을 가진 모든 퍼즐 조각을 반환합니다.
    public Pices[] GetPicesWithName(string name)
    {
        if(!dictionary.ContainsKey(name)) return null;
        return dictionary[name].ToArray();
    }
    
    //해당 피스에 남은 조각 수
    public int GetPicesCount(string name)
    {
        if (dictionary.Count == 0) return 0;

        if (!dictionary.ContainsKey(name)) {  Debug.LogWarning($"{name} 에 해당하는 값이 없습니다."); return 0; }

        int length = dictionary[name].Where(x => !x.data.Activation).ToArray().Length;

        return length;
    }

    //원하는 조각 중 하나
    public Pices GetPiece(string name)
    {
        if (!dictionary.ContainsKey(name))
        {
            return null;
        }

        Pices[] p = dictionary[name].Where(x => !x.data.Activation).ToArray();

        return  p!=null ?  p[0] : null;
    }
    
    //조각 추가
    public void AddPiece(string name, Pices data)
    {
        if (data == null)
        {
            Debug.LogError($"{name}에 해당하는 사전값이 없습니다.");
        }

        if (!dictionary.ContainsKey(name)) dictionary[name] = new List<Pices> {data};
        else dictionary[name].Add(data);

        Debug.LogError($"{name}등록 {dictionary[name].Count} {data.name}");
    }

    //모든 조각 제거
    public void Clear()
    {
        if (dictionary.Count == 0) { Debug.LogError("퍼즐 사전에 데이터가 없습니다."); return; }

        foreach(var p in dictionary.Values)
        {
            p.Clear();
        }

        dictionary.Clear();
    }
}

 
 
 

결과

 

'제작 > 한폭의 그림을 만들리' 카테고리의 다른 글

기본 기능 완성  (0) 2024.06.17
카메라 입력 및 OrthographicSize  (0) 2024.06.16
중간 결산 24.6.15  (0) 2024.06.15
퍼즐 오브젝트의 Sort 정렬  (0) 2024.06.15
UI를 통한 퍼즐 조각 꺼내기  (0) 2024.06.15
Contents

아핫

땡큐하다