05.05 v.1: A*

This commit is contained in:
ulazho 2023-05-05 01:24:45 +02:00
parent 40b5ce787d
commit fb6511b05b
8 changed files with 179 additions and 84 deletions

19
.vscode/launch.json vendored Normal file
View 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
View 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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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