글 작성자: Doublsb
현재 회사에서 설계하고 유지보수한 3매치 코드는 이미 검증되었지만,
과거의 자신을 돌아보는 것이 늘 그렇듯 다시 읽어보면 구데기인 부분이 너무 많다.

그래서 이 시리즈는 과거의 설계를 돌아보며 더 확장성있는 코드를 고민해보는 글이 되겠다.
으엄... 이번 글은 확장 관련 얘기는 없지만 말이다.

 

조건

1. 연속된 블록의 개수에 따라 다른 결과물을 만들어낼 것

 

매치 케이스 예시

 


 

과거의 나

1. BFS(너비 우선 탐색)으로 연속된 블록들을 모두 리스트로 가져온다.

2. 리스트의 블록들을 순회하면서 그 블록 기준으로 연속된 가로/세로 개수를 구한다.

3. 개수 조건에 들어맞는 매치를 수행한다.

 

class ConnectInfo {
    
    List<Slot> slots;
    
    //중복해서 계산하는 일이 없도록 캐싱함
    Dictionary<Vector2Int, List<Slot>> horizontal;
    Dictioanry<Vector2Int, List<Slot>> vertical;
    
    ConnectInfo(Vector2Int pivot, Block block) {
        slots = BFS(pivot, block);
    }
    
    List<Slot> GetHorizontal(Vector2Int pivot) {
    
        if(!horizontal.Exist(pivot))
    	    horizontal.Add(pivot, slots.Where(e => e.pos.y == pivot.y));
        
        return horizontal[pivot];
    }
    
    List<Slot> GetVertical(Vector2Int pivot) { }
}

abstract class Match {
    
    struct Result { //생략 } 
    abstract Result GetResult(Vector2Int pivot);
}

class Match_3x3 : Match {
    
    override Result GetResult(Vector2Int pivot) {
        
        var block = board.slots[pivot].Blocks.Top;
        var connect = new ConnectInfo(pivot, block); //실제로는 new가 아니라 캐싱해서 파라미터로 불러들여 씀
        
        //연결된 블록들을 순회하면서 3개 이상의 조건에 맞으면 반환함
        foreach(var s in connect.slots) {
            
            var h = connect.GetHorizontal(s.pos);
            var v = connect.GetVertical(s.pos);
            
            if(h.Count >= 3 && v.Count >= 3) 
            	return new Result(horizontal + Vertical); //대충 Append했다 칩시다
        }
    }
}

 

플로우

 

모듈화를 할 때 매치를 쉽게 적용할 수 있도록 객체화했다.

실제로, 2x2 매치를 제외하고 싶으면 우선순위 리스트로 달려가서 주석처리 한 줄만 하면 되니까 잘 짰다고 생각했다.

 

 


 

 

현재의 나

 

1. 가로/세로 개수를 확인할 때, 모든 슬롯을 탐색할 필요가 없었다

연결된 슬롯들을 찾을 때, 2방향 이상의 슬롯이 탐색된 경우 그 지점들을 저장해둘 수 있었다.

그러면 Match_3x3 같은 매치에서 연결된 모든 슬롯들을 탐색할 필요 없이 이 부분들만 탐색해도 되었을 것이다.

이걸 이제 생각해내다니! (이마치기)

2방향 이상의 슬롯이 탐색된 지점

 

 

반응형