// Copy constructor public SokobanState(SokobanState other) { if (other != null) { this.crates = new List <Vector2> (other.crates); this.player = other.player; } }
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); }
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); }
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); }
//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); }
//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); }
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); }
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); }
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); }
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); }
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); }
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); }
//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); }
//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); }
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); }
//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); }