/// <summary> /// 해결하기 위한 유효한 스도쿠 보드를 생성합니다. /// </summary> /// <param name="sudokuDifficulty">생성된 스도쿠의 난이도</param> public SudokuRow[] GenerateSudoku(SudokuDifficultyType sudokuDifficulty) { sudokuTransformer.ShuffleSudoku(generatedSudokuBoard); for (int i = 0; i < 9; i++) { generatedSudokuBoard[i].CopyTo(sudokuBoardForPlayer[i], 0); } sudokuTransformer.EraseCells(sudokuBoardForPlayer, sudokuDifficulty); return(SudokuUtils.GenerateSudokuGridFromBoard(sudokuBoardForPlayer)); }
/// <summary> /// 유효한 스도쿠에서 난이도에 알맞게 셀을 삭제하여 플레이어가 해결할 수 있도록 합니다. /// </summary> /// <param name="sudokuBoard">9*9 가변 배열</param> public void EraseCells(byte[][] sudokuBoard, SudokuDifficultyType sudokuDifficulty) { if (!SudokuUtils.IsSudokuBoardValid(sudokuBoard)) { throw new ArgumentException(InvalidSudokuBoardMessage); } // 지울 셀의 개수를 0으로 초기화 int cellsToErase = 0; // 지울 셀의 개수를 난이도에 따라 지정 if (sudokuDifficulty == SudokuDifficultyType.데모) { cellsToErase = CellsToEraseOnDemo; } if (sudokuDifficulty == SudokuDifficultyType.Easy) { cellsToErase = CellsToEraseOnEasyDifficulty; } else if (sudokuDifficulty == SudokuDifficultyType.Medium) { cellsToErase = CellsToEraseOnMediumDifficulty; } else if (sudokuDifficulty == SudokuDifficultyType.Hard) { cellsToErase = CellsToEraseOnHardDifficulty; } else if (sudokuDifficulty == SudokuDifficultyType.Expert) { cellsToErase = CellsToEraseOnImpossibleDifficulty; } else if (sudokuDifficulty == SudokuDifficultyType.Custom) { cellsToErase = CustomMode; } else { cellsToErase = 20; // 오류 발생시 빈칸 20개 뚫기 (Demo 와 Easy 사이 난이도) } // 셀 지우는 방법: // 1. 행에서 시스템의 Random() 함수로 선택된 셀을 지운다. // 2. 반 대각선 (Minor Diagonal) 에 있는 셀을 지운다. // 3. 반복한다. while (cellsToErase > 0) { // 0 부터 8 까지의 행, 1씩 증가 for (int row = 0; row < 9; row++) { // 최소 0, 최대 9 의 열 중 하나를 선택 (시스탬이 Random() 함수로 선택) int col = random.Next(0, 9); if (sudokuBoard[row][col] != 0) // 선택받은 (?) sudokuBoard[행][열] 이 0이 아니라면 (빈칸이 아니라면) { sudokuBoard[row][col] = 0; // 빈칸으로 전환 cellsToErase--; // 지울 셀의 개수 - 1 } if (cellsToErase <= 0) // 지울 셀의 개수가 0 이하가 되면 { return; // 멈춤 } int oppositeRow = 9 - col - 1; // 반대편 행 선택 int oppositeCol = 9 - row - 1; // 반대편 열 선택 if (sudokuBoard[oppositeRow][oppositeCol] != 0) // sudokuBoard[반대편 행][반대편 열] 이 0이 아니라면 (빈칸이 아니라면) { sudokuBoard[oppositeRow][oppositeCol] = 0; // 빈칸으로 전환 cellsToErase--; // 지울 셀의 개수 - 1 } if (cellsToErase <= 0) // 지울 셀의 개수가 0 이하가 되면 { return; // 멈춤 } } } }