void SetInitialNumberClues(Puzzle puzzle) { for (int face = 0; face < 3; ++face) { // 퍼즐의 한 면 var numberClueFace = puzzle.numberClue[face]; // 한 면의 모든 라인에 대하여 for (int i = 0; i < numberClueFace.GetLength(0); ++i) { for (int j = 0; j < numberClueFace.GetLength(1); ++j) { // 해당 라인의 number clue 계산 var line = GetPuzzleLine(new lineIndex((FACE_TYPE)face, i, j), puzzle); var numberClue = CalculateNumberClue(line, puzzle); // 퍼즐에 기록 Puzzle.CLUE_SHAPE clueShape; switch (numberClue[1]) { case 1: case 0: clueShape = Puzzle.CLUE_SHAPE.NONE; break; case 2: clueShape = Puzzle.CLUE_SHAPE.CIRCLE; break; default: clueShape = Puzzle.CLUE_SHAPE.SQUARE; break; } numberClueFace[i, j] = new Puzzle.NumberClue(numberClue[0], clueShape); } } } }
// 주로 사용될 line solver 함수... 나머지 함수들은 거들 뿐 public List <PuzzleSolver.CELLSTATE> lineSolver(Puzzle.NumberClue clue, List <PuzzleSolver.puzzleIndex> line, PuzzleSolver.MyPuzzle myPuzzle) { int lineLen = line.Count; List <PuzzleSolver.CELLSTATE> result = new List <PuzzleSolver.CELLSTATE>(lineLen); if (clue.number == 0) { for (int i = 0; i < lineLen; ++i) { result.Add(PuzzleSolver.CELLSTATE.EMPTY); } return(result); } for (int i = 0; i < lineLen; ++i) { result.Add(PuzzleSolver.CELLSTATE.BLANK); } List <List <PuzzleSolver.CELLSTATE> > results = new List <List <PuzzleSolver.CELLSTATE> >(); List <List <int> > numberClueExpansions = expansionCache[(int)clue.shape, clue.number]; // leftMost와 rightMost를 구할 수 있는 모든 expansion들에 대해 풀어보고 모든 풀이의 공통점만 찾아서 반환하기 foreach (List <int> numberClue in numberClueExpansions) { List <Block> leftMost = new List <Block>(); List <Block> rightMost = new List <Block>(); leftMost = getLeftMostSolution(numberClue, line, true, myPuzzle); rightMost = getLeftMostSolution(numberClue, line, false, myPuzzle); if (leftMost.Count > 0 && rightMost.Count > 0) { List <PuzzleSolver.CELLSTATE> res = new List <PuzzleSolver.CELLSTATE>(lineLen); for (int i = 0; i < lineLen; ++i) { res.Add(myPuzzle.puzzleState[line[i].z, line[i].y, line[i].x]); } int blockLen = leftMost.Count; // 확실한 SOLID 결정 for (int i = 0; i < blockLen; ++i) { if (leftMost[i].end >= rightMost[i].start && leftMost[i].start <= rightMost[i].end) { int overlapCnt = leftMost[i].end - rightMost[i].start + 1; for (int j = 0; j < overlapCnt; ++j) { res[rightMost[i].start + j] = PuzzleSolver.CELLSTATE.SOLID; } } } // 확실한 EMPTY 결정 for (int cell = 0; cell < lineLen; ++cell) { bool empty = true; for (int i = 0; i < blockLen; ++i) { if (leftMost[i].start <= cell && cell <= rightMost[i].end) { empty = false; break; } } if (empty) { res[cell] = PuzzleSolver.CELLSTATE.EMPTY; } } results.Add(res); } } // 모든 result들을 대조해서 공통된 부분만 뽑아내기 int resultCount = results.Count; for (int i = 0; i < lineLen; ++i) { bool consistent = true; for (int j = 0; j < resultCount - 1; ++j) { if (results[j][i] != results[j + 1][i]) { consistent = false; break; } } if (consistent) { result[i] = results[0][i]; } } return(result); }