graph search

This commit is contained in:
s464923 2024-05-18 17:10:56 +02:00
parent fb4cd44b61
commit 8fcf4fad2b
4 changed files with 120 additions and 155 deletions

View File

@ -2,59 +2,55 @@ import pygame
from constant import size, rows, cols
import random
class Board:
def __init__(self):
self.board = []
self.load_images()
self.generate_board()
def load_images(self):
self.grass = pygame.image.load("board/grass.png")
self.dirt = pygame.image.load("board/dirt.png")
self.rock= pygame.image.load("board/rock.png")
self.weeds = pygame.image.load("board/weeds.png")
self.rock = pygame.image.load("board/rock.png")
self.weeds = pygame.image.load("board/weeds.png")
self.soil = pygame.image.load("board/zyzna.png")
def generate_board(self):
self.board = [[random.choice([0,1,2,3,4,5,6,7,8,9]) for _ in range(rows)] for _ in range(cols)]
self.board = [[random.choice([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) for _ in range(cols)] for _ in range(rows)]
def draw_cubes(self, win):
for row in range(rows):
for col in range(cols):
cube_rect = pygame.Rect(row * size, col * size, size, size)
cube=self.board[row][col]
if row==4 and col==4:
cube_rect = pygame.Rect(col * size, row * size, size, size)
cube = self.board[row][col]
if row == 4 and col == 4:
win.blit(self.grass, cube_rect)
elif cube == 0:
rock_scale = pygame.transform.scale(self.rock, (size, size))
win.blit(self.dirt, cube_rect)
win.blit(rock_scale, cube_rect)
win.blit(rock_scale, cube_rect)
elif cube == 1:
weed_scale = pygame.transform.scale(self.weeds, (size,size))
weed_scale = pygame.transform.scale(self.weeds, (size, size))
win.blit(self.grass, cube_rect)
win.blit(weed_scale, cube_rect)
elif cube in(2,3,4,5):
win.blit(self.grass, cube_rect)
elif cube in (2, 3, 4, 5):
win.blit(self.grass, cube_rect)
elif cube == 10:
win.blit(self.soil, cube_rect)
else:
win.blit(self.dirt, cube_rect)
win.blit(self.dirt, cube_rect)
def is_rock(self, row, col):
return self.board[row][col] == 0
def is_weed(self,row,col):
def is_weed(self, row, col):
return self.board[row][col] == 1
def set_grass(self,row,col):
self.board[row][col]=2
def set_grass(self, row, col):
self.board[row][col] = 2
def is_dirt(self,row,col):
return self.board[row][col] in (6,7,8,9)
def is_dirt(self, row, col):
return self.board[row][col] in (6, 7, 8, 9)
def set_soil(self, row, col):
self.board[row][col] = 10

View File

@ -1,80 +1,39 @@
from constant import width, height, rows, cols
from constant import rows, cols
class Stan:
def __init__(self, row, col, dir):
def __init__(self, row, col, direction):
self.p = []
self.a = ""
self.row = row
self.col = col
self.direction = dir
self.direction = direction
def __str__(self):
return f"row: {self.row}, col: {self.col}, direction: {self.direction}"
def parrent(self, stan, action):
if(len(self.p) == 0):
if len(self.p) == 0:
self.p.append(stan)
self.a = action
def succ(self, action, board):
if(action == "up"):
if(self.direction == "left"):
if not board.is_rock(max(self.col - 1, 0), self.row):
return Stan( self.row , max(self.col - 1, 0), self.direction)
return Stan(self.row, self.col, self.direction)
if(self.direction == "up"):
if not board.is_rock(self.col, max(self.row - 1, 0)):
return Stan(max(self.row - 1,0) , self.col, self.direction)
return Stan(self.row, self.col, self.direction)
if(self.direction == "right"):
if not board.is_rock(min(self.col + 1, cols - 1), self.row):
return Stan(self.row, min(self.col + 1, cols - 1) , self.direction)
return Stan(self.row, self.col, self.direction)
if(self.direction == "down"):
if not board.is_rock(self.col, min(self.row + 1,rows - 1 )):
return Stan(min(self.row + 1,rows - 1 ) , self.col, self.direction)
return Stan(self.row, self.col, self.direction)
if(action == "left"):
if(self.direction == "left"):
return Stan(self.row , self.col, "down")
if(self.direction == "up"):
return Stan(self.row, self.col, "left")
if(self.direction == "right"):
return Stan(self.row, self.col, "up")
if(self.direction == "down"):
return Stan(self.row, self.col , "right")
if(action == "right"):
if(self.direction == "left"):
return Stan(self.row, self.col, "up")
if(self.direction == "up"):
return Stan(self.row, self.col, "right")
if(self.direction == "right"):
return Stan(self.row, self.col, "down")
if(self.direction == "down"):
return Stan(self.row, self.col,"left")
move_offsets = {
"up": {"up": (-1, 0), "left": (0, -1), "down": (1, 0), "right": (0, 1)},
"left": {"up": "left", "left": "down", "down": "right", "right": "up"},
"right": {"up": "right", "right": "down", "down": "left", "left": "up"}
}
class Kolejka:
def __init__(self):
self.id = 0
self.len = 0
self.stany = []
if action == "up":
row_offset, col_offset = move_offsets[action][self.direction]
new_row = self.row + row_offset
new_col = self.col + col_offset
if 0 <= new_row < rows and 0 <= new_col < cols and not board.is_rock(new_row, new_col):
return Stan(new_row, new_col, self.direction)
def dodaj_stan(self, stan):
self.stany.append(stan)
self.len += 1
def usun_stan(self):
if not self.czy_pusta():
self.id += 1
return self.stany[self.id - 1]
else:
raise IndexError("Kolejka stanów jest pusta")
elif action in ["left", "right"]:
new_direction = move_offsets[action][self.direction]
return Stan(self.row, self.col, new_direction)
def czy_pusta(self):
return self.len <= self.id
def check(self, stan):
indeks = 0
for i in self.stany:
if(stan.direction == i.direction and stan.col == i.col and stan.row == i.row):
return True
return False
return None
class Odwiedzone:
def __init__(self):

97
main.py
View File

@ -2,8 +2,8 @@ import pygame
from board import Board
from constant import width, height, rows, cols
from tractor import Tractor
from kolejka import Stan, Kolejka, Odwiedzone
from kolejka import Stan, Odwiedzone
from queue import Queue
@ -13,7 +13,7 @@ WIN = pygame.display.set_mode((width, height))
pygame.display.set_caption('Inteligenty Traktor')
def goal_test(elem, goaltest, board):
if board.is_rock(goaltest.col, goaltest.row):
if board.is_rock(goaltest.row, goaltest.col):
return True
if((elem.row == goaltest.row) and (elem.col == goaltest.col)):
return True
@ -21,38 +21,46 @@ def goal_test(elem, goaltest, board):
return False
def actions(elem, istate):
akcje = []
while((elem.row != istate.row) or (elem.col != istate.col) or (elem.direction != istate.direction)):
while (elem.row != istate.row) or (elem.col != istate.col) or (elem.direction != istate.direction):
akcje.append(elem.a)
elem = elem.p[0]
return akcje[::-1] # Odwracamy kolejność, aby akcje były w poprawnej sekwencji
return akcje
def graphsearch(istate, goaltest, board):
explored = Odwiedzone()
fringe = Kolejka()
fringe.dodaj_stan(istate)
fringe = Queue()
fringe.put(istate)
moves = ["up", "left", "right"]
while not fringe.czy_pusta():
elem = fringe.usun_stan()
while not fringe.empty():
elem = fringe.get()
if goal_test(elem, goaltest, board):
return actions(elem, istate)
explored.dodaj_stan(elem)
for action in moves:
stan = elem.succ(action, board)
if((not fringe.check(stan)) and (not explored.check(stan))):
stan.parrent(elem, action)
fringe.dodaj_stan(stan)
if stan is not None:
if((not fringe_check(fringe,stan)) and (not explored.check(stan))):
stan.parrent(elem, action)
fringe.put(stan)
return "Brak sciezki"
def fringe_check(fringe, stan): # Funkcja pomocnicza do sprawdzania stanu w kolejce
with fringe.mutex:
for item in fringe.queue:
if stan.direction == item.direction and stan.col == item.col and stan.row == item.row:
return True
return False
def main():
rotation = ["left", "up", "right", "down"]
initial_state = Stan(4,4, "down")
goaltest = Stan(1,1, "up")
run = True
clock = pygame.time.Clock()
board = Board()
board.load_images()
actions = graphsearch(initial_state, goaltest, board)
print("akcje: >",actions )
akcje = graphsearch(initial_state, goaltest, board)
print("akcje: >",akcje )
tractor = Tractor(4, 4)
while run:
clock.tick(fps)
@ -61,63 +69,14 @@ def main():
if event.type == pygame.QUIT:
run = False
if actions:
action = actions.pop() # Pobierz kolejną akcję z listy
if akcje:
action = akcje.pop(0) # Pobierz kolejną akcję z listy
if action == "left":
if tractor.direction == "up":
tractor.direction = "left"
elif tractor.direction == "down":
tractor.direction = "right"
elif tractor.direction == "left":
tractor.direction = "down"
elif tractor.direction == "right":
tractor.direction = "up"
tractor.turn_left()
elif action == "right":
if tractor.direction == "up":
tractor.direction = "right"
elif tractor.direction == "down":
tractor.direction = "left"
elif tractor.direction == "left":
tractor.direction = "up"
elif tractor.direction == "right":
tractor.direction = "down"
tractor.turn_right()
elif action == "up":
if (tractor.direction == "up" and tractor.row > 0):
if board.is_weed(tractor.col, tractor.row - 1):
board.set_grass(tractor.col, tractor.row - 1)
tractor.row -= 1
elif board.is_dirt(tractor.col, tractor.row - 1):
board.set_soil(tractor.col, tractor.row - 1)
tractor.row -= 1
elif not board.is_rock(tractor.col, tractor.row - 1):
tractor.row -= 1
elif (tractor.direction == "left" and tractor.col > 0):
if board.is_weed(tractor.col - 1, tractor.row):
board.set_grass(tractor.col - 1, tractor.row)
tractor.col -= 1
elif board.is_dirt(tractor.col - 1, tractor.row):
board.set_soil(tractor.col - 1, tractor.row)
tractor.col -= 1
elif not board.is_rock(tractor.col - 1, tractor.row):
tractor.col -= 1
elif (tractor.direction == "down" and tractor.row < rows - 1):
if board.is_weed(tractor.col, tractor.row + 1):
board.set_grass(tractor.col, tractor.row + 1)
tractor.row += 1
elif board.is_dirt(tractor.col, tractor.row + 1):
board.set_soil(tractor.col, tractor.row + 1)
tractor.row += 1
elif not board.is_rock(tractor.col, tractor.row + 1):
tractor.row += 1
elif (tractor.direction == "right" and tractor.col < cols - 1):
if board.is_weed(tractor.col + 1, tractor.row):
board.set_grass(tractor.col + 1, tractor.row)
tractor.col += 1
elif board.is_dirt(tractor.col + 1, tractor.row):
board.set_soil(tractor.col + 1, tractor.row)
tractor.col += 1
elif not board.is_rock(tractor.col + 1, tractor.row):
tractor.col += 1
tractor.move_forward(board)
board.draw_cubes(WIN)

View File

@ -1,5 +1,6 @@
import pygame
from constant import size
from constant import size, rows, cols
class Tractor:
def __init__(self, row, col):
self.row = row
@ -8,10 +9,60 @@ class Tractor:
"up": pygame.image.load("tractor/up.png"),
"down": pygame.image.load("tractor/down.png"),
"left": pygame.image.load("tractor/left.png"),
"right":pygame.image.load("tractor/right.png")
"right": pygame.image.load("tractor/right.png")
}
self.direction = "down"
def draw(self, win):
tractor_image = self.images[self.direction]
win.blit(tractor_image, (self.col*size, self.row*size))
win.blit(tractor_image, (self.col * size, self.row * size))
def turn_left(self):
if self.direction == "up":
self.direction = "left"
elif self.direction == "left":
self.direction = "down"
elif self.direction == "down":
self.direction = "right"
elif self.direction == "right":
self.direction = "up"
def turn_right(self):
if self.direction == "up":
self.direction = "right"
elif self.direction == "right":
self.direction = "down"
elif self.direction == "down":
self.direction = "left"
elif self.direction == "left":
self.direction = "up"
def move_forward(self, board):
if self.direction == "up" and self.row > 0:
if not board.is_rock(self.row - 1, self.col):
if board.is_weed(self.row - 1, self.col):
board.set_grass(self.row - 1, self.col)
elif board.is_dirt(self.row - 1, self.col):
board.set_soil(self.row - 1, self.col)
self.row -= 1
elif self.direction == "left" and self.col > 0:
if not board.is_rock(self.row, self.col - 1):
if board.is_weed(self.row, self.col - 1):
board.set_grass(self.row, self.col - 1)
elif board.is_dirt(self.row, self.col - 1):
board.set_soil(self.row, self.col - 1)
self.col -= 1
elif self.direction == "down" and self.row < rows - 1:
if not board.is_rock(self.row + 1, self.col):
if board.is_weed(self.row + 1, self.col):
board.set_grass(self.row + 1, self.col)
elif board.is_dirt(self.row + 1, self.col):
board.set_soil(self.row + 1, self.col)
self.row += 1
elif self.direction == "right" and self.col < cols - 1:
if not board.is_rock(self.row, self.col + 1):
if board.is_weed(self.row, self.col + 1):
board.set_grass(self.row, self.col + 1)
elif board.is_dirt(self.row, self.col + 1):
board.set_soil(self.row, self.col + 1)
self.col += 1