3x3 그리드를 문자열로 인코딩하고 정규식 일치를 사용 하면 특정 그리드 구성이 특정 레시피와 일치하는지 확인하는 것이 간단합니다 . 조회 속도를 높이는 것은 다른 문제이며 결국 이야기하겠습니다. 자세한 내용은 계속 읽으십시오.
1 단계) 그리드를 문자열로 인코딩
각 셀 유형에 문자 ID를 지정하고 다음 순서대로 모든 항목을 나란히 연결하십시오.
123
456 => 123456789
789
보다 구체적인 예로, W는 나무를 나타내고 E는 빈 셀입니다 (빈 문자 ''를 사용할 수 있음).
EEE
WEE => EEEWEEWEE
WEE
2 단계) 정규 표현식 (또는 문자열을 사용하여 레시피 일치) 데이터에 약간의 처리가 포함되어 있습니다.
위의 예에서 계속해서, 우리가 포메이션을 움직여도 문자열에는 여전히 패턴이 있습니다 (양쪽에 E로 채워진 WEEW).
EEW
EEW => EEWEEWEEE
EEE
따라서 스틱을 어디에서 움직여도 여전히 다음 정규식과 일치합니다. /^E*WEEWE*$/
정규식을 사용하면 언급 한 조건부 동작을 수행 할 수도 있습니다. 예를 들어 (레시피 구성) 철 이나 석재로 만든 곡괭이가 같은 결과 를 원할 경우 :
III SSS
EWE or EWE
EWE EWE
정규식으로 두 가지를 결합 할 수 있습니다. /^(III)|(SSS)EWEEWE$/
수평 플립도 마찬가지로 쉽게 추가 할 수 있습니다 (연산자를 사용하여).
편집 : 어쨌든 정규 표현식 부분이 꼭 필요한 것은 아닙니다. 단일 식으로 문제를 캡슐화하는 한 가지 방법 일뿐입니다. 그러나 가변 위치 문제의 경우 모든 패딩 공간 (또는이 예제에서 E)의 그리드 문자열을 자르고 String.Contains ()를 수행 할 수 있습니다. 그리고 다중 성분 문제 또는 미러 된 레시피의 경우, 동일한 출력을 가진 모든 (즉, 별도의) 레시피로 모든 것을 처리 할 수 있습니다.
3 단계) 조회 속도 향상
검색을 줄이려면 레시피를 그룹화하고 조회에 도움이되는 일부 데이터 구조를 작성해야합니다. 그리드를 문자열로 취급하면 여기에도 몇 가지 장점이 있습니다 .
비어 있지 않은 첫 번째 문자와 비어 있지 않은 마지막 문자 사이의 거리로 레시피의 "길이"를 정의 할 수 있습니다. 간단한 Trim().Length()
정보 만 제공하면됩니다. 레시피는 길이별로 그룹화하여 사전에 저장할 수 있습니다.
또는
"길이"의 다른 정의는 비어 있지 않은 문자 수입니다. 다른 것은 변하지 않습니다. 이 기준에 따라 레시피를 그룹화 할 수도 있습니다.
포인트 번호 1이 충분하지 않은 경우 레시피는 레시피에 나타나는 첫 번째 재료의 유형별로 그룹화 될 수 있습니다. 이것은 수행하는 것만 큼 간단합니다 Trim().CharAt(0)
(그리고 트림을 방지하여 빈 문자열을 생성 함).
예를 들어 레시피는
Dictionary<int, Dictionary<char, List<string>>> _recipes;
그리고 다음과 같이 조회를 수행하십시오.
// A string encode of your current grid configuration
string grid;
// Get length and first char in our grid
string trim = grid.Trim();
int length = trim.Length();
char firstChar = length==0 ? ' ' : trim[0];
foreach(string recipe in _recipes[length][firstChar])
{
// Check for a match with the recipe
if(Regex.Match(grid, recipe))
{
// We found a matching recipe, do something with it
}
}