Merge pull request 'bfs_implementation' (#10) from bfs_implementation into main

Reviewed-on: s473634/TurboTraktor#10
This commit is contained in:
Daria Dworzyńska 2023-04-23 20:54:10 +02:00
commit 4c28f5a049
12 changed files with 189 additions and 53 deletions

Binary file not shown.

33
main.py
View File

@ -1,10 +1,11 @@
import pygame import pygame
import sys import sys
import random import random
from settings import screen_height, screen_width, SIZE, SPECIES, block_size, tile, road_coords from settings import screen_height, screen_width, SIZE, SPECIES, block_size, tile, road_coords, directions
from src.map import drawRoads, seedForFirstTime from src.map import drawRoads, seedForFirstTime
from src.Tractor import Tractor from src.Tractor import Tractor
from src.Plant import Plant from src.Plant import Plant
from src.bfs import BFS
# pygame initialization # pygame initialization
pygame.init() pygame.init()
@ -21,20 +22,29 @@ background.fill((90,50,20))
background = drawRoads(background) background = drawRoads(background)
for line in range(26): for line in range(26):
pygame.draw.line(background, (0, 0, 0), (0, line * 36), (SIZE[0], line * 36)) pygame.draw.line(background, (0, 0, 0), (0, line * block_size), (screen_width, line * block_size))
pygame.draw.line(background, (0, 0, 0), (line * 36, 0), (line * 36, SIZE[1])) pygame.draw.line(background, (0, 0, 0), (line * block_size, 0), (line * block_size, screen_height))
#TRACTOR #TRACTOR
tractor = Tractor('oil','manual', 'fuel', 'fertilizer1') tractor = Tractor('oil','manual', 'fuel', 'fertilizer1', 20)
tractor_group = pygame.sprite.Group() tractor_group = pygame.sprite.Group()
tractor.rect.x = 0
tractor.rect.y = 0
tractor_group.add(tractor) tractor_group.add(tractor)
#PLANTS #PLANTS
plant_group = pygame.sprite.Group() plant_group = pygame.sprite.Group()
plant_group = seedForFirstTime() plant_group = seedForFirstTime()
#
tractor_move = pygame.USEREVENT + 1
pygame.time.set_timer(tractor_move, 800)
moves = []
goal_bfs = BFS()
destination = (random.randrange(0, 936, 36), random.randrange(0, 900, 36))
print("Destination: ", destination)
moves = goal_bfs.search(
[tractor.rect.x, tractor.rect.y, directions[tractor.rotation]], destination)
if __name__ == "__main__": if __name__ == "__main__":
running = True running = True
@ -49,11 +59,16 @@ if __name__ == "__main__":
tractor.collect(plant_group) tractor.collect(plant_group)
if event.key == pygame.K_ESCAPE: if event.key == pygame.K_ESCAPE:
running = False running = False
if event.type == tractor_move:
Tractor.movement(tractor) if len(moves) != 0:
step = moves.pop()
tractor.movement(step[0])
Tractor.movement_using_keys(tractor)
screen.blit(background,(0,0)) screen.blit(background,(0,0))
plant_group.draw(screen) plant_group.draw(screen)
tractor_group.draw(screen) tractor_group.draw((screen))
tractor_group.update() tractor_group.update()
pygame.display.flip() pygame.display.flip()
clock.tick(60) clock.tick(60)

View File

@ -12,4 +12,6 @@ road_coords = [0, 5, 10, 15, 20, 25]
field_width = 4 field_width = 4
field_height = 4 field_height = 4
field_size = field_width*field_height field_size = field_width*field_height
fields_amount = 25 fields_amount = 26
directions = {0: 'UP', 90: 'RIGHT', 180: 'DOWN', 270: 'LEFT'}

View File

@ -1,4 +1,5 @@
import pygame import pygame
from settings import block_size
class Plant(pygame.sprite.Sprite): class Plant(pygame.sprite.Sprite):
def __init__(self,species,is_ill,pos_x,pos_y): def __init__(self,species,is_ill,pos_x,pos_y):
@ -43,7 +44,7 @@ class Plant(pygame.sprite.Sprite):
self.pic_path="assets/Wheat.png" self.pic_path="assets/Wheat.png"
self.image = pygame.image.load(self.pic_path) #zmienic self.image = pygame.image.load(self.pic_path) #zmienic
self.image = pygame.transform.scale(self.image,(36,36)) self.image = pygame.transform.scale(self.image,(block_size, block_size))
self.rect = self.image.get_rect() self.rect = self.image.get_rect()
self.rect.center = [pos_x,pos_y] self.rect.center = [pos_x,pos_y]

View File

@ -1,60 +1,103 @@
import pygame import pygame
from settings import block_size, tile
class Tractor(pygame.sprite.Sprite): class Tractor(pygame.sprite.Sprite):
def __init__(self,engine,transmission,fuel,fertilizer): def __init__(self, engine, transmission, fuel, fertilizer, capacity):
super().__init__() super().__init__()
self.image=pygame.image.load("assets/tractor/tractor.png") self.image = pygame.image.load("assets/tractor/tractor.png")
self.image=pygame.transform.scale(self.image,(36,36)) self.image = pygame.transform.scale(self.image, tile)
self.UP = pygame.transform.rotate(self.image, 0) self.rect = self.image.get_rect()
self.DOWN = pygame.transform.rotate(self.image, 180)
self.LEFT = pygame.transform.rotate(self.image, 90) self.up = pygame.transform.rotate(self.image, 0)
self.RIGHT = pygame.transform.rotate(self.image, -90) self.down = pygame.transform.rotate(self.image, 180)
self.rect = self.image.get_rect() self.left = pygame.transform.rotate(self.image, 90)
self.right = pygame.transform.rotate(self.image, -90)
self.rect.x = 0
self.rect.y = 0
self.direction = 'F'
self.rotation = 90
self.engine=engine self.collected = 0
self.transmission=transmission self.capacity = capacity
self.fuel=fuel self.engine = engine
self.fertilizer=fertilizer self.transmission = transmission
self.fuel = fuel
self.fertilizer = fertilizer
def movement(self): def movement_using_keys(self):
keys = pygame.key.get_pressed() keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and self.rect.x>0: if keys[pygame.K_LEFT]:
self.image = self.LEFT self.movement('L')
self.rect.x -= 36 if keys[pygame.K_RIGHT]:
if keys[pygame.K_RIGHT] and self.rect.x<900: self.movement('R')
self.image = self.RIGHT if keys[pygame.K_UP]:
self.rect.x += 36 self.movement('F')
if keys[pygame.K_UP] and self.rect.y>0:
self.image = self.UP
self.rect.y -= 36
if keys[pygame.K_DOWN] and self.rect.y<900:
self.image = self.DOWN
self.rect.y += 36
def collect(self,plant_group):
self.plant_group=plant_group
print("collected plant")
pygame.sprite.spritecollide(self,self.plant_group,True)
# collected=collected+1
# print("plants in trunk "+collected)
def water_plant(self,plant_group): #waits between moves to avoid moving to fast
self.plant_group=plant_group pygame.time.wait(100)
def move_forward(self):
if self.rect.y > 0 and self.rotation == 0:
self.rect.y -= block_size
if self.rect.x < 900 and self.rotation == 90:
self.rect.x += block_size
if self.rect.y < 900 and self.rotation == 180:
self.rect.y += block_size
if self.rect.x > 0 and self.rotation == 270:
self.rect.x -= block_size
def move_left(self):
self.rotation -= 90
if self.rotation < 0:
self.rotation = 270
def move_right(self):
self.rotation += 90
if self.rotation >= 360:
self.rotation = 0
def check_rotation(self):
if self.rotation == 0:
self.image = self.up
elif self.rotation == 90:
self.image = self.right
elif self.rotation == 180:
self.image = self.down
elif self.rotation == 270:
self.image = self.left
def movement(self, direction):
if direction == 'F':
self.move_forward()
elif direction == 'L':
self.move_left()
elif direction == 'R':
self.move_right()
self.check_rotation()
def collect(self, plant_group):
if self.collected <= self.capacity:
self.plant_group=plant_group
# print("collected plant")
pygame.sprite.spritecollide(self, self.plant_group, True)
self.collected += 1
# print("plants in trunk "+collected)
def water_plant(self, plant_group):
self.plant_group = plant_group
print("watered plant") print("watered plant")
# def update(self):
# self.rect.center=pygame.mouse.get_pos()
def fertilize(self, plant_group): def fertilize(self, plant_group):
self.plant_group=plant_group self.plant_group = plant_group
print("fertilize") print("fertilize")
def plant(self, plant_group): def plant(self, plant_group):
self.plant_group=plant_group self.plant_group = plant_group
print("new plant") print("new plant")
def find_nearest_plant(self,plant_group): def find_nearest_plant(self, plant_group):
self.plant_group=plant_group self.plant_group = plant_group

Binary file not shown.

Binary file not shown.

75
src/bfs.py Normal file
View File

@ -0,0 +1,75 @@
from settings import block_size, screen_width, directions
import copy
class Node:
def __init__(self, state, parent=None, action=None):
self.state = state
self.parent = parent
self.action = action
class BFS:
def __init__(self):
self.fringe = []
self.explored = []
def successor(self, state):
pos_x, pos_y, rotation = state
options = []
if rotation == directions[0]:
states = [(pos_x, pos_y - block_size, directions[0]), (pos_x, pos_y, directions[270]), (pos_x, pos_y, directions[90])]
actions = ['F', 'L', 'R']
elif rotation == directions[90]:
states = [(pos_x + block_size, pos_y, directions[90]), (pos_x, pos_y, directions[0]), (pos_x, pos_y, directions[180])]
actions = ['F', 'L', 'R']
elif rotation == directions[180]:
states = [(pos_x, pos_y + block_size, directions[180]), (pos_x, pos_y, directions[90]), (pos_x, pos_y, directions[270])]
actions = ['F', 'L', 'R']
elif rotation == directions[270]:
states = [(pos_x - block_size, pos_y, directions[270]), (pos_x, pos_y, directions[0]), (pos_x, pos_y, directions[180])]
actions = ['F', 'L', 'R']
for s, a in zip(states, actions):
if self.valid_state(s):
options.append((a, s))
return options
def valid_state(self, state):
pos_x, pos_y, rotation = state
if pos_x < 0 or pos_x >= screen_width or pos_y < 0 or pos_y >= screen_width:
return False
return True
def goal_path(self, elem):
path = []
while elem.parent:
path.append([elem.action, elem.state[0], elem.state[1]])
elem = elem.parent
path = path[::-1]
return path
def search(self, istate, goaltest):
x, y, rotation = istate
start_node = Node((x, y, rotation))
self.fringe.append(start_node)
while True:
if len(self.fringe) == 0:
return False
elem = self.fringe.pop(0)
if elem.state[0] == goaltest[0] and elem.state[1] == goaltest[1]:
return self.goal_path(elem)
self.explored.append(elem.state)
for (action, state) in self.successor(elem.state):
if state not in self.explored:
x = Node(state, elem, action)
self.fringe.append(x)