diff --git a/board.py b/board.py index 57887f835..af84f5040 100644 --- a/board.py +++ b/board.py @@ -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 \ No newline at end of file + self.board[row][col] = 10 diff --git a/kolejka.py b/kolejka.py index bf12e0abe..a1742efc1 100644 --- a/kolejka.py +++ b/kolejka.py @@ -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): diff --git a/main.py b/main.py index dfb08ff1e..a67fba312 100644 --- a/main.py +++ b/main.py @@ -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) diff --git a/tractor.py b/tractor.py index 4588616bb..54e0123b3 100644 --- a/tractor.py +++ b/tractor.py @@ -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