프로그래밍/기타
3매치 구조 회고 (3) : 효율적으로 매치하기
Doublsb
2023. 9. 19. 14:55
현재 회사에서 설계하고 유지보수한 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 같은 매치에서 연결된 모든 슬롯들을 탐색할 필요 없이 이 부분들만 탐색해도 되었을 것이다.
이걸 이제 생각해내다니! (이마치기)
반응형