Esempio n. 1
0
 // Copy constructor
 public SokobanState(SokobanState other)
 {
     if (other != null)
     {
         this.crates = new List <Vector2> (other.crates);
         this.player = other.player;
     }
 }
Esempio n. 2
0
    public bool check_lock(object state)
    {
        SokobanState   s              = (SokobanState)state;
        float          goals_missing  = GoalsMissing(state);
        List <Vector2> crates_missing = new List <Vector2> ();

        foreach (Vector2 crate in s.crates)
        {
            if (!goals.Contains(crate))
            {
                crates_missing.Add(crate);

                if (goals_missing == crates_missing.Count)
                {
                    break;
                }
            }
        }


        foreach (Vector2 crate in crates_missing)
        {
            //falta ver se as caixas vizinhas se podem mover
            float x = crate.x, y = crate.y;
            //Debug.Log("x= {"+x+"} y={"+y+"}");
            Vector2 topleft = new Vector2(x - 1, y - 1), topright = new Vector2(x - 1, y + 1), bottomleft = new Vector2(x + 1, y - 1), bottomright = new Vector2(x + 1, y + 1);
            Vector2 left = new Vector2(x - 1, y), right = new Vector2(x + 1, y), top = new Vector2(x, y - 1), bottom = new Vector2(x, y + 1);
            if (s.crates.Contains(topleft) || walls[(int)topleft.y, (int)topleft.x])
            {
                if ((s.crates.Contains(top) || walls[(int)top.y, (int)top.x]) && (s.crates.Contains(left) || walls[(int)left.y, (int)left.x]))
                {
                    return(false);
                }
            }
            if (s.crates.Contains(topright) || walls[(int)topright.y, (int)topright.x])
            {
                if ((s.crates.Contains(top) || walls[(int)top.y, (int)top.x]) && (s.crates.Contains(right) || walls[(int)right.y, (int)right.x]))
                {
                    return(false);
                }
            }
            if (s.crates.Contains(bottomleft) || walls[(int)bottomleft.y, (int)bottomleft.x])
            {
                if ((s.crates.Contains(bottom) || walls[(int)bottom.y, (int)bottom.x]) && (s.crates.Contains(left) || walls[(int)left.y, (int)left.x]))
                {
                    return(false);
                }
            }
            if (s.crates.Contains(bottomright) || walls[(int)bottomright.y, (int)bottomright.x])
            {
                if ((s.crates.Contains(bottom) || walls[(int)bottom.y, (int)bottom.x]) && (s.crates.Contains(right) || walls[(int)right.y, (int)right.x]))
                {
                    return(false);
                }
            }
        }
        return(true);
    }
Esempio n. 3
0
    public SokobanProblem(Vector2 player, List <Vector2> crates, List <Vector2> goals, bool [,] walls)
    {
        this.walls = walls;
        this.goals = goals;

        List <Vector2> crates_copy = new List <Vector2> (crates);

        start_state = new SokobanState(crates_copy, player);
    }
    public SokobanProblem(Map map)
    {
        walls = map.GetWalls();
        goals = map.GetGoals();

        List <Vector2> crates_copy = new List <Vector2> (map.GetCrates());

        start_state = new SokobanState(crates_copy, map.GetPlayerStart());
    }
    public float distEuclPlayer(object state)
    {
        SokobanState s     = (SokobanState)state;
        float        dist  = float.MaxValue;
        float        total = 0;

        foreach (Vector2 crate in s.crates)
        {
            dist   = Mathf.Min(dist, (Mathf.Sqrt(((crate.x - s.player.x) * (crate.x - s.player.x) + (crate.y - s.player.y) * (crate.y - s.player.y)))));
            total += dist;
        }
        return(total);
    }
Esempio n. 6
0
    public List <Vector2> getRemainingCratesCoordinates(object state)
    {
        SokobanState   new_state = (SokobanState)state;
        List <Vector2> result    = new List <Vector2>();

        foreach (Vector2 crate in new_state.crates)
        {
            if (!goals.Contains(crate))
            {
                result.Add(crate);
            }
        }
        return(result);
    }
    public int getRemainingGoals(object state)
    {
        SokobanState s = (SokobanState)state;
        int          remainingGoals = goals.Count;

        foreach (Vector2 crate in s.crates)
        {
            if (goals.Contains(crate))
            {
                remainingGoals--;
            }
        }
        return(remainingGoals);
    }
Esempio n. 8
0
    //Fórmula da distância de euclides aplicada de forma a calcular a distância entre o player e a caixa

    public float euclGetPlayer(object state)
    {
        SokobanState s        = (SokobanState)state;
        float        valorMax = float.MaxValue;

        foreach (Vector2 crate in s.crates)
        {
            foreach (Vector2 goal in goals)
            {
                float dist = Mathf.Sqrt(Mathf.Pow(crate.x - s.player.x, 2.0f) + Mathf.Pow(crate.y - s.player.y, 2.0f));
                valorMax = Mathf.Min(valorMax, dist);
            }
        }
        return(valorMax);
    }
Esempio n. 9
0
    //Fórmula da distância de manhattan aplicada de forma a calcular a distância entre o player e a caixa

    public float manhaGetPlayer(object state)
    {
        SokobanState s        = (SokobanState)state;
        float        valorMax = float.MaxValue;

        foreach (Vector2 crate in s.crates)
        {
            foreach (Vector2 goal in goals)
            {
                float dist = Mathf.Abs(crate.x - s.player.x) + Mathf.Abs(crate.y - s.player.y);
                valorMax = Mathf.Min(valorMax, dist);
            }
        }
        return(valorMax);
    }
Esempio n. 10
0
    public List <Vector2> getRemainingGoalsCoordinates(object state)
    {
        SokobanState new_state = (SokobanState)state;

        List <Vector2> result = new List <Vector2>();

        foreach (Vector2 goal in goals)
        {
            if (!new_state.crates.Contains(goal))
            {
                result.Add(goal);
            }
        }
        return(result);
    }
Esempio n. 11
0
    public float GoalsMissing(object state)
    {
        SokobanState s = (SokobanState)state;

        float remainingGoals = goals.Count;

        foreach (Vector2 crate in s.crates)
        {
            if (goals.Contains(crate))
            {
                remainingGoals--;
            }
        }

        return(remainingGoals);
    }
Esempio n. 12
0
    public float distEuclGoal(object state)
    {
        SokobanState s     = (SokobanState)state;
        float        dist  = float.MaxValue;
        float        total = 0;

        foreach (Vector2 crate in s.crates)
        {
            foreach (Vector2 goal in goals)
            {
                dist   = Mathf.Min(dist, (Mathf.Sqrt(((crate.x - goal.x) * (crate.x - goal.x) + (crate.y - goal.y) * (crate.y - goal.y)))));
                total += dist;
            }
        }
        return(total);
    }
Esempio n. 13
0
    public float getPlayerToClosestCrateToClosestGoalDistance(object state)
    {
        SokobanState new_state    = (SokobanState)state;
        float        min_dist     = float.MaxValue;
        Vector2      closestCrate = Vector2.zero;

        for (int i = 0; i < new_state.crates.Count; i++)
        {
            if (goals.Contains(new_state.crates [i]))
            {
                //nothing to do here
            }
            else
            {
                if (closestCrate == Vector2.zero)
                {
                    closestCrate = new_state.crates [i];
                }
                else
                {
                    if ((new_state.crates [i] - new_state.player).magnitude < (closestCrate - new_state.player).magnitude)
                    {
                        closestCrate = new_state.crates [i];
                    }
                }
            }
        }

        for (int i = 0; i < goals.Count; i++)
        {
            if (new_state.crates.Contains(goals [i]))
            {
                //nothing to do here
            }
            else
            {
                float dist = (closestCrate - goals [i]).magnitude;
                if (dist < min_dist)
                {
                    min_dist = dist;
                }
            }
        }
        min_dist += (closestCrate - new_state.player).magnitude;
        //Debug.Log ("Min_Dist = " + min_dist);
        return(min_dist);
    }
Esempio n. 14
0
    public float getPlayerToCratesSumManhattanDistance(object state)
    {
        SokobanState new_state  = (SokobanState)state;
        float        total_dist = 0;

        for (int i = 0; i < new_state.crates.Count; i++)
        {
            if (goals.Contains(new_state.crates [i]))
            {
                //nothing to do here
            }
            else
            {
                total_dist += Mathf.Abs(new_state.crates [i].x - new_state.player.x) + Mathf.Abs(new_state.crates [i].y - new_state.player.y);
            }
        }
        //Debug.Log ("Min_Dist = " + min_dist);
        return(total_dist);
    }
Esempio n. 15
0
    public float getPlayerToCratesSumDistance(object state)
    {
        SokobanState new_state  = (SokobanState)state;
        float        total_dist = 0;

        //Debug.Log ("Num crates = " + new_state.crates.Count);
        for (int i = 0; i < new_state.crates.Count; i++)
        {
            if (goals.Contains(new_state.crates [i]))
            {
                //nothing to do here
            }
            else
            {
                total_dist += (new_state.crates [i] - new_state.player).magnitude;
            }
        }
        //Debug.Log("Min_Dist = " + min_dist);
        return(total_dist);
    }
Esempio n. 16
0
    //this method analyses the map txt and and adds the corner positions to the hashMap
    //the method is not working properly and is therefore commented

    /*
     * public void markSimpleDeadlocks () {
     *      TextAsset map_txt = map.map;
     *      int cellSize = map.cellSize;
     *      string[] mapString = map_txt.text.TrimEnd('\n').Split('\n');
     *      int width = mapString [0].Length;
     *      int height = mapString.Length;
     *      Vector2 pos;
     *
     *      for (int y = height - 1; y >= 0; y--) {
     *              for (int x = 0; x < width; x++) {
     *
     *                      bool N_wall = false;
     *                      bool E_wall = false;
     *                      bool S_wall = false;
     *                      bool W_wall = false;
     *                      bool in_corner = false;
     *
     *                      pos = new Vector2 (x * cellSize, (height - y - 1) * cellSize);
     *
     *                      if ((mapString [y] [x] != '#') && (mapString [y] [x] != '.') && (mapString [y] [x] != '$') && (mapString [y] [x] != '@')) {
     *                              //check if there is a wall north of the box
     *                              if (mapString[y - 1][x] == '#')
     *                                      N_wall = true;
     *                              //check if there is a wall east of the box
     *                              if (mapString[y][x + 1] == '#')
     *                                      E_wall = true;
     *                              //check if there is a wall south of the box
     *                              if (mapString[y + 1][x] == '#')
     *                                      S_wall = true;
     *                              //check if there is a wall west of the box
     *                              if (mapString[y][x - 1] == '#')
     *                                      W_wall = true;
     *
     *                              //check if box in NE corner
     *                              if (N_wall && E_wall)
     *                              {
     *                                      in_corner = true;
     *                              }
     *                              //check if box in NW corner
     *                              else if (N_wall && W_wall)
     *                              {
     *                                      in_corner = true;
     *                              }
     *                              //check if box in SE corner
     *                              else if (S_wall && E_wall)
     *                              {
     *                                      in_corner = true;
     *                              }
     *                              //check if box in SW corner
     *                              else if (S_wall && W_wall)
     *                              {
     *                                      in_corner = true;
     *                              }
     *
     *                              if (in_corner) {
     *                                      simpleDeadlocksHash.Add (pos);
     *                                      Debug.LogWarning ("Simple Deadlock at: "+ pos.x + ", " + pos.y);
     *                              }
     *                      }
     *
     *              }
     *      }
     *      Debug.LogWarning ("There Are " + simpleDeadlocksHash.Count + " Corners In The Map");
     * }
     */

    //Method that checks all crates in a state and if there is one in a deadlock(corner) position it returns 1;
    //this method aren't working and are therefore commented

    /*
     * public int simpleDeadlocks(object state)
     * {
     *      TextAsset map_txt = map.map;
     *      int cellSize = map.cellSize;
     *      string[] mapString = map_txt.text.TrimEnd('\n').Split('\n');
     *      int width = mapString [0].Length;
     *      int height = mapString.Length;
     *      int deadlock = 0;
     *      SokobanState s = (SokobanState)state;
     *
     *      foreach (Vector2 crate in s.crates) {
     *              //Debug.LogWarning ("CRATE AT POSITION " + crate.ToString());
     *              Vector2 pos = new Vector2 (crate.x * cellSize, (height - crate.y - 1) * cellSize);
     *              if (simpleDeadlocksHash.Contains (crate)) {
     *                      Debug.LogWarning ("IN THIS STATE THERE IS A CRATE AT " + pos.x + " " + pos.y);
     *                      deadlock = 1;
     *              } else {
     *                      Debug.LogWarning ("Not on deadlock");
     *                      deadlock = -1;
     *              }
     *      }
     *      Debug.LogError ("RETURNED DEADLOCK = " + deadlock);
     *      return deadlock;
     * }
     */

    //Initial heuristics where we return the number of remaining goals
    public float GetHeuristics(object state)
    {
        List <Vector2> goals;

        goals = map.GetGoals();

        SokobanState s = (SokobanState)state;
        int          remainingGoals = goals.Count;


        foreach (Vector2 crate in s.crates)
        {
            if (goals.Contains(crate))
            {
                remainingGoals--;
            }
        }

        return((float)remainingGoals);
    }
    public bool IsGoal(object state)
    {
        SokobanState s = (SokobanState)state;
        int          remainingGoals = goals.Count;

        foreach (Vector2 crate in s.crates)
        {
            if (goals.Contains(crate))
            {
                remainingGoals--;
            }
        }

        if (remainingGoals == 0)
        {
            return(true);
        }

        return(false);
    }
    public bool Equals(SokobanState s)
    {
        if ((System.Object)s == null)
        {
            return(false);
        }

        if (player != s.player)
        {
            return(false);
        }

        for (int i = 0; i < crates.Count; i++)
        {
            if (crates[i] != s.crates[i])
            {
                return(false);
            }
        }

        return(true);
    }
Esempio n. 19
0
    //heuristica de expansão de nós
    public int Checkexpansion(object state)
    {
        SokobanState s = (SokobanState)state;

        Action[] allActions      = Actions.GetAll();
        int      possibleActions = 0;

        foreach (Action a in allActions)
        {
            Vector2 movement = Actions.GetVector(a);
            Vector2 new_pos  = s.player + movement;

            // Move to wall?
            if (walls [(int)new_pos.y, (int)new_pos.x])
            {
                break;
            }

            // Crate in front and able to move?
            int index = s.crates.IndexOf(new_pos);
            if (index != -1)
            {
                Vector2 new_crate_pos = s.crates [index] + movement;

                if (walls [(int)new_crate_pos.y, (int)new_crate_pos.x])
                {
                    break;
                }

                if (s.crates.Contains(new_crate_pos))
                {
                    break;
                }
            }
            possibleActions += 1;
        }
        //Debug.Log (possibleActions);
        return(possibleActions);
    }
Esempio n. 20
0
    public float getPlayerToCratesMinimumManhattanDistance(object state)
    {
        SokobanState new_state = (SokobanState)state;
        float        min_dist  = float.MaxValue;

        for (int i = 0; i < new_state.crates.Count; i++)
        {
            if (goals.Contains(new_state.crates [i]))
            {
                //nothing to do here
            }
            else
            {
                float dist = Mathf.Abs(new_state.crates [i].x - new_state.player.x) + Mathf.Abs(new_state.crates [i].y - new_state.player.y);
                if (dist < min_dist)
                {
                    min_dist = dist;
                }
            }
        }
        //Debug.Log ("Min_Dist = " + min_dist);
        return(min_dist);
    }
Esempio n. 21
0
    //Heuristics function uses Manhattan distance between player and
    //nearest box, and between box and nearest goal
    public float GetHeuristicsD(object state)
    {
        List <Vector2> goals;

        goals = map.GetGoals();
        SokobanState s = (SokobanState)state;

        Vector2 player = s.player;

        //the lower the better
        float score = 0;

        float playerdist = 1000;
        float mindist    = 1000;

        //for each box on the floor, calculate the distance to each empty goal
        foreach (Vector2 crate in s.crates)
        {
            mindist = 1000;
            foreach (Vector2 goal in goals)
            {
                float sum;
                //calculate distance of x and y cords
                float xdist = crate.x - goal.x;
                float ydist = crate.y - goal.y;

                //take absolute value of distance
                if (xdist < 0)
                {
                    xdist *= -1;
                }
                if (ydist < 0)
                {
                    ydist *= -1;
                }

                sum = xdist + ydist;

                if (sum < mindist)
                {
                    mindist = sum;
                }
            }

            score += mindist;
            //calculate player to box distances
            float p_to_box_x = crate.x - player.x;
            float p_to_box_y = crate.y - player.y;

            //take absolute value of distance
            if (p_to_box_x < 0)
            {
                p_to_box_x *= -1;
            }
            if (p_to_box_y < 0)
            {
                p_to_box_y *= -1;
            }

            //stores shortest distance to any box
            if (playerdist > (p_to_box_y + p_to_box_x))
            {
                playerdist = (p_to_box_y + p_to_box_x);
            }
        }
        score += playerdist;
        Debug.LogWarning("SCORE == " + score);
        return(score);
    }