diff --git a/DataModels/GC.py b/DataModels/GC.py index 58bca6f..0b0b74e 100644 --- a/DataModels/GC.py +++ b/DataModels/GC.py @@ -53,7 +53,7 @@ class GC(Cell): self.moves.extend(result) self.moves.reverse() - def find_houses_BestFS(self,enviromnent, house_count): + """def find_houses_BestFS(self,enviromnent, house_count): x = self.x y = self.y result = [] @@ -73,14 +73,40 @@ class GC(Cell): a += 1 available_movement = check_moves(enviromnent, x, y) - result, [x, y] = BestFS(enviromnent, [x, y], houses_list) + result, [x, y] = BestFS(enviromnent, [[x, y]], houses_list) self.moves.extend(result) available_movement = check_moves(enviromnent, x, y) - result, [x, y] = BestFS(enviromnent, [x, y], dump_list) + result, [x, y] = BestFS(enviromnent, [[x, y]], dump_list) print("IM ALIVEEEEEEEEEEEEEEEE") self.moves.extend(result[1:]) - self.moves.reverse() + self.moves.reverse()""" + def find_houses_BestFS(self, environment): + x = self.x + y = self.y + result = [[x,y]] + + houses_list = [] + dump_list = [] + a = 0 + for row in environment: + b = 0 + for col in row: + print(col) + if (type(col) is House): + houses_list.append([col,[a,b]]) + if (type(col) is Dump): + dump_list.append([col,[a,b]]) + b += 1 + a += 1 + + x, y = self.x, self.y + + for i in range(len(houses_list)): + available_movement = check_moves(environment, x, y) + [x,y],result,houses_list = BestFS(environment, available_movement, [[x,y]], houses_list) + self.moves.extend(result[1:]) + self.moves.reverse() def make_actions_from_list(self,environment): now = pygame.time.get_ticks() diff --git a/Traversal/BestFS.py b/Traversal/BestFS.py index 8d1f706..7ad375e 100644 --- a/Traversal/BestFS.py +++ b/Traversal/BestFS.py @@ -14,113 +14,64 @@ def CalculateDistance(gc, object_list): min_distance_goal = [h[1], distance] return min_distance_goal -def BestFS(grid, gc_moveset, object_list): +def BestFS(grid, available_movement, gc_moveset, object_list, depth = 0): + + x, y = gc_moveset[-1][0], gc_moveset[-1][1] - if(len(object_list) == 0): - return result + #if depth exceeded, return + if(depth > 30 or len(available_movement) == 0): + return - result = [gc_moveset] - print(gc_moveset) - x, y = gc_moveset[0], gc_moveset[1] - available_movement = check_moves(grid, x, y) + #calculate distance to the nearest object + min_distance_goal = CalculateDistance([x,y], object_list) + print(min_distance_goal) - decision_stack = [] + if(min_distance_goal[1] == 1): + gc_moveset.append("pick_garbage") + cell = grid[min_distance_goal[0][0]][min_distance_goal[0][1]] + print("***"+str([cell,min_distance_goal[0]])+"***") + object_list.remove([cell,min_distance_goal[0]]) + return([x, y], gc_moveset, object_list) - constraint = 100 - while(len(object_list) > 0 and constraint > 0): + #set preffered directions based on the closest object + preffered_directions = [] + discouraged_directions = [] - print("================") - print("iteracja: "+str(100-constraint)) - print("GC: "+str([x,y])) - print(object_list) + if(min_distance_goal[0][0] > x): + preffered_directions.append("right") + if(min_distance_goal[0][0] < x): + preffered_directions.append("left") + if(min_distance_goal[0][1] > y): + preffered_directions.append("down") + if(min_distance_goal[0][1] < y): + preffered_directions.append("up") - #calculate distance to the nearest object - min_distance_goal = CalculateDistance([x,y], object_list) - print(min_distance_goal) + if(len(preffered_directions) == 1): + discouraged_directions.append(movement(grid, x, y)[1][preffered_directions[0]]) - #set preffered directions based on the closest object - preffered_directions = [] - discouraged_directions = [] - if(min_distance_goal[1] == 1): - result.append("pick_garbage") - decision_stack = [] - cell = grid[min_distance_goal[0][0]][min_distance_goal[0][1]] - print("***"+str([cell,min_distance_goal[0]])+"***") - object_list.remove([cell,min_distance_goal[0]]) - if(len(object_list)==0): - break - available_movement = check_moves(grid, x, y) + """print("Preferred: "+str(preffered_directions)) + print("Discouraged: "+str(discouraged_directions)) + print("Available: "+str(available_movement))""" + + #sort available moves according to preferences + sorted = [o for o in preffered_directions if o in available_movement] + for o in sorted: + available_movement.remove(o) + sorted.extend([o for o in available_movement if o not in discouraged_directions]) + for o in sorted: + if(o in available_movement): + available_movement.remove(o) + sorted.extend(available_movement) + available_movement = sorted.copy() - min_distance_goal = CalculateDistance([x,y], object_list) - print(min_distance_goal) + #print("After sorting: "+str(available_movement)) - print(min_distance_goal[0]) - - - if(min_distance_goal[0][0] > x): - preffered_directions.append("right") - if(min_distance_goal[0][0] < x): - preffered_directions.append("left") - if(min_distance_goal[0][1] > y): - preffered_directions.append("down") - if(min_distance_goal[0][1] < y): - preffered_directions.append("up") - - if(len(preffered_directions) == 1): - discouraged_directions.append(movement(grid, x, y)[1][preffered_directions[0]]) - - print("Preferred: "+str(preffered_directions)) - print("Discouraged: "+str(discouraged_directions)) - print("Available: "+str(available_movement)) - - possible_routes = len([i for i in available_movement if i in preffered_directions ]) - print("Preferred to available count: "+str(possible_routes)) - - #HOTFIX - if(possible_routes > 1): - if(len(decision_stack) > 0): - if(decision_stack[0] == [x,y]): - preffered_directions.pop(1) - else: - decision_stack = [[x,y]] - preffered_directions.pop(0) - print("Decision stack: "+str(decision_stack)) - - """ if(possible_routes > 1): - for move in available_movement: - if (move in preffered_directions): - x_next, y_next = movement(grid, x, y)[0][move] - route = BestFS(grid, [x_next,y_next], houses_list, [[x_next, y_next]], check_moves(grid, x_next, y_next, move), "House", depth + 1) - print("DIRECTION: "+str(move)+", GIVEN "+str(len(houses_list))+" HOUSES, RECURSION ON DEPTH "+str(depth+1)+" returned "+str(route)) - if (route == None): - break - if (route.count("pick_garbage") - 1 == len(houses_list)): - print(str(route.count("pick_garbage"))+" / "+str(len(houses_list))) - print("ROUTE ADDED") - result.extend(route) - break - break """ - - if(len(available_movement) == 0): - available_movement = check_moves(grid, x, y) - if(len(available_movement)>0): - next_move = available_movement[0] - for move in available_movement: - if (move not in discouraged_directions): - next_move = move - break - for move in preffered_directions: - if(move in available_movement): - next_move = move - break - print("Next move: "+str(next_move)) - x_next, y_next = movement(grid, x, y)[0][next_move] - print("Next moving to "+str(x_next)+" "+str(y_next)) - result.append([x_next,y_next]) - x, y = x_next, y_next - available_movement = check_moves(grid, x, y, next_move) - print("------------------------------") - - constraint -= 1 - - return result, [x,y] + for direction in available_movement: + x_next, y_next = movement(grid,x,y)[0][direction] + available_movement_next = check_moves(grid, x_next,y_next,direction) + gc_moveset_next = gc_moveset.copy() + gc_moveset_next.append([x_next,y_next]) + result = BestFS(grid, available_movement_next, gc_moveset_next, object_list, depth + 1) + print(type(result)) + if result!= None: + return result \ No newline at end of file diff --git a/Traversal/BestFS_nope.py b/Traversal/BestFS_nope.py new file mode 100644 index 0000000..06cc4ca --- /dev/null +++ b/Traversal/BestFS_nope.py @@ -0,0 +1,131 @@ +from utilities import movement,check_moves +from DataModels.House import House +from DataModels.Container import Container +from config import GRID_WIDTH, GRID_HEIGHT +from math import sqrt +INF = float('Inf') + + +def CalculateDistance(gc, object_list): + min_distance_goal = ['-',INF] + for h in object_list: + distance = sqrt(pow(h[1][0]-gc[0],2)+pow(h[1][1]-gc[1],2)) + if(min_distance_goal[1] > distance): + min_distance_goal = [h[1], distance] + return min_distance_goal + +def BestFS(grid, gc_moveset, object_list): + print(gc_moveset) + x, y = gc_moveset[-1][0], gc_moveset[-1][1] + available_movement = check_moves(grid, x, y) + + if(len(object_list) == 0): + return gc_moveset + + + decision_stack = [] + + constraint = 100 + while(len(object_list) > 0 and constraint > 0): + + print("================") + print("iteracja: "+str(100-constraint)) + print("GC: "+str([x,y])) + print(object_list) + + #calculate distance to the nearest object + min_distance_goal = CalculateDistance([x,y], object_list) + print(min_distance_goal) + + #check if can pick garbage + if(min_distance_goal[1] == 1): + gc_moveset.append("pick_garbage") + decision_stack = [] + #remove object from goals list + cell = grid[min_distance_goal[0][0]][min_distance_goal[0][1]] + print("***"+str([cell,min_distance_goal[0]])+"***") + object_list.remove([cell,min_distance_goal[0]]) + #if that was the last object, return + if(len(object_list)==0): + break + #look for a new goal + available_movement = check_moves(grid, x, y) + min_distance_goal = CalculateDistance([x,y], object_list) + print(min_distance_goal) + print(min_distance_goal[0]) + + #set preffered directions based on the closest object + preffered_directions = [] + discouraged_directions = [] + + if(min_distance_goal[0][0] > x): + preffered_directions.append("right") + if(min_distance_goal[0][0] < x): + preffered_directions.append("left") + if(min_distance_goal[0][1] > y): + preffered_directions.append("down") + if(min_distance_goal[0][1] < y): + preffered_directions.append("up") + + if(len(preffered_directions) == 1): + discouraged_directions.append(movement(grid, x, y)[1][preffered_directions[0]]) + + print("Preferred: "+str(preffered_directions)) + print("Discouraged: "+str(discouraged_directions)) + print("Available: "+str(available_movement)) + + #if agent finds more than 1 optimal route + possible_routes = len([i for i in available_movement if i in preffered_directions ]) + print("Preferred to available count: "+str(possible_routes)) + + #HOTFIX + if(possible_routes > 1): + if(len(decision_stack) > 0): + if(decision_stack[0] == [x,y]): + preffered_directions.pop(1) + else: + decision_stack = [[x,y]] + preffered_directions.pop(0) + print("Decision stack: "+str(decision_stack)) + + """ if(possible_routes > 1): + for move in available_movement: + if (move in preffered_directions): + x_next, y_next = movement(grid, x, y)[0][move] + route = BestFS(grid, [x_next,y_next], houses_list, [[x_next, y_next]], check_moves(grid, x_next, y_next, move), "House", depth + 1) + print("DIRECTION: "+str(move)+", GIVEN "+str(len(houses_list))+" HOUSES, RECURSION ON DEPTH "+str(depth+1)+" returned "+str(route)) + if (route == None): + break + if (route.count("pick_garbage") - 1 == len(houses_list)): + print(str(route.count("pick_garbage"))+" / "+str(len(houses_list))) + print("ROUTE ADDED") + gc_moveset.extend(route) + break + break """ + + #if got no available moves but still has goals to visit + if(len(available_movement) == 0): + available_movement = check_moves(grid, x, y) + + #selecting next move based on preferences (starting with the worst option) + if(len(available_movement)>0): + next_move = available_movement[0] #pick any + for move in available_movement: + if (move not in discouraged_directions): #pick any not discouraged move if possible + next_move = move + break + for move in preffered_directions: + if(move in available_movement): #pick any preferred move if possible + next_move = move + break + print("Next move: "+str(next_move)) + x_next, y_next = movement(grid, x, y)[0][next_move] + print("Next moving to "+str(x_next)+" "+str(y_next)) + gc_moveset.append([x_next,y_next]) + x, y = x_next, y_next + available_movement = check_moves(grid, x, y, next_move) + print("------------------------------") + + constraint -= 1 + + return gc_moveset, [x,y] diff --git a/main.py b/main.py index 2f63268..77c689a 100755 --- a/main.py +++ b/main.py @@ -101,15 +101,15 @@ while True: elif event.key == pygame.K_0: gc.find_houses(map_objects,house_count,dump_count) elif event.key == pygame.K_9: - gc.find_houses_BestFS(map_objects,house_count) + gc.find_houses_BestFS(map_objects) gc.make_actions_from_list(map_objects) pygame_sprites.update() pygame_sprites.draw(GAME_WINDOW) #draw GC moves - bg_rect = pygame.Surface((105,30), pygame.SRCALPHA) # per-pixel alpha - bg_rect.fill((0,0,0,160)) # notice the alpha value in the color + bg_rect = pygame.Surface((105,30), pygame.SRCALPHA) + bg_rect.fill((0,0,0,160)) GAME_WINDOW.blit(bg_rect, (0, WINDOW_HEIGHT-30)) font = pygame.font.SysFont("monospace", 15)