05.05 v.1: A*
This commit is contained in:
parent
40b5ce787d
commit
fb6511b05b
19
.vscode/launch.json
vendored
Normal file
19
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "Python: Current File",
|
||||||
|
"type": "python",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${file}",
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"justMyCode": true,
|
||||||
|
"cwd": "${fileDirname}"
|
||||||
|
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
72
src/Field.py
Normal file
72
src/Field.py
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
|
||||||
|
class Field:
|
||||||
|
Nodes = []
|
||||||
|
FieldSizeX = 0
|
||||||
|
FieldSizeY = 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def __getitem__(self, pos):
|
||||||
|
X, Y = pos
|
||||||
|
return self.Nodes[X][Y].Type
|
||||||
|
|
||||||
|
def __setitem__(self, pos, value):
|
||||||
|
X, Y = pos
|
||||||
|
self.Nodes[X][Y].Type = value
|
||||||
|
|
||||||
|
def __init__(self, tilemap):
|
||||||
|
self.FieldSizeX = len(tilemap) - 1
|
||||||
|
self.FieldSizeY = len(tilemap[0]) - 1
|
||||||
|
if(tilemap != []):
|
||||||
|
for x in range(0, self.FieldSizeX + 1):
|
||||||
|
self.Nodes.append([])
|
||||||
|
for y in range(0, self.FieldSizeY + 1):
|
||||||
|
|
||||||
|
node = Node(x, y, tilemap[x][y])
|
||||||
|
self.Nodes[x].append(node)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def PrintField(self):
|
||||||
|
for x in range(len(self.Nodes)):
|
||||||
|
print()
|
||||||
|
for y in range(len(self.Nodes[0])):
|
||||||
|
print(self.Nodes[x][y].Type, end=' ')
|
||||||
|
|
||||||
|
def Neighbors(field, pos):
|
||||||
|
x, y, dir = pos
|
||||||
|
neighbors = []
|
||||||
|
if(x == 11):
|
||||||
|
x = 11
|
||||||
|
if(x > 0 and field[x - 1, y] != TREE and dir == 3):
|
||||||
|
neighbors.append((x - 1, y, dir))
|
||||||
|
if(y > 0 and field[x, y - 1] != TREE and dir == 0):
|
||||||
|
neighbors.append((x, y - 1, dir))
|
||||||
|
if(x < field.FieldSizeX and field[x + 1, y] != TREE and dir == 1):
|
||||||
|
neighbors.append((x+1, y, dir))
|
||||||
|
if(y < field.FieldSizeY and field[x, y+1] != TREE and dir == 2):
|
||||||
|
neighbors.append((x, y+1, dir))
|
||||||
|
neighbors.append((x, y, (dir + 1) % 4))
|
||||||
|
if(dir == 0):
|
||||||
|
neighbors.append((x, y, 3))
|
||||||
|
else:
|
||||||
|
neighbors.append((x, y, dir - 1))
|
||||||
|
return neighbors
|
||||||
|
|
||||||
|
class Node:
|
||||||
|
X = 0
|
||||||
|
Y = 0
|
||||||
|
Type = None
|
||||||
|
|
||||||
|
def __init__(self, X, Y, Type):
|
||||||
|
self.X = X
|
||||||
|
self.Y = Y
|
||||||
|
self.Type = Type
|
||||||
|
|
||||||
|
|
||||||
|
SHORT = 1
|
||||||
|
TALL = 80
|
||||||
|
TREE = 100
|
||||||
|
|
||||||
|
|
||||||
|
|
BIN
src/__pycache__/Bee.cpython-310.pyc
Normal file
BIN
src/__pycache__/Bee.cpython-310.pyc
Normal file
Binary file not shown.
BIN
src/__pycache__/Beehive.cpython-310.pyc
Normal file
BIN
src/__pycache__/Beehive.cpython-310.pyc
Normal file
Binary file not shown.
BIN
src/__pycache__/Field.cpython-310.pyc
Normal file
BIN
src/__pycache__/Field.cpython-310.pyc
Normal file
Binary file not shown.
BIN
src/__pycache__/Flower.cpython-310.pyc
Normal file
BIN
src/__pycache__/Flower.cpython-310.pyc
Normal file
Binary file not shown.
BIN
src/__pycache__/Frames.cpython-310.pyc
Normal file
BIN
src/__pycache__/Frames.cpython-310.pyc
Normal file
Binary file not shown.
172
src/main.py
172
src/main.py
@ -3,7 +3,9 @@ import random
|
|||||||
import Flower
|
import Flower
|
||||||
import Beehive
|
import Beehive
|
||||||
import Frames
|
import Frames
|
||||||
|
from Field import Field, Neighbors
|
||||||
|
from queue import Queue
|
||||||
|
import heapq as h
|
||||||
|
|
||||||
white = (255, 255, 255)
|
white = (255, 255, 255)
|
||||||
|
|
||||||
@ -23,11 +25,18 @@ pygame.display.set_icon(setIcon)
|
|||||||
|
|
||||||
|
|
||||||
### tilemap
|
### tilemap
|
||||||
SHORT = 0
|
SHORT = 1
|
||||||
TALL = 1
|
TALL = 80
|
||||||
TREE = 10
|
TREE = 100
|
||||||
BEE = pygame.image.load('spritesNtiles/bee64.png')
|
BEE = pygame.image.load('spritesNtiles/bee64.png')
|
||||||
|
|
||||||
|
Directions = {
|
||||||
|
0 : 'north',
|
||||||
|
1 : 'east',
|
||||||
|
2 : 'south',
|
||||||
|
3 : 'west'
|
||||||
|
}
|
||||||
|
|
||||||
tiles = {
|
tiles = {
|
||||||
SHORT: pygame.image.load('spritesNtiles/shortGrass64.png'),
|
SHORT: pygame.image.load('spritesNtiles/shortGrass64.png'),
|
||||||
TALL: pygame.image.load('spritesNtiles/tallGrass64.png'),
|
TALL: pygame.image.load('spritesNtiles/tallGrass64.png'),
|
||||||
@ -49,8 +58,10 @@ tilemap = [
|
|||||||
[SHORT, SHORT, SHORT, SHORT, TALL, SHORT, SHORT, SHORT, SHORT, SHORT, SHORT, SHORT, TALL, SHORT, SHORT],
|
[SHORT, SHORT, SHORT, SHORT, TALL, SHORT, SHORT, SHORT, SHORT, SHORT, SHORT, SHORT, TALL, SHORT, SHORT],
|
||||||
|
|
||||||
]
|
]
|
||||||
tilemapSizeY = 12
|
|
||||||
tilemapSizeX = 15
|
|
||||||
|
tilemapSizeX = 12
|
||||||
|
tilemapSizeY = 15
|
||||||
tileSize = 64
|
tileSize = 64
|
||||||
###
|
###
|
||||||
|
|
||||||
@ -78,57 +89,76 @@ dis = pygame.display.set_mode((disX, disY))
|
|||||||
clock = pygame.time.Clock()
|
clock = pygame.time.Clock()
|
||||||
|
|
||||||
#position of the bee and pos changings
|
#position of the bee and pos changings
|
||||||
bee_x = 1
|
bee_x = 2
|
||||||
bee_y = 0
|
bee_y = 1
|
||||||
bee_dir = 'west'
|
bee_dir = 'west'
|
||||||
|
|
||||||
# tall grass counter
|
field = Field(tilemap)
|
||||||
tall_grass_counter = 0
|
|
||||||
def createGraph(tilemap):
|
|
||||||
graph = {}
|
|
||||||
for y in range(tilemapSizeY):
|
|
||||||
for x in range(tilemapSizeX):
|
|
||||||
if tilemap[y][x] != TREE:
|
|
||||||
node = {}
|
|
||||||
if y > 0 and tilemap[y-1][x] != TREE:
|
|
||||||
node[(x,y-1)] = 1
|
|
||||||
if y < tilemapSizeY-1 and tilemap[y+1][x] != TREE:
|
|
||||||
node[(x,y+1)] = 1
|
|
||||||
if x > 0 and tilemap[y][x-1] != TREE:
|
|
||||||
node[(x-1,y)] = 1
|
|
||||||
if x < tilemapSizeX-1 and tilemap[y][x+1] != TREE:
|
|
||||||
node[(x+1,y)] = 1
|
|
||||||
graph[(x,y)] = node
|
|
||||||
return graph
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def Manhattan_dis(start, end):
|
||||||
|
start_x, start_y = start
|
||||||
|
end_x, end_y = end
|
||||||
|
return abs(start_x - end_x) + abs(start_y - end_y)
|
||||||
|
|
||||||
graph = createGraph(tilemap)
|
def Make_path(start, end, previos):
|
||||||
|
path = [end]
|
||||||
|
while start not in path:
|
||||||
def bfs(graph, start, end):
|
path.append(previos[path[-1]])
|
||||||
queue = [(start, [start])]
|
path.reverse()
|
||||||
visited = set()
|
|
||||||
while queue:
|
|
||||||
(node, path) = queue.pop(0)
|
|
||||||
if node == end:
|
|
||||||
return path
|
return path
|
||||||
if node not in visited:
|
|
||||||
visited.add(node)
|
def A_star(field, start, end):
|
||||||
for neighbor in graph[node]:
|
open = []
|
||||||
if neighbor not in visited and neighbor not in path and tilemap[neighbor[1]][neighbor[0]] != TREE:
|
previous = {}
|
||||||
queue.append((neighbor, path + [neighbor]))
|
closed = set()
|
||||||
return None
|
checked = set()
|
||||||
|
now = (0, start)
|
||||||
|
h.heappush(open, (0, start))
|
||||||
|
while len(open) > 0:
|
||||||
|
now = h.heappop(open)
|
||||||
|
if now[1] in closed:
|
||||||
|
continue
|
||||||
|
if now[1][0:2] == end:
|
||||||
|
|
||||||
|
path = Make_path(start, now[1], previous)
|
||||||
|
return path
|
||||||
|
closed.add(now[1])
|
||||||
|
checked.add(now[1][0:2])
|
||||||
|
for x in Neighbors(field, now[1]):
|
||||||
|
if x not in closed and x not in checked:
|
||||||
|
previous[x] = now[1]
|
||||||
|
if now[1][0:2] != x[0:2]:
|
||||||
|
added_cost = field[x[0], x[1]] + Manhattan_dis(x[0:2], end)
|
||||||
|
else : added_cost = 0
|
||||||
|
h.heappush(open, (now[0] + added_cost, x))
|
||||||
|
checked.add(x)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
while True:
|
||||||
|
random_x = random.randint(0, tilemapSizeX-2)
|
||||||
|
random_y = random.randint(0, tilemapSizeY-2)
|
||||||
|
if(field[random_x, random_y] != TREE):
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
random_x = random.randint(0, tilemapSizeX-1)
|
|
||||||
random_y = random.randint(0, tilemapSizeY-1)
|
|
||||||
print(random_x, random_y)
|
print(random_x, random_y)
|
||||||
path = bfs(graph, (bee_x, bee_y), (random_x, random_y))
|
|
||||||
|
|
||||||
# set starting node to first node in path
|
|
||||||
|
path_A_star = A_star(field, (bee_x, bee_y, 3), (random_x, random_y))
|
||||||
|
check_path_A = []
|
||||||
|
for x in path_A_star:
|
||||||
|
if x[0:2] not in check_path_A:
|
||||||
|
check_path_A.append(x[0:2])
|
||||||
|
print(check_path_A)
|
||||||
|
path = path_A_star
|
||||||
|
|
||||||
|
|
||||||
current_node = 0
|
current_node = 0
|
||||||
|
step = 1
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
# check for events
|
# check for events
|
||||||
@ -137,49 +167,15 @@ while True:
|
|||||||
pygame.quit()
|
pygame.quit()
|
||||||
quit()
|
quit()
|
||||||
|
|
||||||
# get next node in path if bee has reached current node
|
bee_x, bee_y, bee_dir = path[current_node]
|
||||||
if bee_x == path[current_node][0] and bee_y == path[current_node][1]:
|
|
||||||
current_node += 1
|
|
||||||
if current_node >= len(path):
|
|
||||||
current_node = 0
|
|
||||||
|
|
||||||
# move bee towards next node in path
|
bee_dir = Directions[bee_dir]
|
||||||
next_node = path[current_node]
|
|
||||||
if bee_x < next_node[0]:
|
|
||||||
bee_x += 1
|
|
||||||
bee_dir = 'east'
|
|
||||||
print(bee_x, bee_y)
|
|
||||||
elif bee_x > next_node[0]:
|
|
||||||
bee_x -= 1
|
|
||||||
bee_dir = 'west'
|
|
||||||
print(bee_x, bee_y)
|
|
||||||
elif bee_y < next_node[1]:
|
|
||||||
bee_y += 1
|
|
||||||
bee_dir = 'south'
|
|
||||||
print(bee_x, bee_y)
|
|
||||||
elif bee_y > next_node[1]:
|
|
||||||
bee_y -= 1
|
|
||||||
bee_dir = 'north'
|
|
||||||
print(bee_x, bee_y)
|
|
||||||
# check for collision with the screen edges
|
|
||||||
if bee_x < 0:
|
|
||||||
bee_x = 0
|
|
||||||
bee_dir = 'east'
|
|
||||||
elif bee_x >= tilemapSizeX:
|
|
||||||
bee_x = tilemapSizeX - 1
|
|
||||||
bee_dir = 'west'
|
|
||||||
elif bee_y < 0:
|
|
||||||
bee_y = 0
|
|
||||||
bee_dir = 'south'
|
|
||||||
elif bee_y >= tilemapSizeY:
|
|
||||||
bee_y = tilemapSizeY - 1
|
|
||||||
bee_dir = 'north'
|
|
||||||
|
|
||||||
# render the bee and the tilemap
|
# render the bee and the tilemap
|
||||||
dis.fill(white)
|
dis.fill(white)
|
||||||
for y in range(tilemapSizeY):
|
|
||||||
for x in range(tilemapSizeX):
|
for x in range(tilemapSizeX):
|
||||||
tile = tilemap[y][x]
|
for y in range(tilemapSizeY):
|
||||||
|
tile = tilemap[x][y]
|
||||||
dis.blit(tiles[tile], (x * tileSize, y * tileSize))
|
dis.blit(tiles[tile], (x * tileSize, y * tileSize))
|
||||||
|
|
||||||
# rotate and render the bee
|
# rotate and render the bee
|
||||||
@ -195,5 +191,13 @@ while True:
|
|||||||
dis.blit(bee_image, (bee_x * tileSize, bee_y * tileSize))
|
dis.blit(bee_image, (bee_x * tileSize, bee_y * tileSize))
|
||||||
pygame.display.update()
|
pygame.display.update()
|
||||||
|
|
||||||
clock.tick(1)
|
clock.tick(5)
|
||||||
|
|
||||||
|
if(current_node + 1 == len(path)):
|
||||||
|
step *= -1
|
||||||
|
if(step == -1 and current_node == 0):
|
||||||
|
step *= -1
|
||||||
|
current_node += step
|
||||||
|
|
||||||
|
|
||||||
|
## setitem, bfs
|
Loading…
Reference in New Issue
Block a user