Пример #1
0
    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);
                }
            }
        }
    }
Пример #2
0
    // 주로 사용될 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);
    }