private bool fillOnlyOneElement(Definition.GridLine gridLine)
        {
            //get empty element
            Definition.Element emptyElement = null;
            using (var e = gridLine.Elements
                           .Where(item => !item.HasValue)
                           .GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    return(true);                               //not empty element
                }
                emptyElement = e.Current;
                if (e.MoveNext())
                {
                    return(false);                              //more than one empty element
                }
            }

            var lineType = gridLine.LineType;

            //get two other grids
            var currentGrid = gridLine.Grid;

            Definition.Grid otherGrid1, otherGrid2;
            currentGrid.GetOtherGrids(lineType, out otherGrid1, out otherGrid2);

            int currentLineIndex = gridLine.Index;

            var otherElementValues1 = otherGrid1.GetElementsInOtherGridLine(currentLineIndex, lineType)
                                      .Values();

            var otherElementValues2 = otherGrid2.GetElementsInOtherGridLine(currentLineIndex, lineType)
                                      .Values();

            var currentElementValues = currentGrid.Elements
                                       .Values();

            var exceptResult = otherElementValues1
                               .Concat(otherElementValues2)
                               .Except(currentElementValues);

            if (!exceptResult.Any())
            {
                return(false);                //no result
            }
            //get value which appeared both
            var bothOtherElementValues      = otherElementValues1.Intersect(otherElementValues2);
            var exactIntersectElementValues = bothOtherElementValues.Intersect(exceptResult);

            int value = exactIntersectElementValues.SingleOrDefault(-1);

            if (value > 0)
            {
                filling(emptyElement, value);
                emptyElement.SetValue(value);
                return(true);
            }
            return(false);
        }
 /// <summary>
 /// log
 /// </summary>
 protected void filling(Definition.Element element, int value)
 {
     //Console.WriteLine("{0, -30}: ({1}, {2}) - {3}",
     //	this.name,
     //	element.GridIndex + 1,
     //	element.Index + 1,
     //	value);
 }
            public bool NextEmptyElement(Definition.Grid grid, out Definition.Element element)
            {
                if (grid == null)
                {
                    throw new ArgumentNullException("grid");
                }

                element = null;

                int nextIndex = 0;

                lock (this.mapLock)
                {
                    var gridElementMap = this.gridElementMap;
                    if (!gridElementMap.TryGetValue(grid, out nextIndex))
                    {
                        for (int i = 0; i < 9; i++)
                        {
                            var item = grid.Elements[i];
                            if (!item.HasValue)
                            {
                                gridElementMap.Add(grid, i + 1);
                                element = item;
                                return(true);
                            }
                        }
                        return(false);
                    }
                    else
                    {
                        for (int i = nextIndex; i < 9; i++)
                        {
                            var item = grid.Elements[i];
                            if (!item.HasValue)
                            {
                                gridElementMap[grid] = i + 1;
                                element = item;
                                return(true);
                            }
                        }
                        return(false);
                    }
                }
            }
Example #4
0
        private bool fillOnlyOneElement(IEnumerable <Definition.Element> elements)
        {
            if (elements == null)
            {
                throw new ArgumentNullException("elements");
            }

            //get empty element
            Definition.Element emptyElement = null;
            using (var e = elements
                           .Where(item => !item.HasValue)
                           .GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    return(true);                               //not empty element
                }
                emptyElement = e.Current;
                if (e.MoveNext())
                {
                    return(false);                              //more than one empty element
                }
            }

            int value = 1;

            foreach (int element in elements
                     .Where(item => item.HasValue)
                     .OrderBy(item => item))
            {
                if (element != value)
                {
                    break;
                }
                value++;
            }
            filling(emptyElement, value);
            emptyElement.SetValue(value);

            return(true);
        }
        private bool fillAnyEmptyElement(Definition.Grid grid, Definition.Element emptyElement)
        {
            if (emptyElement.HasValue)
            {
                return(false);
            }

            //get two other grids in same row
            Definition.Grid otherGridInRow1, otherGridInRow2;
            grid.GetOtherGrids(Definition.LineType.Row, out otherGridInRow1, out otherGridInRow2);

            //get two other grids in same column
            Definition.Grid otherGridInColumn1, otherGridInColumn2;
            grid.GetOtherGrids(Definition.LineType.Column, out otherGridInColumn1, out otherGridInColumn2);

            int elementIndex    = emptyElement.Index;
            int rowLineIndex    = elementIndex / 3;
            int columnLineIndex = elementIndex % 3;

            var otherGridInRow1Values = otherGridInRow1
                                        .GetElementsInOtherGridLine(rowLineIndex, Definition.LineType.Row)
                                        .Values();
            var otherGridInRow2Values = otherGridInRow2
                                        .GetElementsInOtherGridLine(rowLineIndex, Definition.LineType.Row)
                                        .Values();
            var otherGridInColumn1Values = otherGridInColumn1
                                           .GetElementsInOtherGridLine(columnLineIndex, Definition.LineType.Column)
                                           .Values();
            var otherGridInColumn2Values = otherGridInColumn2
                                           .GetElementsInOtherGridLine(columnLineIndex, Definition.LineType.Column)
                                           .Values();

            var currentElementValues = grid.Elements
                                       .Values();

            var exceptResult = otherGridInRow1Values
                               .Concat(otherGridInRow2Values)
                               .Concat(otherGridInColumn1Values)
                               .Concat(otherGridInColumn2Values)
                               .Except(currentElementValues);

            if (!exceptResult.Any())
            {
                return(false);                //no result
            }
            //get value which appeared both
            var bothOtherElementValues = otherGridInRow1Values
                                         .Intersect(otherGridInRow2Values)
                                         .Intersect(otherGridInColumn1Values)
                                         .Intersect(otherGridInColumn2Values);
            var exactIntersectElementValues = bothOtherElementValues.Intersect(exceptResult);

            int value = exactIntersectElementValues.SingleOrDefault(-1);

            if (value > 0)
            {
                filling(emptyElement, value);
                emptyElement.SetValue(value);
                return(true);
            }
            return(false);
        }
        private bool fillOnlyOneElement(Definition.GridLine gridLine)
        {
            //get empty element
            Definition.Element emptyElement = null;
            using (var e = gridLine.Elements
                           .Where(item => !item.HasValue)
                           .GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    return(true);                               //not empty element
                }
                emptyElement = e.Current;
                if (e.MoveNext())
                {
                    return(false);                              //more than one empty element
                }
            }

            var lineType = gridLine.LineType;

            //get two other grids
            var currentGrid = gridLine.Grid;

            Definition.Grid otherGrid1, otherGrid2;
            currentGrid.GetOtherGrids(lineType, out otherGrid1, out otherGrid2);

            int currentLineIndex = gridLine.Index;

            var grid1Completed = otherGrid1
                                 .GetElementsInCurrentGridLine(currentLineIndex, lineType)
                                 .AllHasValue();
            var grid2Completed = otherGrid2
                                 .GetElementsInCurrentGridLine(currentLineIndex, lineType)
                                 .AllHasValue();

            //only when one other grid line is completed
            if (grid1Completed == grid2Completed)
            {
                return(false);
            }

            var targetGrid = grid1Completed ? otherGrid2 : otherGrid1;

            //if one of seats value appeared in target grid, fill to complete
            var seatValues = new LineEnumerable(this.sudoku, lineType)
                             //.ElementAt(currentLineIndex) //should get sudoku line index here
                             .ElementAt(getSudokuLineIndex(currentLineIndex, currentGrid.Index, lineType))
                             .Elements
                             .Values()
                             .SudokuExcept();
            var intersectResults = targetGrid.Elements.Values()
                                   .Except(currentGrid.Elements.Values())
                                   .Intersect(seatValues);

            int value = intersectResults.SingleOrDefault(-1);

            if (value > 0)
            {
                filling(emptyElement, value);
                emptyElement.SetValue(value);
                return(true);
            }
            return(false);
        }