コード例 #1
0
        /// <summary>
        /// Filters a cell for a given edge filter
        /// </summary>
        /// <param name="edgeFilter">Edge filter</param>
        public void FilterCell(EdgeFilter edgeFilter)
        {
            //Debug.Log($"FilterCell({edgeFilter.EdgeIndex}, {edgeFilter.FilterType.ToString()})", gameObject);

            if (SolvedScore == 1)
            {
                return;
            }

            var removingModules = new List <int>();

            // Filter possible Modules list for a given filter
            for (int i = 0; i < possibleModulesIndices.Count; i++)
            {
                var module       = _moduleManager.modules[possibleModulesIndices[i]];
                var isImpossible = module.CheckModule(edgeFilter);

                if (isImpossible)
                {
                    // Remove module
                    removingModules.Add(possibleModulesIndices[i]);
                }
            }

            // Now remove filtered modules
            for (int i = 0; i < removingModules.Count; i++)
            {
                RemoveModule(removingModules[i]);
            }

            CheckSetCell();
        }
コード例 #2
0
        /// <summary>
        /// Initial constraint: There can only be border on the outside.
        /// </summary>
        private void BorderOutsideConstraint()
        {
            var bottomFilter = new EdgeFilter(2, Module.EdgeConnectionTypes.Block, true);
            var topFilter    = new EdgeFilter(0, Module.EdgeConnectionTypes.Block, true);
            var leftFilter   = new EdgeFilter(1, Module.EdgeConnectionTypes.Block, true);
            var rightFilter  = new EdgeFilter(3, Module.EdgeConnectionTypes.Block, true);

            // filter bottom and top cells for only border
            for (var i = 0; i < 2; i++)
            {
                var z = i * (height - 1);

                for (var x = 0; x < width; x++)
                {
                    cells[x, z].FilterCell(i == 0 ? bottomFilter : topFilter);
                }
            }

            // filter left and right cells for only border
            for (var i = 0; i < 2; i++)
            {
                var x = i * (width - 1);

                for (var z = 0; z < height; z++)
                {
                    cells[x, z].FilterCell(i == 0 ? leftFilter : rightFilter);
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// Initial constraint: There can only be border on the outside
        /// </summary>
        /// <param name="cells">The grid`s cells</param>
        private void BorderOutsideConstraint(ref Cell[,] cells)
        {
            var edgeTypes = (Module.EdgeConnectionTypes[])Enum.GetValues(typeof(Module.EdgeConnectionTypes));

            for (int i = 0; i < 2; i++)
            {
                i = (cells.GetLength(0) - 1) * i;

                for (int j = 0; j < cells.GetLength(1); j++)
                {
                    var cell = cells[i, j];

                    foreach (var edgeType in edgeTypes)
                    {
                        if (edgeType == Module.EdgeConnectionTypes.Block)
                        {
                            continue;
                        }

                        var edgeFilter = new EdgeFilter(i == 0 ? 1 : 3, edgeType);

                        cell.FilterCell(edgeFilter);
                    }
                }
            }

            for (int j = 0; j < 2; j++)
            {
                j = (cells.GetLength(1) - 1) * j;

                for (int i = 0; i < cells.GetLength(0); i++)
                {
                    var cell = cells[i, j];

                    foreach (var edgeType in edgeTypes)
                    {
                        if (edgeType == Module.EdgeConnectionTypes.Block)
                        {
                            continue;
                        }

                        var edgeFilter = new EdgeFilter(j == 0 ? 0 : 2, edgeType);

                        cell.FilterCell(edgeFilter);
                    }
                }
            }
        }
コード例 #4
0
        /// <summary>
        /// Checks if the removing module had the last edge type of any kind for this cell and if so populates the changes to the affected neighbour cell.
        /// Than removes module from <see cref="possibleModulesIndices"/>
        /// </summary>
        /// <param name="moduleIndex">Index of the removing module in <see cref="ModuleManager.modules"/></param>
        public void RemoveModule(int moduleIndex)
        {
            // Check module`s edge types
            var module = _moduleManager.modules[moduleIndex];

            // Remove module from possibility space
            possibleModulesIndices.Remove(moduleIndex);

            // Update item on the heap
            LevelGenerator.Instance.OrderedCells.UpdateItem(this);

            //Debug.Log($"{gameObject.name} | RemoveModule({module.moduleGO.name})", gameObject);

            for (int j = 0; j < 4; j++)
            {
                // Only check if cell has a neighbour on this edge
                if (neighbourCells[j] == null)
                {
                    continue;
                }

                var edgeType     = module.edgeConnections[j];
                var lastEdgeType = true;

                // Search in other possible modules for the same edge type
                for (int i = 0; i < possibleModulesIndices.Count; i++)
                {
                    if (_moduleManager.modules[possibleModulesIndices[i]].edgeConnections[j] == edgeType)
                    {
                        lastEdgeType = false;
                        break;
                    }
                }

                if (lastEdgeType)
                {
                    //Debug.Log($"{gameObject.name} | Last edge({j}, {edgeType.ToString()})", gameObject);

                    // Populate edge changes to neighbour cell
                    var edgeFilter = new EdgeFilter(j, edgeType);
                    neighbourCells[j].FilterCell(edgeFilter);
                }
            }

            CheckSetCell();
        }
コード例 #5
0
        /// <summary>
        /// Checks this module for a specific edge filter
        /// </summary>
        /// <param name="filter">The filter</param>
        /// <returns>Does this model depend on the given edge filter</returns>
        public bool CheckModule(EdgeFilter filter)
        {
            //Debug.Log($"Checking {moduleGO.name} for edge filter {filter.EdgeIndex}, {filter.FilterType}");

            // Get receiving edge index of this module
            var edge = filter.EdgeIndex + 2;

            if (edge == 4)
            {
                edge = 0;
            }
            else if (edge == 5)
            {
                edge = 1;
            }

            // Check if module matches a given filter
            return(edgeConnections[edge] == filter.FilterType);
        }
コード例 #6
0
        public void SetSpecialModule(int moduleIndex)
        {
            possibleModulesIndices = new List <int> {
                moduleIndex
            };

            var module = ModuleManager.Instance.modules[moduleIndex];

            // Update item on the heap
            LevelGenerator.Instance.OrderedCells.UpdateItem(this);

            var edgeTypes = (Module.EdgeConnectionTypes[])Enum.GetValues(typeof(Module.EdgeConnectionTypes));

            // Propagate changes to neighbours
            for (int i = 0; i < 4; i++)
            {
                if (neighbourCells[i] == null)
                {
                    continue;
                }

                for (int j = 0; j < edgeTypes.Length; j++)
                {
                    if (edgeTypes[j] != module.edgeConnections[i])
                    {
                        // This edge type was removed from this edge
                        // Populate edge changes to neighbour cell
                        var edgeFilter = new EdgeFilter(i, edgeTypes[j]);
                        neighbourCells[i].FilterCell(edgeFilter);
                    }
                }
            }

            var newModule = Instantiate(module.moduleGO, transform.position,
                                        Quaternion.identity, transform);

            isCellSet = true;
        }
コード例 #7
0
        /// <summary>
        /// Removes a <see cref="Module"/> from <see cref="possibleModules"/>
        /// checking if it was the last one on any edge of a specific edge type and
        /// if so propagating the changes to the affected neighbour.
        /// </summary>
        /// <param name="module">The <see cref="Module"/> to remove.</param>
        public void RemoveModule(Module module)
        {
            // remove module from possibility space
            possibleModules.Remove(module);

            // update item on the heap
            levelGenerator.orderedCells.UpdateItem(this);

            for (var j = 0; j < neighbours.Length; j++)
            {
                // only check if cell has a neighbour on this edge
                if (neighbours[j] == null)
                {
                    continue;
                }

                var edgeType         = module.edgeConnections[j];
                var lastWithEdgeType = true;

                // search in other possible modules for the same edge type
                for (var i = 0; i < possibleModules.Count; i++)
                {
                    if (possibleModules[i].edgeConnections[j] == edgeType)
                    {
                        lastWithEdgeType = false;
                        break;
                    }
                }

                if (lastWithEdgeType)
                {
                    // populate edge changes to neighbour cell
                    var edgeFilter = new EdgeFilter(j, edgeType, false);
                    neighbours[j].FilterCell(edgeFilter);
                }
            }
        }
コード例 #8
0
        /// <summary>
        /// Applies an <see cref="EdgeFilter"/> to this cell.
        /// </summary>
        /// <param name="filter">The filter to apply.</param>
        public void FilterCell(EdgeFilter filter)
        {
            if (possibleModules.Count == 1)
            {
                return;
            }

            var removingModules = new List <Module>();

            // filter possible modules list
            for (var i = 0; i < possibleModules.Count; i++)
            {
                if (filter.CheckModule(possibleModules[i]))
                {
                    removingModules.Add(possibleModules[i]);
                }
            }

            // remove filtered modules
            for (var i = 0; i < removingModules.Count; i++)
            {
                RemoveModule(removingModules[i]);
            }
        }