public void SetFillReason(int slotIndex, int value, FillReason reason) { _targetSlotIndex = slotIndex; SudokuUtility.ConvertToIndex(slotIndex, out int rowIndex, out int columnIndex, out int _); _text.text = string.Format("Solution {0} found at Row {1}, Column {2} by {3} method", value, rowIndex, columnIndex, GetReasonString(reason), slotIndex); }
private async void OnSudokuDataInputChanged() { if (SudokuUtility.IsSudokuDataComplete(_sData)) { _isResolving = false; UIWindowCongratulations window = await UIWindowManager.Instance.GetWindow(SystemDefine.UI_WINDOW_NAME_CONGRATULATIONS) as UIWindowCongratulations; await window.Show(true, true); window.PlayAnimation(); } }
private bool TryToFindNextStep() { _sData.Update(); SolutionInfo solution = SudokuUtility.FindSolution(_sData); if (solution != null) { FillSolutionIntoSlot(solution.SlotData.SlotIndex, solution.Value, solution.Reason); return(true); } return(false); }
public bool FillAllSolution() { if (!IsSolvable()) { return(false); } while (this.HasEmptySlot()) { SolutionInfo solution = SudokuUtility.FindSolution(this); SetSlotValueAndReason(solution.SlotData.SlotIndex, solution.Value, FillReason.PlayerInput); Update(); } return(true); }
/// <summary> /// per ogni cella, rimuove tra gli AllowableValues i valori già presenti nella colonna /// </summary> /// <param name="game"></param> /// <returns>'true' se ha operato almeno un'azione</returns> protected bool useColumnConstraint(SudokuGame game) { bool atLeastOneOperation = false; for (int colIndex = 0; colIndex < game.GameMatrix.Count; ++colIndex) { List <SudokuCell> column = SudokuUtility.getMatrixSubSpace(game, new MatrixCoords { TopologyType = SpaceType.COLUMN, COLUMN = colIndex }); bool atLeastOneOperationInColumn = false; atLeastOneOperationInColumn = useConstraintOnGenericSpace(column); atLeastOneOperation |= atLeastOneOperationInColumn; } return(atLeastOneOperation); }
/// <summary> /// per ogni cella, rimuove tra gli AllowableValues i valori già presenti nella riga /// </summary> /// <param name="game"></param> /// <returns>'true' se ha operato almeno un'azione</returns> protected bool useRowConstraint(SudokuGame game) { bool atLeastOneOperation = false; for (int rowIndex = 0; rowIndex < game.GameMatrix.Count; ++rowIndex) { List <SudokuCell> row = SudokuUtility.getMatrixSubSpace(game, new MatrixCoords { TopologyType = SpaceType.ROW, ROW = rowIndex }); bool atLeastOneOperationInRow = false; atLeastOneOperationInRow = useConstraintOnGenericSpace(row); atLeastOneOperation |= atLeastOneOperationInRow; } return(atLeastOneOperation); }
public bool IsSolvable() { SudokuData cloneData = GetClone(); cloneData.Update(); while (cloneData.HasEmptySlot()) { SolutionInfo solution = SudokuUtility.FindSolution(cloneData); if (solution == null) { return(false); } cloneData.SetSlotValueAndReason(solution.SlotData.SlotIndex, solution.Value, FillReason.None); cloneData.Update(); } return(true); }
/// <summary> /// per ogni cella, rimuove tra gli AllowableValues i valori già presenti nel rispettivo box /// </summary> /// <param name="game"></param> /// <returns>'true' se ha operato almeno un'azione</returns> protected bool useBoxConstraint(SudokuGame game) { bool atLeastOneOperation = false; for (int boxRowIndex = 0; boxRowIndex < SudokuUtility.DEFAULT_OUTERBOX_SIZE; ++boxRowIndex) { for (int boxColIndex = 0; boxColIndex < SudokuUtility.DEFAULT_OUTERBOX_SIZE; ++boxColIndex) { List <SudokuCell> box = SudokuUtility.getMatrixSubSpace(game, new MatrixCoords { TopologyType = SpaceType.BOX, ROW = boxRowIndex * 3, COLUMN = boxColIndex * 3 }); bool atLeastOneOperationInBox = false; atLeastOneOperationInBox = useConstraintOnGenericSpace(box); atLeastOneOperation |= atLeastOneOperationInBox; } } return(atLeastOneOperation); }
public void RefreshDisplay() { _textValue.color = SudokuUtility.GetFillReasonColor(_reason); _textValue.text = _value == 0 ? string.Empty : string.Format("{0}", _value); }
public void SetSlotValueAndReason(int rowIndex, int columnIndex, int value, FillReason reason) { int slotIndex = SudokuUtility.ConvertToSlotIndex(rowIndex, columnIndex); SetSlotValueAndReason(slotIndex, value, reason); }
public SlotData GetSlotData(int rowIndex, int columnIndex) { int slotIndex = SudokuUtility.ConvertToSlotIndex(rowIndex, columnIndex); return(GetSlotData(slotIndex)); }
public static SolutionInfo FindByExclusion(SudokuData sData) { ///////////////////////////////////////////////////////// // Method : 排除法, 已填了數字的欄位, // // 與該數字同行同列的位置不會再出現同樣的數字 // ///////////////////////////////////////////////////////// // 需要建立該數字已出現在那行那列的資料 // 檢查 1 ~ 9, 在每個九宮格中的 "可能出現位置" 是不是只剩下一個 ? for (int i = 0; i < PUZZLE_LENGTH; i++) { // For 1 ~ 9 int checkNumber = i + 1; // NOTE: 若某一個數字在一個九宮格的可能出現欄位在同一行 or 列上 // 則可以視為此行 or 列必定有一個該數字, 進而排除其他欄位 bool recheck = true; List <int> tempRow = new List <int>(); List <int> tempColumn = new List <int>(); while (recheck) { recheck = false; for (int squareIndex = 0; squareIndex < PUZZLE_LENGTH; squareIndex++) { // For 每一個九宮格 if (SudokuUtility.IsNumberContainedInSquare(sData, checkNumber, squareIndex)) { continue; } // For 九宮格裡的每一小格 List <SlotData> fillableSlot = new List <SlotData>(); int squareStartIndex = (squareIndex % SQUARE_LENGTH) * SQUARE_LENGTH + (squareIndex / SQUARE_LENGTH) * PUZZLE_LENGTH * SQUARE_LENGTH; // 該九宮格的起始點(左上)的 Slot 的 Index, 用 0 ~ 80 表示 for (int j = 0; j < PUZZLE_LENGTH; j++) { int slotIndex = squareStartIndex + (j % SQUARE_LENGTH) + ((j / SQUARE_LENGTH) * PUZZLE_LENGTH); // 該九宮格的目標點位置, 用 0 ~ 80 表示 SlotData slotData = sData.SlotDataList[slotIndex]; if (slotData.Value != 0) { continue; } if (IsNumberContainedInRow(sData, checkNumber, slotData.RowIndex)) { continue; } if (tempRow.Contains(slotData.RowIndex)) { continue; } if (IsNumberContainedInColumn(sData, checkNumber, slotData.ColumnIndex)) { continue; } if (tempColumn.Contains(slotData.ColumnIndex)) { continue; } fillableSlot.Add(slotData); } if (fillableSlot.Count == 0) { // Do nothing } else if (fillableSlot.Count == 1) { return(new SolutionInfo { SlotData = fillableSlot[0], Reason = FillReason.SlotExclude, Value = checkNumber }); } else { if (SudokuUtility.IsSlotSameRow(fillableSlot)) { // 若這些候補 Slot 位置剛好在同一行上 tempRow.Add(fillableSlot[0].RowIndex); recheck = true; } else if (SudokuUtility.IsSlotSameColumn(fillableSlot)) { // 若這些候補 Slot 位置剛好在同一列上 tempColumn.Add(fillableSlot[0].ColumnIndex); recheck = true; } } } } } return(null); }
private void FillSolutionIntoSlot(int slotIndex, int value, FillReason reason) { SudokuUtility.ConvertToIndex(slotIndex, out int rowIndex, out int columnIndex, out int _); FillSolutionIntoSlot(rowIndex, columnIndex, value, reason); }