示例#1
0
        private static bool CheckSeveralMissingColumn(GridSquareScript selection, GridSquareScript[] gridSquares)
        {
            int col = GridMaths.ColumnForSquare(selection.Index);

            GridSquareScript[] emptyColSquares = EmptyGridsAtIndexes(GridMaths.GridColumnIndices(col), gridSquares, selection);
            int[] emptyIndices     = emptyColSquares.Select(x => x.Index).Distinct().ToArray();
            int[] bigSquareIndices = emptyColSquares.Select(x => GridMaths.BigSquareForSquare(x.Index)).Distinct().ToArray();

            List <int> usableSquares = new List <int>();

            for (int i = 0; i < bigSquareIndices.Length; i++)
            {
                int box = bigSquareIndices[i];
                if (!DoesBigSquareContainNumber(box, selection, gridSquares))
                {
                    int[] checks = emptyIndices.Intersect(GridMaths.GridColumnInSquare(col, box)).ToArray();
                    if (checks.Length > 0)
                    {
                        usableSquares.AddRange(checks);
                    }
                }
            }
            if (usableSquares.Count > 0)
            {
                return(usableSquares.All(x => DoesRowContainNumber(GridMaths.RowForSquare(x), selection, gridSquares)));
            }
            return(true);
        }
示例#2
0
        public GridSquareScript GetFtueTargetAtIndex(int index)
        {
            GridSquareScript target = TargetAtIndex(index);

            target.SetAsFtueTarget();
            return(target);
        }
示例#3
0
        /// <summary>
        /// Check, like the hash, but for numbers in boxes and cols/rows
        /// </summary>
        /// <param name="selection"></param>
        /// <param name="gridSquares"></param>
        /// <returns>True if this index is only available square for number in relation to number in big squares/cols/rows</returns>
        private static GridSolutionType CheckSeveralMissing(GridSquareScript selection, GridSquareScript[] gridSquares)
        {
            bool missingRow = CheckSeveralMissingRow(selection, gridSquares);
            bool missingCol = CheckSeveralMissingColumn(selection, gridSquares);

            print($"[CHECK] missing passed row: {missingRow} col: {missingCol}");
            return((missingRow || missingCol) ? GridSolutionType.SeveralMissing : GridSolutionType.None);
        }
 private void CreatorSquareSelected(GridSquareScript sender)
 {
     if (currentSelection != null && !currentSelection.Equals(sender))
     {
         currentSelection.DeselectCreatorSquare();
     }
     currentSelection = gridSquares[sender.Index];
 }
示例#5
0
 private static GridSquareScript[] GridsAtIndexes(int[] indexes, GridSquareScript[] gridSquares)
 {
     GridSquareScript[] grids = new GridSquareScript[indexes.Length];
     for (int i = 0; i < indexes.Length; i++)
     {
         if (gridSquares.Length > i && gridSquares[i] != null)
         {
             grids[i] = gridSquares[indexes[i]];
         }
     }
     return(grids);
 }
示例#6
0
 private static GridSquareScript[] EmptyGridsAtIndexes(int[] indexes, GridSquareScript[] gridSquares, GridSquareScript selection)
 {
     GridSquareScript[] grids = new GridSquareScript[indexes.Length];
     for (int i = 0; i < indexes.Length; i++)
     {
         if (gridSquares.Length > i && gridSquares[i] != null)
         {
             grids[i] = gridSquares[indexes[i]];
         }
     }
     return(grids.Where(x => x.Number == 0 || !selection.IsTarget).ToArray());
 }
示例#7
0
 public void SquareSelected(GridSquareScript sender)
 {
     if (!sender.Equals(currentSelection))
     {
         for (int i = 0; i < gridSquares.Length; i++)
         {
             gridSquares[i].ResetSquare();
         }
         currentSelection = TargetAtIndex(sender.Index);
         HighlightSquare(currentSelection.Index);
         print($"New selection!! {sender.Index}");
     }
 }
示例#8
0
        private static GridSolutionType OnlyAvailableNumberCheck(GridSquareScript selection, GridSquareScript[] gridSquares)
        {
            int row       = GridMaths.RowForSquare(selection.Index);
            int col       = GridMaths.ColumnForSquare(selection.Index);
            int bigSquare = GridMaths.BigSquareForSquare(selection.Index);

            int[] rowMissing = MissingNumbersInRow(gridSquares, row);
            int[] colMissing = MissingNumbersInColumn(gridSquares, col);
            int[] bigMissing = MissingNumbersInBigSquare(gridSquares, bigSquare);

            bool overlapCheck = rowMissing.Intersect(colMissing).Intersect(bigMissing).ToArray().Length == 0;

            print($"Only available row: {string.Join(",", rowMissing)} col; {string.Join(",", colMissing)} big; {string.Join(",", bigMissing)} ");

            return(overlapCheck ? GridSolutionType.SingleRule : GridSolutionType.None);
        }
示例#9
0
        public void InitGridWithRules(MainGameData gameData, Action <GridAnswer[]> completion)
        {
            rules       = gameData.Ruleset;
            gridSquares = tileContainer.GetComponentsInChildren <GridSquareScript>();
            targets     = new List <GridSquareScript>();
            //allSquares = new int[0];
            currentSelection   = null;
            completionCallback = completion;
            levelTitle.text    = $"LEVEL {gameData.Level}";
            int[] levelData = rules.levelData.Select(x => Int32.Parse(x.ToString())).ToArray();
            print($"Level data count: {levelData.Length}");

            if (levelData.Length == gridSquares.Length)
            {
                for (int i = 0; i < levelData.Length; i++)
                {
                    bool isTarget = rules.targetIndexes.Contains(i);
                    gridSquares[i].SetupGridSquare(i, levelData[i], isTarget, SquareSelected);
                    if (isTarget)
                    {
                        targets.Add(gridSquares[i]);
                    }
                }
            }
            keyboardController.SetKeyboardClickHandler(KeyboardInput);
            keyboardController.SetKeyboardEnabled(false);
            keyboardController.ShowKeyboard();
            if (gameData.answers != null)
            {
                GridAnswer[] errors   = gameData.answers.Where(x => x.correct == false).ToArray();
                GridAnswer[] corrects = gameData.answers.Where(x => x.correct == true).ToArray();
                if (errors.Length > 0)
                {
                    StartCoroutine(ShowPreviousErrors(errors, ShowNextTarget));
                    if (corrects.Length == 0)
                    {
                        return;
                    }
                }
                if (corrects.Length > 0)
                {
                    StartCoroutine(ShowPreviousCorrects(corrects));
                    return;
                }
            }
            ShowNextTarget();
        }
示例#10
0
        private IEnumerator ShowPreviousCorrects(GridAnswer[] corrects)
        {
            for (int i = 0; i < corrects.Length; i++)
            {
                GridSquareScript gridSquare = gridSquares[corrects[i].index];
                gridSquare.UpdateGridNumber(corrects[i].number);
                gridSquare.MarkSquareCorrect();
            }
            yield return(new WaitForSeconds(1.5f));

            for (int i = 0; i < corrects.Length; i++)
            {
                GridSquareScript gridSquare = gridSquares[corrects[i].index];
                gridSquare.ResetSquare();
            }
            yield return(new WaitForSeconds(0.25f));
        }
示例#11
0
        private static bool DoesSquareForceColumnNumber(int big, GridSquareScript selection, int col, GridSquareScript[] gridSquares)
        {
            print($"DoesSquare {big} ForceColumn {col} Number: {selection.Number}");
            bool numberCheck = DoesBigSquareContainNumber(big, selection, gridSquares);

            if (DoesBigSquareContainNumber(big, selection, gridSquares))
            {
                return(false);
            }
            int[] emptyIndices  = EmptyGridsAtIndexes(GridMaths.GridBigSquareIndices(big), gridSquares, selection).Select(x => x.Index).Distinct().ToArray();
            int[] noColIndices  = emptyIndices.Where(x => !DoesColumnContainNumber(GridMaths.ColumnForSquare(x), selection, gridSquares)).ToArray();
            int[] noRowIndices  = emptyIndices.Where(x => !DoesRowContainNumber(GridMaths.RowForSquare(x), selection, gridSquares)).ToArray();
            int[] forcedColumns = noColIndices.Intersect(noRowIndices).Select(GridMaths.ColumnForSquare).Distinct().ToArray();

            print($"Empty indices in square {big} = {string.Join(",", emptyIndices)} - no col indices ({string.Join(",", noColIndices)})  no row indices ({string.Join(",", noRowIndices)}) = {string.Join(",", forcedColumns)} =  {col}");
            return(forcedColumns.Length == 1 && forcedColumns[0] == col);
        }
示例#12
0
        private GridAnswer[] ValidateTargets()
        {
            List <GridAnswer> answers = new List <GridAnswer>();

            for (int i = 0; i < targets.Count; i++)
            {
                GridSquareScript target  = targets[i];
                bool             correct = GridSolver.SolveGridAtIndex(gridSquares, target) != GridSolutionType.None;
                target.MarkSquareComplete(); //MarkSquareIncorrect();
                print($"Target {target.Index} ({target.Number}) is correct? {correct}");
                answers.Add(new GridAnswer
                {
                    index   = target.Index,
                    number  = target.Number,
                    correct = correct
                });
            }
            return(answers.ToArray());
        }
示例#13
0
        private IEnumerator ShowPreviousErrors(GridAnswer[] errors, Action completion)
        {
            for (int i = 0; i < errors.Length; i++)
            {
                GridSquareScript gridSquare = gridSquares[errors[i].index];
                gridSquare.UpdateGridNumber(errors[i].number);
                gridSquare.MarkSquareIncorrect();
            }
            yield return(new WaitForSeconds(1.5f));

            for (int i = 0; i < errors.Length; i++)
            {
                GridSquareScript gridSquare = gridSquares[errors[i].index];
                gridSquare.UpdateGridNumber(0);
                gridSquare.ResetSquare();
            }
            yield return(new WaitForSeconds(0.25f));

            completion?.Invoke();
        }
示例#14
0
        /// <summary>
        /// Simple overlap check to duplicate numbers in the same row, column or big square
        /// </summary>
        /// <param name="number"></param>
        /// <param name="index"></param>
        /// <param name="gridSquares"></param>
        /// <returns>True if no duplicate numbers for the selected index</returns>
        private static bool SingleRuleCheck(GridSquareScript selection, GridSquareScript[] gridSquares)
        {
            int row       = GridMaths.RowForSquare(selection.Index);
            int col       = GridMaths.ColumnForSquare(selection.Index);
            int bigSquare = GridMaths.BigSquareForSquare(selection.Index);
            //print($"Grid - keyboard number: {number} on square: {index}");
            bool existsInRow = DoesRowContainNumber(row, selection, gridSquares);
            bool existsInCol = DoesColumnContainNumber(col, selection, gridSquares);
            bool existsInBig = DoesBigSquareContainNumber(bigSquare, selection, gridSquares);
            bool failed      = existsInRow || existsInCol || existsInBig;

            if (!existsInRow &&
                !existsInCol &&
                !existsInBig)
            {
                //TODO add check for only number
            }
            print($"[CHECK] Simple overlap test: row: {existsInRow} col: {existsInCol} big: {existsInBig} => {failed}");
            return(failed);
        }
示例#15
0
        private static int[] GridEmptyIntersectIndices(GridSquareScript[] gridSquares, GridSquareScript selection)
        {
            int square = GridMaths.BigSquareForSquare(selection.Index);

            GridSquareScript[] emptySquares = EmptyGridsAtIndexes(GridMaths.GridBigSquareIndices(square), gridSquares, selection);
            int[] emptyIndices = EmptyGridsAtIndexes(GridMaths.GridBigSquareIndices(square), gridSquares, selection).Select(x => x.Index).Distinct().ToArray();

            //check how many row are in the empty indicies
            int[] emptyCols        = emptyIndices.Where(x => !DoesColumnContainNumber(GridMaths.ColumnForSquare(x), selection, gridSquares)).ToArray();
            int[] emptyRows        = emptyIndices.Where(x => !DoesRowContainNumber(GridMaths.RowForSquare(x), selection, gridSquares)).ToArray();
            int[] intersectIndices = emptyCols.Intersect(emptyRows).ToArray();
            print($"GridEmptyIntersectIndices: ({string.Join(",", emptyIndices)}) empty rows: {string.Join(",", emptyRows)} cols: {string.Join(",", emptyCols)} intersect: {string.Join(",", intersectIndices)}");
            return(emptyCols.Intersect(emptyRows).ToArray());
        }
示例#16
0
 /// <summary>
 /// Check for if number is present in other columns or rows to rule out other positions so only one available position
 /// </summary>
 /// <param name="selection"></param>
 /// <param name="gridSquares"></param>
 /// <returns>True if this index is only available square for number in relation to number in cols/rows outside of big square </returns>
 private static GridSolutionType OnlyAvailableSquareHashCheck(GridSquareScript selection, GridSquareScript[] gridSquares)
 {
     return(GridEmptyIntersectIndices(gridSquares, selection).Length == 0 ? GridSolutionType.OnlyAvailable : GridSolutionType.None);
 }
示例#17
0
 private static bool DoesBigSquareContainNumber(int big, GridSquareScript selection, GridSquareScript[] gridSquares)
 {
     GridSquareScript[] bigSquareSquares = GridsAtIndexes(GridMaths.GridBigSquareIndices(big), gridSquares);
     return(bigSquareSquares.Any(x => x.Number == selection.Number && !x.IsTarget)); //x.Index != selection.Index);
 }
示例#18
0
 private static bool DoesColumnContainNumber(int col, GridSquareScript selection, GridSquareScript[] gridSquares)
 {
     GridSquareScript[] colSquares = GridsAtIndexes(GridMaths.GridColumnIndices(col), gridSquares);
     return(colSquares.Any(x => x.Number == selection.Number && !x.IsTarget));//x.Index != selection.Index);
 }
示例#19
0
 private static bool DoesRowContainNumber(int row, GridSquareScript selection, GridSquareScript[] gridSquares)
 {
     GridSquareScript[] rowSquares = GridsAtIndexes(GridMaths.GridRowIndices(row), gridSquares);
     return(rowSquares.Any(x => x.Number == selection.Number && !x.IsTarget));//&& x.Index != selection.Index);
 }
示例#20
0
        private static GridSolutionType CheckDoubleDeduction(GridSquareScript[] gridSquares, GridSquareScript selection)
        {
            int[] intersectIndices = GridEmptyIntersectIndices(gridSquares, selection);
            int[] missingRows      = intersectIndices.Select(GridMaths.RowForSquare).Where(x => x != GridMaths.RowForSquare(selection.Index)).Distinct().ToArray();
            int[] missingCols      = intersectIndices.Select(GridMaths.ColumnForSquare).Where(x => x != GridMaths.ColumnForSquare(selection.Index)).Distinct().ToArray();
            print($"Intersect indices: {string.Join(", ", intersectIndices)} Missing rows: {string.Join(", ", missingRows)} cols: {string.Join(", ", missingCols)}");

            int forceRowCount = 0;
            int big           = GridMaths.BigSquareForSquare(selection.Index);

            for (int i = 0; i < missingRows.Length; i++)
            {
                int[] otherBigRows = GridMaths.OtherBigSquaresForRow(missingRows[i], big);
                for (int j = 0; j < otherBigRows.Length; j++)
                {
                    if (DoesSquareForceRowNumber(otherBigRows[j], selection, missingRows[i], gridSquares))
                    {
                        forceRowCount += 1;
                    }
                }
            }

            int forceColCount = 0;

            for (int i = 0; i < missingCols.Length; i++)
            {
                int[] otherBigCols = GridMaths.OtherBigSquaresForColumn(missingCols[i], big);
                for (int j = 0; j < otherBigCols.Length; j++)
                {
                    if (DoesSquareForceColumnNumber(otherBigCols[j], selection, missingCols[i], gridSquares))
                    {
                        forceColCount += 1;
                    }
                }
            }
            print($"[CHECK] Double deduction: Forced rows: {missingRows.Length} = {forceRowCount} && cols: {missingCols.Length} = {forceColCount} check: {forceColCount == missingCols.Length && forceRowCount == missingRows.Length}");
            return((forceColCount == missingCols.Length && forceRowCount == missingRows.Length) ? GridSolutionType.DoubleDeduction : GridSolutionType.None);
        }
示例#21
0
 public bool ValidateFtueTarget(GridSquareScript target)
 {
     return(GridSolver.SolveGridAtIndex(gridSquares, target) != GridSolutionType.None);
 }
示例#22
0
        //enum GridSolutionType
        //{
        //    None = 0,
        //    SingleRow = 1,
        //    SingleColumn = 2,
        //    SingleSquare = 3,
        //    CompleteRow = 4,
        //    CompleteColumn = 5,
        //    CompleteSquare = 6,
        //    OnlyAvailable = 7,
        //    NakedSingle = 8,
        //    SeveralMissingRow = 9,
        //    SeveralMissingColumn = 10,
        //    DoubleDeduction = 11
        //}

        #region - Public API
        public static GridSolutionType SolveGridAtIndex(GridSquareScript[] gridSquares, GridSquareScript selection)
        {
            if (SingleRuleCheck(selection, gridSquares))
            {
                return(GridSolutionType.None);
            }
            GridSolutionType check = SimpleCompletionCheck(selection.Index, gridSquares);

            if (check != GridSolutionType.None)
            {
                return(check);
            }
            check = OnlyAvailableNumberCheck(selection, gridSquares);
            if (check != GridSolutionType.None)
            {
                return(check);
            }
            check = OnlyAvailableSquareHashCheck(selection, gridSquares);
            if (check != GridSolutionType.None)
            {
                return(check);
            }
            check = CheckForNakedSingle(selection.Index, gridSquares);
            if (check != GridSolutionType.None)
            {
                return(check);
            }
            check = CheckSeveralMissing(selection, gridSquares);
            if (check != GridSolutionType.None)
            {
                return(check);
            }
            check = CheckDoubleDeduction(gridSquares, selection);
            if (check != GridSolutionType.None)
            {
                return(check);
            }
            return(GridSolutionType.None);
        }