import pygame pygame.init() # Game Constants Ucelu = False SCREENX = 500 SCREENY = 500 # SCREEN = pygame.display.set_mode([600, 600]) # screen = pygame.display.set_mode((SCREENX, SCREENY)) SCREEN = pygame.display.set_mode([600,650]) pygame.display.set_caption('Inteligenty Traktor') # COLORS WHITE = (255, 255, 255) BLACK = (0, 0, 0) RED = (255, 0, 0) GREEN = (0, 255, 0, 0) BLUE = (0, 0, 255) GREY = (128, 128, 128) CLOCK = pygame.time.Clock() FPS = 300 DELAY = 100 GRIDX = 10 GRIDY = 10 obstacleObjects = {} # Store the obstacle objects (Blocks on the path) from Obstacle class gridObjects = {} # Store grid-box objects from Grid Class gridObstacle = {} # Store the grid:obstacle pair stuck together boxObjects = {} boxes = 1 obstacles = 1 # BFS Variables startNode = 0 goalNode = 0 graph = dict() pathFound = [] # Store the path in a list box index to draw on later class BFS: # Finds a suitable path from point A to point B using Breadth-First-Search Algorithm def __init__(self, graph, start, goal): self.graph = graph self.start = start self.goal = goal def solve(self): print('Start\n\n') print(self.graph) print('\n\n') # keep track of explored nodes explored = [] # keep track of all paths to be checked queue = [[self.start]] # return path if start is goal if self.start == self.goal: return 'That was easy. Start == Goal' # keep looping until all possible paths are explored while queue: # pop the first path from the queue path = queue.pop(0) # get the last node from the path node = path[-1] if node not in explored: neighbors = self.graph[node] # go through all neighbor nodes # push it into the queue for neighbor in neighbors: new_path = list(path) new_path.append(neighbor) queue.append(new_path) if neighbor == self.goal: return new_path # mark node as explored explored.append(node) # in case there is no path return "path not accessible" class Grid(object): def __init__(self, x, y, sx, sy): self.x = x self.y = y self.sx = sx self.sy = sy self.width = 1 def draw(self): pygame.draw.rect(SCREEN, BLACK, (self.x, self.y, self.sx, self.sy), self.width) class Box(object): def __init__(self, x, y, sx, sy, color): self.x = x self.y = y self.sx = sx self.sy = sy self.color = color def draw(self): pygame.draw.rect(SCREEN, self.color, pygame.Rect(self.x, self.y, self.sx, self.sy)) class Obstacle(object): def __init__(self, mouseObj): self.mseX = mouseObj[0] self.mseY = mouseObj[1] for grid in gridObjects: g = getGridBoxes(grid) self.x = g.x self.y = g.y self.sx = g.sx self.sy = g.sy if self.mseX > self.x and self.mseX < self.x + self.sx: if self.mseY > self.y and self.mseY < self.y + self.sy: self.posX = self.x self.posY = self.y self.gridBox = grid def draw(self): # pygame.draw.rect(SCREEN, GREY, pygame.Rect(self.posX, self.posY, self.sx, self.sy)) SCREEN.blit(imgTree, (self.posX, self.posY)) def getGridBoxes(grid_box): return gridObjects[grid_box] def drawGrid(sizex,sizey): spaceX = SCREENX // sizex spaceY = SCREENY // sizey width = 2 counter = 1 for i in range(sizex): for j in range(sizey): # g = Grid(i*spaceX, j*spaceY, spaceX, spaceY) g = Grid(50 + i*50, 50 + j*50, spaceX, spaceY) gridObjects[counter] = g counter += 1 def generateGraph(row,col): # This function generates a graph based on the gridObjects instantiated! sample_graph = {'A':['B','C','E'], 'B':['A','D','E'], 'C':['A','F','G'], 'D':['B'], 'E':['A','B','D'], 'F':['C'], 'G':['C'] } miniG = {} for grid in range(len(gridObjects)): grid += 1 # Synchronize index mod = grid % col # Used to check the Top and Bottom Grid Boxes! gN = grid - 1 gS = grid + 1 gE = grid + col gW = grid - col # CHECK THE NEIGHBORS TO THE GRID-BOXES, ACCOUNTING FOR THE EXTREME GRID-BOXES(BORDERS) if mod == 0: # 5,10,15,20,25 - You can't go south from here (Bottom Boxes) if grid > col: # Away from the Left Border of the Screen if grid > (col*row)-col: # You are on the Right Border of the screen - You can't go East miniG[grid] = [gN, gW] else: # Away from the Right Border of the Screen - You can go East miniG[grid] = [gN, gE, gW] else: # You are on the Left Edge of the screen - You can't go West miniG[grid] = [gN, gE] elif mod == 1: # 6,11,16,21 :> You can't go North from here (Top Boxes) if grid > col: # Away from the Left Border of the Screen if grid > (col*row)-col: # You are on the Right Border of the screen - You can't go East miniG[grid] = [gS, gW] else: # Away from the Right Border of the Screen - You can go east miniG[grid] = [gS, gE, gW] else: # You are on the Left Edge of the screen - You can't go West miniG[grid] = [gS, gE] else: # All the rest (Not Top or Bottom Boxes) - You can go North or South if grid > col: # Away from the Left Border of the Screen if grid > (col*row)-col: # You are on the Right Border of the screen - You can't go East miniG[grid] = [gN, gS, gW] else: # Away from the Right Border of the Screen - You can go East miniG[grid] = [gN, gS, gE, gW] else: # You are on the Left Edge of the screen - You can't go West miniG[grid] = [gN, gS, gE] # FILTER OUT OBSTACLES FROM THE GRAPH miniG2 = {} for grid in range(len(gridObjects)): grid += 1 if grid not in gridObstacle: # gridObjects.remove(grid) # Dict object has no attribute : 'remove' # HACK miniG2[grid] = miniG[grid] # Created a new dictionary that stored the values required # IN-DEPTH FILTER - Filter out obstacles from the neighbors-list for neigbor in miniG2[grid]: if neigbor in gridObstacle: miniG2[grid].remove(neigbor) # Filtering again as the first Filter block didn't clear out everything # Filtering through the neighbors for grid in miniG2: for item in miniG2[grid]: if item in gridObstacle: miniG2[grid].remove(item) return miniG2 def drawGraph(pathF, Ucelu): #Draws the path given the path-list print(pathF) if Ucelu == False: for grid in pathF: g = gridObjects[grid] # Get the grid-box object mentioned in the path x = g.x y = g.y sx = g.sx sy = g.sy # pygame.draw.rect(SCREEN, GREEN, pygame.Rect(x, y, sx, sy)) player.x = x/50 - 1 player.y =y/50 - 1 # ----------------------------- i = 0 while i < len(T): j = 0 while j < len(T[i]): #color = (255, 255, 255, 0) if T[i][j].isWet == 0: # a = 1 color = (160, 80, 40, 0) else: # a = 1 color = (50, 25, 0, 0) #Covers 'player' on the way pygame.draw.rect(SCREEN, color, pygame.Rect(50 + 50 * i, 50 + 50 * j, 50, 50)) if T[i][j].plantType == 1: SCREEN.blit(imgWheat, (50 + 50 * i, 50 + 50 * j)) if T[i][j].plantType == 2: SCREEN.blit(imgCarrot, (50 + 50 * i, 50 + 50 * j)) if T[i][j].plantType == 3: SCREEN.blit(imgCabbage, (50 + 50 * i, 50 + 50 * j)) if T[i][j].plantType == 4: SCREEN.blit(imgTree, (50 + 50 * i, 50 + 50 * j)) j = j + 1 i = i + 1 # Render the trees for obs in obstacleObjects: obstacleObjects[obs].draw() for bx in boxObjects: boxObjects[bx].draw() i = 0 while i < len(T)+1: pygame.draw.line(SCREEN, (0, 0, 0), (50 + i * 50, 50), (50 + i * 50, 50 + len(T) * 50), 1) pygame.draw.line(SCREEN, (0, 0, 0), (50, 50 + i * 50), (50 + len(T) * 50, 50 + i * 50), 1) i = i + 1 tmpImg = pygame.transform.rotate(imgPlayer, player.rotation) if player.rotation == 180: tmpImg = pygame.transform.flip(tmpImg, True, True) tmpImg = pygame.transform.flip(tmpImg, True, False) #player is seen on the way SCREEN.blit(tmpImg, (55 + 50 * player.x, 55 + 50 * player.y)) # -------------------------------------- # tmpImg = pygame.transform.rotate(imgPlayer, player.rotation) # # if flip: # # if flip == True: # if player.rotation == 180: # tmpImg = pygame.transform.flip(tmpImg, True, True) # tmpImg = pygame.transform.flip(tmpImg, True, False) # # SCREEN.blit(tmpImg, (55 + 50 * player.x, 55 + 50 * player.y)) pygame.display.update() pygame.time.wait(300) #SCREEN.fill((WHITE)) # pygame.time.wait(50) # pygame.draw.rect(SCREEN, WHITE, pygame.Rect(x, y, sx, sy)) Ucelu = True def UIHandler(mouseObj, Ucelu): # drawGrid(GRIDX, GRIDY) drawGrid(10,10) for grid in gridObjects: gridObjects[grid].draw() for bx in boxObjects: boxObjects[bx].draw() for obs in obstacleObjects: obstacleObjects[obs].draw() if pathFound: if Ucelu == False: drawGraph(pathFound, Ucelu) Ucelu = True def eventHandler(kbdObj,mouseObj, Ucelu): global boxes global obstacles global startNode global goalNode global pathFound # If Key_f is pressed, set goal node if kbdObj[pygame.K_f]: gBox = getGridBoxes(int(len(gridObjects))) # gBox = getGridBoxes() x = mouseObj[0] y = mouseObj[1] # x = gBox.x # y = gBox.y sx = gBox.sx sy = gBox.sy # ---------------------------------------- mseX = mouseObj[0] mseY = mouseObj[1] for grid in gridObjects: g = getGridBoxes(grid) x = g.x y = g.y sx = g.sx sy = g.sy if mseX > x and mseX < x + sx: if mseY > y and mseY < y + sy: posX = x posY = y gridBox = grid # SCREEN.blit(imgTree, (posX, posY)) # --------------------------------------- bo = Box(posX, posY, sx, sy, BLUE) boxObjects[boxes] = bo # boxes += 1 boxes = 1 # goalNode = GRIDX*GRIDX # goalNode = (10 * (x + 1) + (y + 1) - 10) goalNode = (10 * (posX/50 ) + (posY/50) - 10) # goalNode = (x/sx) * (y/sy) # Delay to avoid multiple spawning of objects pygame.time.wait(DELAY) # If Key_x is pressed, spawn tree if kbdObj[pygame.K_x]: obs = Obstacle(mouseObj) obstacleObjects[obstacles] = obs # print(obs.gridBox) obstacles += 1 # print(obstacleObjects) gridObstacle[obs.gridBox] = obstacles # Delay to avoid multiple spawning of objects pygame.time.wait(DELAY) # if Key_SPACE is pressed, start the magic if kbdObj[pygame.K_SPACE]: gBox = getGridBoxes(1) x = gBox.x y = gBox.y sx = gBox.sx sy = gBox.sy x = (player.x +1) * 50 y = (player.y +1) * 50 # tmpImg = pygame.transform.rotate(imgPlayer, player.rotation) # SCREEN.blit(tmpImg, (50 + 50 * player.x, 50 + 50 * player.y)) # pygame.display.update() #when on it keeps flashing - among others #bo = Box(x, y, sx, sy, RED) #boxObjects[boxes] = bo # boxes += 1 boxes = 1 startNode = (10 * (player.x + 1) + (player.y + 1) - 10) # startNode = (((player.x + 1)*10 - 9) * (player.y + 1) ) # startNode = 2 # tmpImg = pygame.transform.rotate(imgPlayer, player.rotation) # SCREEN.blit(tmpImg, (55 + 50 * player.x, 55 + 50 * player.y)) # pygame.display.update() # Delay to avoid multiple spawning of objects #pygame.time.wait(DELAY) graph = generateGraph(GRIDY,GRIDX) bfs = BFS(graph, startNode, goalNode) # print(bfs.solve()) pathFound = bfs.solve() # Delay to avoid multiple spawning of objects pygame.time.wait(DELAY) #With it it keeps going, if without it turns off Ucelu = False class Field: def __init__(self, fieldType, plantType, isWet, wetTime, isFertilized, fertilizedTime): self.fieldType = fieldType # good/bad self.plantType = plantType # wheat/carrot/cabbage self.isWet = isWet # yes/no self.wetTime = wetTime # number self.isFertilized = isFertilized # yes/no self.fertilizedTime = fertilizedTime # number class Plant: def __init__(self, plantType, growthState): self.plantType = plantType # wheat/carrot/cabbage self.growthState = growthState # growing/grown class Fertilizer: def __init__(self, fertilizerType): self.fertilizerType = fertilizerType # wheat/carrot/cabbage class Player: x = 0 y = 0 rotation = 0 T = [[Field(1,0,0,0,0,0),Field(0,0,1,0,0,0),Field(1,1,1,0,0,0),Field(1,2,0,0,0,0),Field(0,3,1,0,0,0),Field(0,0,0,0,0,0),Field(0,0,0,0,0,0),Field(1,0,1,0,0,0),Field(1,0,0,0,0,0),Field(1,0,1,0,0,0)], [Field(1,0,0,0,0,0),Field(0,0,1,0,0,0),Field(1,1,1,0,0,0),Field(1,2,0,0,0,0),Field(0,3,1,0,0,0),Field(0,0,0,0,0,0),Field(0,0,0,0,0,0),Field(1,0,1,0,0,0),Field(1,0,0,0,0,0),Field(1,0,1,0,0,0)], [Field(1,0,0,0,0,0),Field(0,0,1,0,0,0),Field(1,1,1,0,0,0),Field(1,2,0,0,0,0),Field(0,3,1,0,0,0),Field(0,0,0,0,0,0),Field(0,0,0,0,0,0),Field(1,0,1,0,0,0),Field(1,0,0,0,0,0),Field(1,0,1,0,0,0)], [Field(1,0,0,0,0,0),Field(0,0,1,0,0,0),Field(1,1,1,0,0,0),Field(1,2,0,0,0,0),Field(0,3,1,0,0,0),Field(0,0,0,0,0,0),Field(0,0,0,0,0,0),Field(1,0,1,0,0,0),Field(1,0,0,0,0,0),Field(1,0,1,0,0,0)], [Field(1,0,0,0,0,0),Field(0,0,1,0,0,0),Field(1,1,1,0,0,0),Field(1,2,0,0,0,0),Field(0,3,1,0,0,0),Field(0,0,0,0,0,0),Field(0,0,0,0,0,0),Field(1,0,1,0,0,0),Field(1,0,0,0,0,0),Field(1,0,1,0,0,0)], [Field(1,0,0,0,0,0),Field(0,0,1,0,0,0),Field(1,1,1,0,0,0),Field(1,2,0,0,0,0),Field(0,3,1,0,0,0),Field(0,0,0,0,0,0),Field(0,0,0,0,0,0),Field(1,0,1,0,0,0),Field(1,0,0,0,0,0),Field(1,0,1,0,0,0)], [Field(1,0,0,0,0,0),Field(0,0,1,0,0,0),Field(1,1,1,0,0,0),Field(1,2,0,0,0,0),Field(0,3,1,0,0,0),Field(0,0,0,0,0,0),Field(0,0,0,0,0,0),Field(1,0,1,0,0,0),Field(1,0,0,0,0,0),Field(1,0,1,0,0,0)], [Field(1,0,0,0,0,0),Field(0,0,1,0,0,0),Field(1,1,1,0,0,0),Field(1,2,0,0,0,0),Field(0,3,1,0,0,0),Field(0,0,0,0,0,0),Field(0,0,0,0,0,0),Field(1,0,1,0,0,0),Field(1,0,0,0,0,0),Field(1,0,1,0,0,0)], [Field(1,0,0,0,0,0),Field(0,0,1,0,0,0),Field(1,1,1,0,0,0),Field(1,2,0,0,0,0),Field(0,3,1,0,0,0),Field(0,0,0,0,0,0),Field(0,0,0,0,0,0),Field(1,0,1,0,0,0),Field(1,0,0,0,0,0),Field(1,0,1,0,0,0)], [Field(1,0,0,0,0,0),Field(0,0,1,0,0,0),Field(1,1,1,0,0,0),Field(1,2,0,0,0,0),Field(0,3,1,0,0,0),Field(0,0,0,0,0,0),Field(0,0,0,0,0,0),Field(1,0,1,0,0,0),Field(1,0,0,0,0,0),Field(1,0,1,0,0,0)]] #pygame.init() player = Player() # player.x = 2 # player.y = 2 #screen = pygame.display.set_mode([600, 600]) running = True # clock = pygame.time.Clock() SCREEN.fill((WHITE)) while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: if player.x > 0: player.x = player.x - 1 if event.key == pygame.K_UP: if player.y > 0: player.y = player.y - 1 if event.key == pygame.K_RIGHT: if player.x < 9: player.x = player.x + 1 if event.key == pygame.K_DOWN: if player.y < 9: player.y = player.y + 1 # Aga start lewo prawo, naprzód if event.key == pygame.K_a: player.rotation = (player.rotation + 90) % 360 if event.key == pygame.K_d: player.rotation = (player.rotation - 90) % 360 if event.key == pygame.K_w: if player.rotation == 0: if player.x < 9: player.x = player.x + 1 if player.rotation == 180: if player.x > 0: player.x = player.x - 1 if player.rotation == 270: if player.y < 9: player.y = player.y + 1 if player.rotation == 90: if player.y > 0: player.y = player.y - 1 # left, right, forward # if it's not here, it leaves a trail WELL NOT ANYMORE #SCREEN.fill((WHITE)) kbd = pygame.key.get_pressed() # kbd = event.key() mse = pygame.mouse.get_pos() # SCREEN.fill((WHITE)) Ucelu = False UIHandler(mse, Ucelu) eventHandler(kbd, mse, Ucelu) pygame.display.update() # CLOCK.tick(FPS) #screen.fill((175, 255, 50, 0)) #screen.fill((WHITE)) imgWheat = pygame.image.load('img/wheat.png') imgCarrot = pygame.image.load('img/carrot.png') imgCabbage = pygame.image.load('img/cabbage.png') imgPlayer = pygame.image.load('img/player.png') imgTree = pygame.image.load('img/tree.png') i = 0 while i < len(T): j = 0 while j < len(T[i]): # color = (255, 255, 255, 0) if T[i][j].isWet == 0: # a = 1 color = (160, 80, 40, 0) else: # a = 1 color = (50, 25, 0, 0) #colour from the beginning pygame.draw.rect(SCREEN, color, pygame.Rect(50 + 50 * i, 50 + 50 * j, 50, 50)) if T[i][j].plantType == 1: SCREEN.blit(imgWheat, (50 + 50 * i, 50 + 50 * j)) if T[i][j].plantType == 2: SCREEN.blit(imgCarrot, (50 + 50 * i, 50 + 50 * j)) if T[i][j].plantType == 3: SCREEN.blit(imgCabbage, (50 + 50 * i, 50 + 50 * j)) if T[i][j].plantType == 4: SCREEN.blit(imgTree, (50 + 50 * i, 50 + 50 * j)) j = j + 1 i = i + 1 i = 0 while i < len(T)+1: pygame.draw.line(SCREEN, (0, 0, 0), (50 + i * 50, 50), (50 + i * 50, 50 + len(T) * 50), 1) pygame.draw.line(SCREEN, (0, 0, 0), (50, 50 + i * 50), (50 + len(T) * 50, 50 + i * 50), 1) i = i + 1 tmpImg = pygame.transform.rotate(imgPlayer, player.rotation) if player.rotation == 180: tmpImg = pygame.transform.flip(tmpImg, True, True) tmpImg = pygame.transform.flip(tmpImg, True, False) #player seen at the beginning SCREEN.blit(tmpImg, (55 + 50 * player.x, 55 + 50 * player.y)) # set Start Node where the Player is located # gBox = getGridBoxes(1) # x = gBox.x # y = gBox.y # sx = gBox.sx # sy = gBox.sy # bo = Box(x, y, sx, sy, RED) # boxObjects[boxes] = bo # boxes += 1 # startNode = 1 # # Delay to avoid multiple spawning of objects # pygame.time.wait(DELAY) font = pygame.font.SysFont('comicsans', 18) label = font.render('f- punkt końcowy, x- drzewa, spacja- uruchomienie', 1, (0, 0, 0)) label1 = font.render('strzałki-ręczne poruszanie traktorem,', 1, (0, 0, 0)) label2 = font.render('a- obrót w lewo, d- w prawo, w-ruch naprzód', 1, (0, 0, 0)) SCREEN.blit(label, (10, 570)) SCREEN.blit(label1, (10, 590)) SCREEN.blit(label2, (10, 610)) # pygame.display.flip() pygame.display.update() CLOCK.tick(FPS) # Done! Time to quit. pygame.quit()