Try to implement to A*

Co-authored-by: Sebastian Piotrowski <sebpio@st.amu.edu.pl>
Co-authored-by: Marcin Matoga <marmat35@st.amu.edu.pl>
Co-authored-by: Ladislaus3III <Ladislaus3III@users.noreply.github.com>
This commit is contained in:
eugenep 2021-04-24 01:44:57 +02:00
parent 0e0a59b6ab
commit 520efb84ea
10 changed files with 1285 additions and 16 deletions

335
astar.py Normal file
View File

@ -0,0 +1,335 @@
import heapq
from os import path
from settings import *
class Problem:
def __init__(self, initial, goal):
self.initial = initial
self.goal = goal
def actions(self, state):
moves = []
if self.turn_left(state):
moves.append('Left')
if self.turn_right(state):
moves.append('Right')
if self.move_forward(state):
moves.append('Forward')
# print(moves)
return moves
def turn_left(self, state):
return True
def turn_right(self, state):
return True
def move_forward(self, state):
a_row = 0
a_column = 0
for row in range(MAP_SIZE):
for column, pos in enumerate(state[row]):
if pos == ">":
a_row = row
a_column = column
if a_column == MAP_SIZE-1:
return False
elif state[a_row][a_column+1] == '.':
return True
elif state[a_row][a_column+1] == 'p':
return True
return False
if pos == "<":
a_row = row
a_column = column
if a_column == 0:
return False
elif state[a_row][a_column-1] == '.':
return True
return False
if pos == "v":
a_row = row
a_column = column
if a_row == MAP_SIZE-1:
return False
elif state[a_row+1][a_column] == '.':
return True
return False
if pos == "^":
a_row = row
a_column = column
if row == 0:
return False
elif state[a_row-1][a_column] == '.':
return True
return False
def turn_me_or_move(self, state, do_it):
temp_map = [list(item) for item in state]
# print(temp_map)
#a_row = 0
#a_column = 0
for row in range(MAP_SIZE):
for column, pos in enumerate(temp_map[row]):
if pos == ">":
a_row = row
a_column = column
#print("a_row:" + str(a_row))
#print("a_column" + str(a_column))
if(do_it == 'Left'):
temp_map[a_row][a_column] = "^"
if(do_it == 'Right'):
temp_map[a_row][a_column] = 'v'
if(do_it == 'Forward'):
temp_map[a_row][a_column] = '.'
temp_map[a_row][a_column+1] = '>'
return temp_map
if pos == "<":
a_row = row
a_column = column
if(do_it == 'Left'):
temp_map[a_row][a_column] = 'v'
if(do_it == 'Right'):
temp_map[a_row][a_column] = '^'
if(do_it == 'Forward'):
temp_map[a_row][a_column] = '.'
temp_map[a_row][a_column-1] = '<'
return temp_map
if pos == "v":
a_row = row
a_column = column
if(do_it == 'Left'):
temp_map[a_row][a_column] = '>'
if(do_it == 'Right'):
temp_map[a_row][a_column] = '<'
if(do_it == 'Forward'):
temp_map[a_row][a_column] = '.'
temp_map[a_row+1][a_column] = 'v'
return temp_map
if pos == "^":
a_row = row
a_column = column
if(do_it == 'Left'):
temp_map[a_row][a_column] = '<'
if(do_it == 'Right'):
temp_map[a_row][a_column] = '>'
if(do_it == 'Forward'):
temp_map[a_row][a_column] = '.'
temp_map[a_row-1][a_column] = '^'
return temp_map
return temp_map
def result(self, state, action):
new_state = []
if action == 'Left':
new_state = self.turn_me_or_move(state, 'Left')
elif action == 'Right':
new_state = self.turn_me_or_move(state, 'Right')
elif action == 'Forward':
new_state = self.turn_me_or_move(state, 'Forward')
super_new_state = tuple(map(tuple, new_state))
return super_new_state
def goal_test(self, state):
if self.goal == state:
return True
return False
def path_cost(self, c, state1, action, state2, in_puddle1, in_puddle2):
return c+1
# funkcja heurystyki
def h(self, node):
node_row = node.row
node_column = node.column
class Node:
def __init__(self, state, parent=None, action=None, path_cost=0):
"""Create a search tree Node, derived from a parent by an action."""
self.state = state
self.parent = parent
self.action = action
self.path_cost = path_cost
self.in_puddle = False
#self.row = row
#self.column = column
def __repr__(self):
return "<Node {}>".format(self.state)
def expand(self, problem):
"""List the nodes reachable in one step from this node."""
return [self.child_node(problem, action)
for action in problem.actions(self.state)]
def child_node(self, problem, action):
next_state = problem.result(self.state, action)
next_node = Node(next_state, self, action, problem.path_cost(self.path_cost, self.state, action, next_state, in_puddle))
return next_node
def where_am_i(self):
temp_map = [list(item) for item in state]
for row in range(MAP_SIZE):
for column, pos in enumerate(temp_map[row]):
if pos == ">" or pos == "<" or pos == "^" or pos == "v":
self.row = row
self.column = column
def __eq__(self, other):
return isinstance(other, Node) and self.state == other.state
def __hash__(self):
# We use the hash value of the state
# stored in the node instead of the node
# object itself to quickly search a node
# with the same state in a Hash Table
return hash(self.state)
class PriorityQueue:
"""A Queue in which the minimum (or maximum) element (as determined by f and
order) is returned first.
If order is 'min', the item with minimum f(x) is
returned first; if order is 'max', then it is the item with maximum f(x).
Also supports dict-like lookup."""
def __init__(self, order='min', f=lambda x: x):
self.heap = []
if order == 'min':
self.f = f
elif order == 'max': # now item with max f(x)
self.f = lambda x: -f(x) # will be popped first
else:
raise ValueError("Order must be either 'min' or 'max'.")
def append(self, item):
"""Insert item at its correct position."""
heapq.heappush(self.heap, (self.f(item), item))
def extend(self, items):
"""Insert each item in items at its correct position."""
for item in items:
self.append(item)
def pop(self):
"""Pop and return the item (with min or max f(x) value)
depending on the order."""
if self.heap:
return heapq.heappop(self.heap)[1]
else:
raise Exception('Trying to pop from empty PriorityQueue.')
def __len__(self):
"""Return current capacity of PriorityQueue."""
return len(self.heap)
def __contains__(self, key):
"""Return True if the key is in PriorityQueue."""
return any([item == key for _, item in self.heap])
def __getitem__(self, key):
"""Returns the first value associated with key in PriorityQueue.
Raises KeyError if key is not present."""
for value, item in self.heap:
if item == key:
return value
raise KeyError(str(key) + " is not in the priority queue")
def __delitem__(self, key):
"""Delete the first occurrence of key."""
try:
del self.heap[[item == key for _, item in self.heap].index(True)]
except ValueError:
raise KeyError(str(key) + " is not in the priority queue")
heapq.heapify(self.heap)
class Astar:
@staticmethod
def best_first_graph_search(problem, f, display=False):
"""Search the nodes with the lowest f scores first.
You specify the function f(node) that you want to minimize; for example,
if f is a heuristic estimate to the goal, then we have greedy best
first search; if f is node.depth then we have breadth-first search.
There is a subtlety: the line "f = memoize(f, 'f')" means that the f
values will be cached on the nodes as they are computed. So after doing
a best first search you can examine the f values of the path returned."""
#f = memoize(f, 'f')
node = Node(problem.initial)
# PriorityQueue ma przechowywac g+h
frontier = PriorityQueue('min', f)
frontier.append(node)
explored = set()
while frontier:
node = frontier.pop()
if problem.goal_test(node.state):
if display:
print(len(explored), "paths have been expanded and",
len(frontier), "paths remain in the frontier")
return node
explored.add(node.state)
for child in node.expand(problem):
if child.state not in explored and child not in frontier:
frontier.append(child)
elif child in frontier:
if f(child) < frontier[child]:
del frontier[child]
frontier.append(child)
return None
@staticmethod
def loadMap(map_name=''):
maze = []
map_folder = path.dirname(__file__)
with open(path.join(map_folder, map_name), 'rt') as f:
for line in f:
maze.append(line.rstrip('\n'))
#print(maze)
return maze
@staticmethod
def run():
initial_map = tuple(map(tuple, Astar.loadMap('map.txt')))
goal_map = tuple(map(tuple, Astar.loadMap('goal_map.txt')))
problem = Problem(initial_map, goal_map)
#BFS.print_node_state(initial_map)
#BFS.print_node_state(goal_map)
result = Astar.breadth_first_graph_search(problem)
print(result)
return result
#print(BFS.print_node_state(result))

542
astar2.py Normal file
View File

@ -0,0 +1,542 @@
from os import path
import heapq
from settings import *
from sprites import Direction
class PlanRoute():
""" The problem of moving the Hybrid Wumpus Agent from one place to other """
def __init__(self, initial, goal, allowed, puddles=None, dimrow=None):
""" Define goal state and initialize a problem """
self.initial = initial
self.goal = goal
self.dimrow = dimrow
self.goal = goal
self.allowed = allowed
self.puddles = puddles
def actions(self, state):
""" Return the actions that can be executed in the given state.
The result would be a list, since there are only three possible actions
in any given state of the environment """
possible_actions = ['Forward', 'Left', 'Right']
x, y = state.get_location()
orientation = state.get_orientation()
# Prevent Bumps
if x == 1 and orientation == 'LEFT':
if 'Forward' in possible_actions:
possible_actions.remove('Forward')
if y == 1 and orientation == 'DOWN':
if 'Forward' in possible_actions:
possible_actions.remove('Forward')
if x == self.dimrow and orientation == 'RIGHT':
if 'Forward' in possible_actions:
possible_actions.remove('Forward')
if y == self.dimrow and orientation == 'UP':
if 'Forward' in possible_actions:
possible_actions.remove('Forward')
return possible_actions
def result(self, state, action):
""" Given state and action, return a new state that is the result of the action.
Action is assumed to be a valid action in the state """
x, y = state.get_location()
#proposed_loc = list()
proposed_loc = []
# Move Forward
if action == 'Forward':
if state.get_orientation() == 'UP':
proposed_loc = [x, y + 1]
elif state.get_orientation() == 'DOWN':
proposed_loc = [x, y - 1]
elif state.get_orientation() == 'LEFT':
proposed_loc = [x - 1, y]
elif state.get_orientation() == 'RIGHT':
proposed_loc = [x + 1, y]
else:
raise Exception('InvalidOrientation')
# Rotate counter-clockwise
elif action == 'Left':
if state.get_orientation() == 'UP':
state.set_orientation('LEFT')
elif state.get_orientation() == 'DOWN':
state.set_orientation('RIGHT')
elif state.get_orientation() == 'LEFT':
state.set_orientation('DOWN')
elif state.get_orientation() == 'RIGHT':
state.set_orientation('UP')
else:
raise Exception('InvalidOrientation')
# Rotate clockwise
elif action == 'Right':
if state.get_orientation() == 'UP':
state.set_orientation('RIGHT')
elif state.get_orientation() == 'DOWN':
state.set_orientation('LEFT')
elif state.get_orientation() == 'LEFT':
state.set_orientation('UP')
elif state.get_orientation() == 'RIGHT':
state.set_orientation('DOWN')
else:
raise Exception('InvalidOrientation')
if tuple(proposed_loc) in self.allowed:
state.set_location(proposed_loc[0], [proposed_loc[1]])
return state
def goal_test(self, state):
""" Given a state, return True if state is a goal state or False, otherwise """
return state.get_location() == self.goal.get_location()
def path_cost(self, c, state1, action, state2):
"""Return the cost of a solution path that arrives at state2 from
state1 via action, assuming cost c to get up to state1. If the problem
is such that the path doesn't matter, this function will only look at
state2. If the path does matter, it will consider c and maybe state1
and action. The default method costs 1 for every step in the path."""
if action == "Forward" or action == "Left" or action == "Right":
x1, y1 = state1.get_location()
location1 = tuple([x1, y1])
x2, y2 = state2.get_location()
location2 = tuple([x1, y1])
if location2 in self.puddles:
return c + 1
if location1 == location2 and state1 in self.puddles:
return c + 1
return c
def h(self, node):
""" Return the heuristic value for a given state."""
# Manhattan Heuristic Function
x1, y1 = node.state.get_location()
x2, y2 = self.goal.get_location()
return abs(x2 - x1) + abs(y2 - y1)
class Node:
def __init__(self, state, parent=None, action=None, path_cost=0):
"""Create a search tree Node, derived from a parent by an action."""
self.state = state #AgentPosition?
self.parent = parent
self.action = action
self.path_cost = path_cost
def __repr__(self):
return "<Node {}>".format(self.state)
def solution(self):
"""Return the sequence of actions to go from the root to this node."""
return [node.action for node in self.path()[1:]]
def expand(self, problem):
"""List the nodes reachable in one step from this node."""
return [self.child_node(problem, action)
for action in problem.actions(self.state)]
def child_node(self, problem, action):
next_state = problem.result(self.state, action)
next_node = Node(next_state, self, action, problem.path_cost(
self.path_cost, self.state, action, next_state))
print(problem.path_cost(
self.path_cost, self.state, action, next_state))
return next_node
def __eq__(self, other):
return isinstance(other, Node) and self.state == other.state
def __hash__(self):
# We use the hash value of the state
# stored in the node instead of the node
# object itself to quickly search a node
# with the same state in a Hash Table
return hash(self.state)
def path(self):
"""Return a list of nodes forming the path from the root to this node."""
node, path_back = self, []
while node:
path_back.append(node)
node = node.parent
return list(reversed(path_back))
class AgentPosition:
def __init__(self, x, y, orientation):
self.X = x
self.Y = y
self.orientation = orientation
def get_location(self):
return self.X, self.Y
def set_location(self, x, y):
self.X = x
self.Y = y
def get_orientation(self):
return self.orientation
def set_orientation(self, orientation):
self.orientation = orientation
def __eq__(self, other):
if (other.get_location() == self.get_location() and
other.get_orientation() == self.get_orientation()):
return True
else:
return False
def __hash__(self):
return hash((self.X, self.Y, self.orientation))
class SweeperAgent:
def __init__(self, dimensions=None):
self.dimrow = dimensions
self.current_position = None
self.orientation = ""
self.initial = set()
self.goal = set()
self.allowed_points = set()
self.puddle_points = set()
def where_am_i(self):
temp_map = [list(item) for item in SweeperAgent.loadMap("map.txt")]
for row in range(MAP_SIZE):
for column, pos in enumerate(temp_map[row]):
if pos == ">" or pos == "<" or pos == "^" or pos == "v":
self.row = row
self.column = column
return row, column
# add orientation
def where_to_go(self):
temp_map = [list(item) for item in SweeperAgent.loadMap("goal_map.txt")]
for row in range(MAP_SIZE):
for column, pos in enumerate(temp_map[row]):
if pos == ">" or pos == "<" or pos == "^" or pos == "v":
self.row = row
self.column = column
return row, column
@staticmethod
def set_allowed(allowed_points):
temp_map = [list(item) for item in SweeperAgent.loadMap('map.txt')]
a_row = 0
a_column = 0
for row in range(MAP_SIZE):
for column, pos in enumerate(temp_map[row]):
if pos == "." or pos == 'p' or pos == '>' or pos == '<' or pos == 'v' or pos == '^':
a_row = row
a_column = column
location = tuple([a_row, a_column])
allowed_points.add(location)
@staticmethod
def set_puddles(puddle_points):
temp_map = [list(item) for item in SweeperAgent.loadMap('map.txt')]
a_row = 0
a_column = 0
for row in range(MAP_SIZE):
for column, pos in enumerate(temp_map[row]):
if pos == "p" :
a_row = row
a_column = column
location = tuple([a_row, a_column])
puddle_points.add(location)
@staticmethod
def get_goal():
temp_map = [list(item) for item in SweeperAgent.loadMap('goal_map.txt')]
a_row = 0
a_column = 0
for row in range(MAP_SIZE):
for column, pos in enumerate(temp_map[row]):
if pos == '>' or pos == '<' or pos == 'v' or pos == '^':
a_row = row
a_column = column
return a_row, a_column
@staticmethod
def set_initial(initial):
temp_map = [list(item) for item in SweeperAgent.loadMap('map.txt')]
a_row = 0
a_column = 0
for row in range(MAP_SIZE):
for column, pos in enumerate(temp_map[row]):
if pos == '>' or pos == '<' or pos == 'v' or pos == '^':
a_row = row
a_column = column
location = tuple([a_row, a_column])
initial.add(location)
@staticmethod
def set_orientation():
temp_map = [list(item) for item in SweeperAgent.loadMap('map.txt')]
orientation = ""
for row in range(MAP_SIZE):
for column, pos in enumerate(temp_map[row]):
if pos == ">":
orientation = "RIGHT"
if pos == "<":
orientation = "LEFT"
if pos == "^":
orientation = "UP"
if pos == "v":
orientation = "DOWN"
return orientation
@staticmethod
def set_goal_orientation():
temp_map = [list(item) for item in SweeperAgent.loadMap('goal_map.txt')]
orientation = ""
for row in range(MAP_SIZE):
for column, pos in enumerate(temp_map[row]):
if pos == ">":
orientation = "RIGHT"
if pos == "<":
orientation = "LEFT"
if pos == "^":
orientation = "UP"
if pos == "v":
orientation = "DOWN"
return orientation
@staticmethod
def run(self):
self.orientation = SweeperAgent.set_orientation()
goal_orientation = SweeperAgent.set_goal_orientation()
#SweeperAgent.set_initial(self.initial)
#SweeperAgent.set_goal(self.goal)
SweeperAgent.set_allowed(self.allowed_points)
SweeperAgent.set_puddles(self.puddle_points)
x, y = self.where_am_i()
x1, y1 = SweeperAgent.get_goal()
agent_position = AgentPosition(x, y, self.orientation)
goal_position = AgentPosition(x1, y1, goal_orientation)
self.plan_route(agent_position, goal_position, self.allowed_points, self.puddle_points)
"""print("allowed: ")
print("(row, column)")
print(sorted(self.allowed_points))
print("puddles:")
print(sorted(self.puddle_points))
print("initial:")
print(self.initial)
print("goal:")
print(self.goal)
print("orientation:")
print(self.orientation)"""
def plan_route(self, current, goals, allowed, puddles):
problem = PlanRoute(current, goals, allowed, puddles)
return SweeperAgent.astar_search(problem, problem.h).solution()
#return SweeperAgent.astar_search(problem, problem.h)
"""TODO"""
# liczenie kosztów
#
@staticmethod
def loadMap(map_name=''):
maze = []
map_folder = path.dirname(__file__)
with open(path.join(map_folder, map_name), 'rt') as f:
for line in f:
maze.append(line.rstrip('\n'))
# print(maze)
return maze
@staticmethod
def astar_search(problem, h=None):
"""A* search is best-first graph search with f(n) = g(n)+h(n).
You need to specify the h function when you call astar_search, or
else in your Problem subclass."""
# h = memoize(h or problem.h, 'h')
return SweeperAgent.best_first_graph_search(problem, lambda n: n.path_cost + h(n))
#return best_first_graph_search(problem)
@staticmethod
#def best_first_graph_search(problem, f, display=False):
def best_first_graph_search(problem, f, display=True):
"""Search the nodes with the lowest f scores first.
You specify the function f(node) that you want to minimize; for example,
if f is a heuristic estimate to the goal, then we have greedy best
first search; if f is node.depth then we have breadth-first search.
There is a subtlety: the line "f = memoize(f, 'f')" means that the f
values will be cached on the nodes as they are computed. So after doing
a best first search you can examine the f values of the path returned."""
# f = memoize(f, 'f')
"""TODO"""
# Zaimplementować klasę Node dla Astar
history = []
node = Node(problem.initial)
frontier = PriorityQueue('min', f)
frontier.append(node)
explored = set()
while frontier:
node = frontier.pop()
if problem.goal_test(node.state):
if display:
print(len(explored), "paths have been expanded and", len(frontier), "paths remain in the frontier")
return node
explored.add(node.state)
for child in node.expand(problem):
if child.state not in explored and child not in frontier:
frontier.append(child)
elif child in frontier:
if f(child) < frontier[child]:
del frontier[child]
frontier.append(child)
return None
class PriorityQueue:
"""A Queue in which the minimum (or maximum) element (as determined by f and
order) is returned first.
If order is 'min', the item with minimum f(x) is
returned first; if order is 'max', then it is the item with maximum f(x).
Also supports dict-like lookup."""
def __init__(self, order='min', f=lambda x: x):
self.heap = []
if order == 'min':
self.f = f
elif order == 'max': # now item with max f(x)
self.f = lambda x: -f(x) # will be popped first
else:
raise ValueError("Order must be either 'min' or 'max'.")
def append(self, item):
"""Insert item at its correct position."""
heapq.heappush(self.heap, (self.f(item), item))
def extend(self, items):
"""Insert each item in items at its correct position."""
for item in items:
self.append(item)
def pop(self):
"""Pop and return the item (with min or max f(x) value)
depending on the order."""
if self.heap:
return heapq.heappop(self.heap)[1]
else:
raise Exception('Trying to pop from empty PriorityQueue.')
def __len__(self):
"""Return current capacity of PriorityQueue."""
return len(self.heap)
def __contains__(self, key):
"""Return True if the key is in PriorityQueue."""
return any([item == key for _, item in self.heap])
def __getitem__(self, key):
"""Returns the first value associated with key in PriorityQueue.
Raises KeyError if key is not present."""
for value, item in self.heap:
if item == key:
return value
raise KeyError(str(key) + " is not in the priority queue")
def __delitem__(self, key):
"""Delete the first occurrence of key."""
try:
del self.heap[[item == key for _, item in self.heap].index(True)]
except ValueError:
raise KeyError(str(key) + " is not in the priority queue")
heapq.heapify(self.heap)
class Test:
@staticmethod
def run():
allowed_points = set()
puddle_points = set()
initial = set()
goal = set()
orientation = SweeperAgent.set_orientation()
SweeperAgent.set_initial(initial)
SweeperAgent.set_goal(goal)
SweeperAgent.set_allowed(allowed_points)
SweeperAgent.set_puddles(puddle_points)
print("allowed: ")
print("(row, column)")
print(sorted(allowed_points))
print("puddles:")
print(sorted(puddle_points))
print("initial:")
print(initial)
print("goal:")
print(goal)
print("orientation:")
print(orientation)

98
astar2_document.txt Normal file
View File

@ -0,0 +1,98 @@
class PlanRoute
actions(state) przyjmuje mape? state
zwraca możliwe akcje agenta
result(state, action) mapa? state, action(string)
tworzy listę możliwych ruchów w liście proposed_loc
sprawdza, czy współrzędne w proposed_loc znajdują się w zbiorze allowed
ustawia kierunek agenta oraz nowe położenie na mapie
zwraca state
goal_test(state) przyjmuje state
sprawdza czy stan docelowy zgadza się ze stanem obecnym
zwraca wartość True lub False
path_cost(c, state1, action, state2)
ocenia nowy koszt po zmianie stanu
zwraca nowy koszt
def h(node) funkcja heurystyki, przyjmuje objekt klasy node
przypisuje zmiennym x i y wartość współrzędnych
za pomocą funkcji get_location()
mamy xy dla stanu obecnego
mamy xy dla stanu docelowego
zwraca ogległość
class Node
expand(problem) przyjmuje klasę problem
tworzy węzły potomne na podstawie możliwych akcji
zwraca listę węzłów potomnych
child_node(problem, action) przyjmuje problem oraz akcję
tworzy węzeł potomny na podstawie otzymanej akcji
zwraca węzeł potomny
class AgentPosition
get_location
zwraca dwie zmienne: X i Y
set_location
ustawia zmienne: X i Y
get_orientation:
zwraca kierunek
set_orientation:
ustawia kierunek
class SweeperAgent - najbardziej tajemnicza klasa, bo do końca nie wiadomo co ma robić
where_am_i() - niby ma zwracać położenie agenta na planszy
set_allowed(allowed_points)
ustawia listę dostępnych miejsc na mapie
set_puddles(puddle_points)
ustawia listę obecnych kałuż
set_goal(goal)
ustawia punkt docelowy
set_initial(initial)
ustawia punkt początkowy
set_orientation()
ustawia kierunek
plan_route() - czarna magia A* (∩ ͝ ° ͜ʖ͡° )⊃━☆゚
load_map() - ładowanie mapy
astar_search() a*
class PriorityQueue - jakaś kolejka priorytetowa

View File

@ -1,7 +1,7 @@
.......
###....
.......
.......
...###.
...#^#.
.......
###.ppp
....p..
....p.p
...###p
...#^#p
......p

BIN
images/puddle.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
images/robot2.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

13
main.py
View File

@ -7,7 +7,7 @@ from grid import *
from settings import *
from sprites import *
from graphsearch import *
from astar2 import *
class Game:
@ -32,6 +32,7 @@ class Game:
self.all_sprites = pg.sprite.Group()
self.walls = pg.sprite.Group()
self.mines = pg.sprite.Group()
self.puddles = pg.sprite.Group()
for row, tiles in enumerate(self.map_data):
for col, tile in enumerate(tiles):
if tile == '2':
@ -42,6 +43,8 @@ class Game:
Grenade(self, col, row)
if tile == "#":
Wall(self, col, row)
if tile == 'p':
Puddle(self, col, row)
if tile == '>':
self.player = Player(self, col, row, Direction.Right.name)
if tile == '^':
@ -49,7 +52,7 @@ class Game:
if tile == '<':
self.player = Player(self, col, row, Direction.Left.name)
if tile == 'v':
self.player = Player(self, col, row. Direction.Down.name)
self.player = Player(self, col, row, Direction.Down.name)
def run(self):
@ -105,6 +108,12 @@ class Game:
player_moves = BFS.run()
self.graph_move(player_moves)
self.wentyl_bezpieczenstwa = 1
if event.key == pg.K_F4 and self.wentyl_bezpieczenstwa == 0:
print("test1")
agent = SweeperAgent()
SweeperAgent.run(agent)
# Test.run()
def graph_move(self, moves):

12
map.txt
View File

@ -1,7 +1,7 @@
.>.....
###....
.......
.......
...###.
...#.#.
.......
###.ppp
....p..
....p.p
...###p
...#.#p
......p

View File

@ -11,8 +11,8 @@ class Player(pg.sprite.Sprite):
pg.sprite.Sprite.__init__(self, self.groups)
self.game = game
#self.image = pg.Surface((TILESIZE, TILESIZE))
self.image = pg.image.load('images/robot.bmp')
self.baseImage = pg.image.load('images/robot.bmp')
self.image = pg.image.load('images/robot2.bmp')
self.baseImage = pg.image.load('images/robot2.bmp')
#self.image.fill(YELLOW)
self.image = pg.transform.scale(self.image, (TILESIZE, TILESIZE))
self.baseImage = pg.transform.scale(self.image, (TILESIZE, TILESIZE))
@ -272,4 +272,19 @@ class Wall(pg.sprite.Sprite):
self.rect.x = self.x * TILESIZE
self.rect.y = self.y * TILESIZE
class Puddle(pg.sprite.Sprite):
def __init__(self, game, x, y):
self.groups = game.all_sprites, game.puddles
pg.sprite.Sprite.__init__(self, self.groups)
self.game = game
self.image = pg.image.load('images/puddle.bmp')
self.image = pg.transform.scale(self.image, (TILESIZE, TILESIZE))
self.rect = self.image.get_rect()
self.x = x
self.y = y
def update(self):
self.rect.x = self.x * TILESIZE
self.rect.y = self.y * TILESIZE

270
todo.txt Normal file
View File

@ -0,0 +1,270 @@
todo:
________________
|'-.--._ _________:
| / | __ __\
| | _ | [\_\= [\_\
| |.' '. \.........|
| ( <) ||: :|_
\ '._.' | :.....: |_(o
'-\_ \ .------./
_ \ ||.---.|| _
/ \ '-._|/\n~~\n' | \
(| []=.--[===[()]===[) |
<\_/ \_______/ _.' /_/
/// (_/_/
|\\ [\\
||:| | I|
|::| | I|
||:| | I|
||:| : \:
|\:| \I|
:/\: ([])
([]) [|
|| |\_
_/_\_ [ -'-.__
<] \> \_____.>
\__/
__...------------._
,-' `-.
,-' `.
,' ,-`.
; `-' `.
; .-. \
; .-. `-' \
; `-' \
; `.
; :
; |
; ;
; ___ ;
; ,-;-','.`.__ |
_..; ,-' ;`,'.`,'.--`. |
///; ,-' `. ,-' ;` ;`,','_.--=: /
|'': ,' : ;` ;,;,,-'_.-._`. ,' IT'S A TRAP!!!
' : ;_.-. `. :' ;;;'.ee. \| /
\.' _..-'/8o. `. : :! ' ':8888) || /
||`-'' \\88o\ : : :! : :`""' ;;/
|| \"88o\; `. \ `. `. ;,'
/) ___ `."'/(--.._ `. `.`. `-..-' ;--.
\(.="""""==.. `'-' `.| `-`-..__.-' `. `.
| `"==.__ ) ) ;
| || `"=== ' .' .'
/\,,|||| | | \ .' .'
| |||'|' |'|' \| .' _.' \
| |\' | | || || .' .' \
' | \ ' |' . ``-- `| || .' .' \
' | ' | . ``-.._ | ; .' .' `.
_.--,;`. . -- ...._,' .' .' `.__
,' ,'; `. . --..__..--'.' .' __/_\
,' ; ; | . --..__.._.' .' ,' `.
/ ; : ; . -.. _.' _.' / `
/ : `-._ | . _.--' _.' |
/ `. `--....--'' _.' |
`._ _..-' |
`-..____...-'' |
|
|
.-.
|_:_|
/(_Y_)\
. ( \/M\/ )
'. _.'-/'-'\-'._
': _/.--'[[[[]'--.\_
': /_' : |::"| : '.\
': // ./ |oUU| \.' :\
': _:'..' \_|___|_/ : :|
':. .' |_[___]_| :.':\
[::\ | : | | : ; : \
'-' \/'.| |.' \ .;.' |
|\_ \ '-' : |
| \ \ .: : | |
| \ | '. : \ |
/ \ :. .; |
/ | | :__/ : \\
| | | \: | \ | ||
/ \ : : |: / |__| /|
| : : :_/_| /'._\ '--|_\
/___.-/_|-' \ \
'-'
.-.__ \ .-. ___ __
|_| '--.-.-( \/\;;\_\.-._______.-.
(-)___ \ \ .-\ \;;\( \ \ \
Y '---._\_((Q)) \;;\\ .-\ __(_)
I __'-' / .--.((Q))---' \,
I ___.-: \| | \'-'_ \
A .-' \ .-.\ \ \ \ '--.__ '\
| |____.----((Q))\ \__|--\_ \ '
( ) '-' \_ : \-' '--.___\
Y \ \ \ \(_)
I \ \ \ \,
I \ \ \ \
A \ \ \ '\
| \ \__| '
\_:. \
\ \ \
\ \ \
\_\_|
.==.
()''()-.
.---. ;--; /
.'_:___". _..'. __'.
|__ --==|'-''' \'...;
[ ] :[| |---\
|__| I=[| .' '.
/ / ____| : '._
|-/.____.' | : :
snd /___\ /___\ '-'._----'
___ |\________/)
[_,_]) \ / \|
/|=T=|] / __ __\
|\ " // |_ 9 p ]\
||'-'/--. / /\ =| \|\ \
/|| <\/> |\ | '._, @ @)<_)
| |\ | | \.__/(_;_)
| . H | | : '='|
| | _H__/ _| : |
\ '.__ \ / ; ';
__'-._(_}==.' : ;
(___| /-' | :. :
[.-' \ | \ \ ; :
.-' | | | | ":
/ |==| \ \ / \_
/ [ | '._\_ -._ \
/ \__) __.- \ \ )\\
/ | /.' >>)
| \ |\ |
| .' '-. | \ /
| / / / / /
snd | /
._,.
"..-..pf.
-L ..#'
.+_L ."]#
,'j' .+.j` -'.__..,.,p.
_~ #..<..0. .J-.``..._f.
.7..#_.. _f. .....-..,`4'
;` ,#j. T' .. ..J....,'.j`
.` .."^.,-0.,,,,yMMMMM,. ,-.J...+`.j@
.'.`...' .yMMMMM0M@^=`""g.. .'..J..".'.jH
j' .'1` q'^)@@#"^".`"='BNg_...,]_)'...0-
.T ...I. j" .'..+,_.'3#MMM0MggCBf....F.
j/.+'.{..+ `^~'-^~~""""'"""?'"``'1`
.... .y.} `.._-:`_...jf
g-. .Lg' ..,..'-....,'.
.'. .Y^ .....',].._f
......-f. .-,,.,.-:--&`
.`...'..`_J`
.~......'#'
'..,,.,_]`
.L..`..``.
,ooo888888888888888oooo,
o8888YYYYYY77iiiiooo8888888o
8888YYYY77iiYY8888888888888888
[88YYY77iiY88888888888888888888]
88YY7iYY888888888888888888888888
[88YYi 88888888888888888888888888]
i88Yo8888888888888888888888888888i
i] ^^^88888888^^^ o [i
oi8 i o8o i 8io
,77788o ^^ ,oooo8888888ooo, ^ o88777,
7777788888888888888888888888888888877777
77777888888888888888888888888888877777
77777788888888^7777777^8888888777777
,oooo888 ooo 88888778888^7777ooooo7777^8887788888 ,o88^^^^888oo
o8888777788[];78 88888888888888888888888888888888888887 7;8^ 888888888oo^88
o888888iii788 ]; o 78888887788788888^;;^888878877888887 o7;[]88888888888888o
88888877 ii78[]8;7o 7888878^ ^8788^;;;;;;^878^ ^878877 o7;8 ]878888888888888
[88888888887888 87;7oo 777888o8888^;ii;;ii;^888o87777 oo7;7[]8778888888888888
88888888888888[]87;777oooooooooooooo888888oooooooooooo77;78]88877i78888888888
o88888888888888 877;7877788777iiiiiii;;;;;iiiiiiiii77877i;78] 88877i;788888888
88^;iiii^88888 o87;78888888888888888888888888888888888887;778] 88877ii;7788888
;;;iiiii7iiii^ 87;;888888888888888888888888888888888888887;778] 888777ii;78888
;iiiii7iiiii7iiii77;i88888888888888888888i7888888888888888877;77i 888877777ii78
iiiiiiiiiii7iiii7iii;;;i7778888888888888ii7788888888888777i;;;;iiii 88888888888
i;iiiiiiiiiiii7iiiiiiiiiiiiiiiiiiiiiiiiii8877iiiiiiiiiiiiiiiiiii877 88888
ii;;iiiiiiiiiiiiii;;;ii^^^;;;ii77777788888888888887777iii;; 77777 78
77iii;;iiiiiiiiii;;;ii;;;;;;;;;^^^^8888888888888888888777ii;; ii7 ;i78
^ii;8iiiiiiii ';;;;ii;;;;;;;;;;;;;;;;;;^^oo ooooo^^^88888888;;i7 7;788
o ^;;^^88888^ 'i;;;;;;;;;;;;;;;;;;;;;;;;;;;^^^88oo^^^^888ii7 7;i788
88ooooooooo ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 788oo^;; 7;i888
887ii8788888 ;;;;;;;ii;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;^87 7;788
887i8788888^ ;;;;;;;ii;;;;;;;oo;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,,, ;;888
87787888888 ;;;;;;;ii;;;;;;;888888oo;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,,;i788
87i8788888^ ';;;ii;;;;;;;8888878777ii8ooo;;;;;;;;;;;;;;;;;;;;;;;;;;i788 7
77i8788888 ioo;;;;;;oo^^ooooo ^7i88^ooooo;;;;;;;;;;;;;;;;;;;;i7888 78
7i87788888o 7;ii788887i7;7;788888ooooo7888888ooo;;;;;;;;;;;;;;oo ^^^ 78
i; 7888888^ 8888^o;ii778877;7;7888887;;7;7788878;878;; ;;;;;;;i78888o ^
i8 788888 [88888^^ ooo ^^^^^;;77888^^^^;;7787^^^^ ^^;;;; iiii;i78888888
^8 7888^ [87888 87 ^877i;i8ooooooo8778oooooo888877ii; iiiiiiii788888888
^^^ [7i888 87;; ^8i;;i7888888888888888887888888 i7iiiiiii88888^^
87;88 o87;;;;o 87i;;;78888788888888888888^^ o 8ii7iiiiii;;
87;i8 877;77888o ^877;;;i7888888888888^^ 7888 78iii7iii7iiii
^87; 877;778888887o 877;;88888888888^ 7ii7888 788oiiiiiiiii
^ 877;7 7888888887 877i;;8888887ii 87i78888 7888888888
[87;;7 78888888887 87i;;888887i 87ii78888 7888888888]
877;7 7788888888887 887i;887i^ 87ii788888 78888888888
87;i8 788888888888887 887ii;;^ 87ii7888888 78888888888
[87;i8 7888888888888887 ^^^^ 87ii77888888 78888888888
87;;78 7888888888888887ii 87i78888888 778888888888
87;788 7888888888888887i] 87i78888888 788888888888
[87;88 778888888888888887 7ii78888888 788888888888
87;;88 78888888888888887] ii778888888 78888888888]
7;;788 7888888888888888] i7888888888 78888888888'
7;;788 7888888888888888 'i788888888 78888888888
7;i788 788888888888888] 788888888 77888888888]
'7;788 778888888888888] [788888888 78888888888'
';77888 78888888888888 8888888888 7888888888]
778888 78888888888888 8888888888 7888888888]
78888 7888888888888] [8888888888 7888888888
7888 788888888888] 88888888888 788888888]
778 78888888888] ]888888888 778888888]
oooooo ^88888^ ^88888^^^^^^^^8888]
87;78888ooooooo8o ,oooooo oo888oooooo
[877;i77888888888] [;78887i8888878i7888;
^877;;ii7888ii788 ;i777;7788887787;778;
^87777;;;iiii777 ;77^^^^^^^^^^^^^^^^;;
^^^^^^^^^ii7] ^ o88888888877iiioo
77777o [88777777iiiiii;;778
77777iii 8877iiiii;;;77888888]
77iiii;8 [77ii;778 788888888888
7iii;;88 iii;78888 778888888888
77i;78888] ;;;;i88888 78888888888
,7;78888888 [;;i788888 7888888888]
i;788888888 ;i7888888 7888888888
;788888888] i77888888 788888888]
';88888888' [77888888 788888888]
[[8ooo88] 78888888 788888888
[88888] 78888888 788888888
^^^ [7888888 77888888]
88888888 7888887
77888888 7888887
;i88888 788888i
,;;78888 788877i7
,7;;i;777777i7i;;7
87778^^^ ^^^^87778
^^^^ o777777o ^^^
o77777iiiiii7777o
7777iiii88888iii777
;;;i7778888888877ii;;
Imperial Stormtrooper [i77888888^^^^8888877i]
(Standard Shock Trooper) 77888^oooo8888oooo^8887]
[788888888888888888888888]
88888888888888888888888888
]8888888^iiiiiiiii^888888]
iiiiiiiiiiiiiiiiiiiiii
^^^^^^^^^^^^^