Esempio n. 1
0
    /// <summary>
    /// Generates a board to play with
    /// </summary>
    public void CreateBoard()
	{
		matrix = new Cell[this.numTiles, this.numTiles];
        heroList = new List<Hero>();
        charInstances = new Dictionary<Guid, GameObject>();
        cellInstances = new Dictionary<Guid, GameObject>();
		boardHolder = this.transform;


        bool foundSolution = false;
        List<Assignment> assignments = new List<Assignment>();
        while (!foundSolution)
        {
            matrix = InitializeBoard(matrix);

            matrix = GenerateRandomTiles(matrix);

            //Create a CSP to fill the remaining data
            List<Variable> vars = ConvertMatrixToVars(matrix);
            List<OverFloorType> values = Enum.GetValues(typeof(OverFloorType)).OfType<OverFloorType>().Where(o => Convert.ToInt32(o) >= 0).ToList();
            CSP problem = new CSP(vars, values, toleranceFW, toleranceFM);
            //Use recursive backtracking to get a solution
            assignments = Search.RecursiveBacktrackingSearch(problem);
            if (assignments != null)
                foundSolution = true;
        }

        //Loop assignments
        foreach (var ass in assignments)
        {
            int x = (int)ass.variable.pos.x;
            int y = (int)ass.variable.pos.y;
            matrix[x,y].overFloor = ass.value;
            CreateTile(new Vector3(ass.variable.pos.x, ass.variable.pos.y), ass.value);
        }

        //Initialize heroes
        matrix = GenerateRandomHeroes(matrix);
        //Loop heroes to render
        foreach (var hero in heroList)
        {
            CreateHero(hero.Position, hero);
        }

        
    }
Esempio n. 2
0
        /// <summary>
        /// Loop all variables and values searching for a solution for the CSP
        /// </summary>
        /// <param name="problem"></param>
        /// <returns></returns>
        public static List <Assignment> RecursiveBacktrackingSearch(CSP problem)
        {
            if (problem.Goal())
            {
                Debug.Log("Goal completed!");
                return(problem.GetAssignments());
            }
            //Loop unassigned
            var orderedVars = problem.OrderVariablesByMinimumRemainingValues();

            foreach (var variable in orderedVars)
            {
                Debug.Log("Variable evaluated:" + variable.pos.ToString());
                var orderedAssignments = problem.OrderAssignmentsByLeastRestrictingValues(variable);
                foreach (var assign in orderedAssignments)
                {
                    Debug.Log("Value evaluated:" + assign.value.ToString());
                    //Assign value
                    bool validResult = problem.AssignValue(assign.variable, assign.value);
                    if (!validResult)
                    {
                        throw new Exception("Error getting available values");
                    }
                    List <Assignment> validAssignments = null;
                    validAssignments = RecursiveBacktrackingSearch(new CSP(problem));
                    if (validAssignments != null)
                    {
                        return(validAssignments);
                    }
                    else
                    {
                        Debug.Log("Backtracking value:" + assign.value.ToString());
                        problem.RemoveValue(assign.variable);
                    }
                }
            }
            Debug.Log("Backtracking");
            return(null);
        }
Esempio n. 3
0
 public CSP(CSP cspToBeCopied)
 {
     this.vars = new List <Variable>();
     cspToBeCopied.vars.ForEach(v => this.vars.Add(new Variable(v.pos, v.val, v.remDomain)));
     this.domain     = cspToBeCopied.domain.ToList();
     this.neighbours = new Dictionary <Vector2, List <Variable> >();
     foreach (var key in cspToBeCopied.neighbours.Keys)
     {
         var listNeigh = new List <Variable>();
         foreach (var neighSour in cspToBeCopied.neighbours[key])
         {
             var variableDest = this.vars.First(v => v.pos == neighSour.pos);
             listNeigh.Add(variableDest);
         }
         this.neighbours[key] = listNeigh;
     }
     this.assignments = new List <Assignment>();
     foreach (var ass in cspToBeCopied.assignments)
     {
         var variableDest = this.vars.First(v => v.pos == ass.variable.pos);
         var assignDest   = new Assignment(variableDest, ass.value);
         assignDest.domainPrune = new Dictionary <Vector2, List <OverFloorType> >();
         foreach (var domPruneKey in ass.domainPrune.Keys)
         {
             var listOfdomainprune = new List <OverFloorType>();
             foreach (var valuePruned in ass.domainPrune[domPruneKey])
             {
                 listOfdomainprune.Add(valuePruned);
             }
             assignDest.domainPrune[domPruneKey] = listOfdomainprune;
         }
         this.assignments.Add(assignDest);
     }
     this.toleranceFM = cspToBeCopied.toleranceFM;
     this.toleranceFW = cspToBeCopied.toleranceFW;
     this.MAC3        = cspToBeCopied.MAC3;
 }
Esempio n. 4
0
 public CSP(CSP cspToBeCopied)
 {
     this.vars = new List<Variable>();
     cspToBeCopied.vars.ForEach(v=>this.vars.Add(new Variable(v.pos,v.val,v.remDomain)));
     this.domain = cspToBeCopied.domain.ToList();
     this.neighbours = new Dictionary<Vector2, List<Variable>>();
     foreach (var key in cspToBeCopied.neighbours.Keys)
     {
         var listNeigh = new List<Variable>();
         foreach (var neighSour in cspToBeCopied.neighbours[key])
         {
             var variableDest = this.vars.First(v => v.pos == neighSour.pos);
             listNeigh.Add(variableDest);
         }
         this.neighbours[key] = listNeigh;
     }
     this.assignments = new List<Assignment>();
     foreach (var ass in cspToBeCopied.assignments)
     {
         var variableDest = this.vars.First(v => v.pos == ass.variable.pos);
         var assignDest = new Assignment(variableDest, ass.value);
         assignDest.domainPrune = new Dictionary<Vector2, List<OverFloorType>>();
         foreach (var domPruneKey in ass.domainPrune.Keys)
         {
             var listOfdomainprune = new List<OverFloorType>();
             foreach (var valuePruned in ass.domainPrune[domPruneKey])
             {
                 listOfdomainprune.Add(valuePruned);
             }
             assignDest.domainPrune[domPruneKey] = listOfdomainprune;
         }
         this.assignments.Add(assignDest);
     }
     this.toleranceFM = cspToBeCopied.toleranceFM;
     this.toleranceFW = cspToBeCopied.toleranceFW;
     this.MAC3 = cspToBeCopied.MAC3;
 }
Esempio n. 5
0
        private static List<OverFloorType> MAC3HeadTailChecker(Variable headVar, Variable tailVar, CSP problem)
        {
            var ret = new List<OverFloorType>();
            //Loop remaining domain values
            var remainingDomains = tailVar.remDomain.ToList();
            foreach (var remDomTail in remainingDomains)
            {
                int validTailValue = 0;
                problem.AssignValue(tailVar, remDomTail, false);
                var remDomainHead = headVar.remDomain.ToList();
                foreach (var remDomHead in remDomainHead)
                {
                    var alreadyAssigned = problem.IsVariableAssigned(headVar);
                        if(!alreadyAssigned)problem.AssignValue(headVar, remDomHead, false);
                    bool valid = problem.ValidateConstraints();
                    if (!valid)
                    {
                        validTailValue++;
                        break;
                    }
                    if (!alreadyAssigned) problem.RemoveValue(headVar);
                }
                if (validTailValue == remDomainHead.Count())
                    ret.Add(remDomTail);
                problem.RemoveValue(tailVar);
            }

            return ret;
        }
Esempio n. 6
0
 /// <summary>
 /// Loop all variables and values searching for a solution for the CSP
 /// </summary>
 /// <param name="problem"></param>
 /// <returns></returns>
 public static List<Assignment> RecursiveBacktrackingSearch(CSP problem)
 {
     if (problem.Goal())
     {
         Debug.Log("Goal completed!");
         return problem.GetAssignments();
     }
     //Loop unassigned
     var orderedVars = problem.OrderVariablesByMinimumRemainingValues();
     foreach (var variable in orderedVars)
     {
         Debug.Log("Variable evaluated:" + variable.pos.ToString());
         var orderedAssignments = problem.OrderAssignmentsByLeastRestrictingValues(variable);
         foreach (var assign in orderedAssignments)
         {
             Debug.Log("Value evaluated:" + assign.value.ToString());
             //Assign value
             bool validResult = problem.AssignValue(assign.variable, assign.value);
             if (!validResult)
                 throw new Exception("Error getting available values");
             List<Assignment> validAssignments = null;
             validAssignments = RecursiveBacktrackingSearch(new CSP(problem));
             if (validAssignments != null)
             {
                 return validAssignments;
             }
             else
             {
                 Debug.Log("Backtracking value:" + assign.value.ToString());
                 problem.RemoveValue(assign.variable);
             }
         }
     }
     Debug.Log("Backtracking");
     return null;
 }
Esempio n. 7
0
        /// <summary>
        /// Maintenance Arc Consistency, this algorithm will check how many domain prunes are done when a assignemnt is executed
        /// </summary>
        /// <param name="assign">Assignment to be evaluated and updated</param>
        /// <param name="neighbours">List of neighbours to start with (difference between AC3 and MAC3)</param>
        /// <returns></returns>
        public static bool MAC3(ref Assignment assign,CSP problem)
        {
            var position = assign.variable.pos;
            var variableInLocalProblem = problem.vars.First(v => v.pos == position);

            //Add the assignment to the problem
            problem.AssignValue(variableInLocalProblem, assign.value,false);

            List<Variable> queueToPrune = new List<Variable>();
            queueToPrune.Add(variableInLocalProblem);

            while (queueToPrune.Any())
            {
                //Get the first variable
                var headVariable = queueToPrune.First();
                queueToPrune.Remove(headVariable);

                //Get the neighbours of the variable
                List<Variable> neighbours = problem.GetNeighbours(headVariable).Where(n => !problem.IsVariableAssigned(n)).ToList();
                //Loop over neighbours
                foreach (var neigh in neighbours)
                {
                    //Get the list of values to delete for conflict
                    List<OverFloorType> valuesToPrune = new List<OverFloorType>();
                    //Check if value is compatible with remaining values in head
                    foreach (var valPruned in MAC3HeadTailChecker(headVariable, neigh, problem))
                    {
                        if (!valuesToPrune.Any(v => v == valPruned))
                            valuesToPrune.Add(valPruned);
                    }

                    //Remove the value from the variable domain in temporal CSP and add to the domain prune
                    foreach (var prunedVal in valuesToPrune)
                    {
                        //Remove domain from variable in problem
                        problem.RemoveDomainElementFromVariable(neigh, prunedVal);
                        //remove domain from variable in current variable
                        neigh.removeDomainElement(prunedVal);
                        if (!neigh.remDomain.Any())
                            return false;
                        //Add prune action to assignment
                        assign.AddDomainPrune(neigh.pos, prunedVal);
                    }

                    if (valuesToPrune.Any())
                    {
                        queueToPrune.Add(neigh);
                    }
                }
            }
            return true;
        }
Esempio n. 8
0
    /// <summary>
    /// Generates a random number of tiles using CSP constraint validaton
    /// </summary>
    /// <param name="matrix">Cell matrix to be filled</param>
    /// <returns>Cell matrix with random values generated</returns>
    private Cell[,] GenerateRandomTiles(Cell[,] matrix)
    {
        //Initialize a new random generator
        System.Random random = new System.Random();

        //Get number of tiles
        var totalNumberOfTiles = this.numTiles * this.numTiles;
        var numberOfRandomTiles = totalNumberOfTiles * randomGeneratedTilesRate / 100;
        //List with all possible values
        List<OverFloorType> values = Enum.GetValues(typeof(OverFloorType)).OfType<OverFloorType>().Where(o => Convert.ToInt32(o) >= 0).ToList();

        for (int i = 0; i < numberOfRandomTiles; i++)
        {
            bool generatedValue = false;
            //Loop until a valid random generated value has been created for this turn
            while (!generatedValue)
            {
                //Generate a random number for x and y
                var x = random.Next(numTiles);
                var y = random.Next(numTiles);
                //Only assign value to unassigned
                if (matrix[x, y].overFloor == OverFloorType.NONE)
                {
                    //Generate a random value
                    Array overfloortypes = Enum.GetValues(typeof(OverFloorType));
                    OverFloorType randomType = OverFloorType.NONE;
                    while (randomType == OverFloorType.NONE)
                        randomType = (OverFloorType)overfloortypes.GetValue(random.Next(0, overfloortypes.Length));
                    //Assign the value
                    matrix[x, y].overFloor = randomType;
                    List<Variable> vars = ConvertMatrixToVars(matrix);
                    CSP problem = new CSP(vars, values, toleranceFW, toleranceFM);
                    if (problem.ValidateConstraints())
                    {
                        generatedValue = true;
                        Debug.Log(string.Format("Position assigned:[{0},{1}] Value: {2}",x.ToString(),y.ToString(),randomType.ToString()));
                    }
                    else
                        matrix[x, y].overFloor = OverFloorType.NONE;
                }
            }
        }

        return matrix;
    }
Esempio n. 9
0
        private static List <OverFloorType> MAC3HeadTailChecker(Variable headVar, Variable tailVar, CSP problem)
        {
            var ret = new List <OverFloorType>();
            //Loop remaining domain values
            var remainingDomains = tailVar.remDomain.ToList();

            foreach (var remDomTail in remainingDomains)
            {
                int validTailValue = 0;
                problem.AssignValue(tailVar, remDomTail, false);
                var remDomainHead = headVar.remDomain.ToList();
                foreach (var remDomHead in remDomainHead)
                {
                    var alreadyAssigned = problem.IsVariableAssigned(headVar);
                    if (!alreadyAssigned)
                    {
                        problem.AssignValue(headVar, remDomHead, false);
                    }
                    bool valid = problem.ValidateConstraints();
                    if (!valid)
                    {
                        validTailValue++;
                        break;
                    }
                    if (!alreadyAssigned)
                    {
                        problem.RemoveValue(headVar);
                    }
                }
                if (validTailValue == remDomainHead.Count())
                {
                    ret.Add(remDomTail);
                }
                problem.RemoveValue(tailVar);
            }

            return(ret);
        }