Merge branch 'genetic_algorithm'

This commit is contained in:
Kacper Kalinowski 2022-06-10 11:14:53 +02:00
commit 1bc8a26bd2
10 changed files with 591 additions and 261 deletions

View File

@ -1,3 +1,4 @@
<<<<<<< HEAD
|--- feature_2 <= 3.50 |--- feature_2 <= 3.50
| |--- feature_4 <= 3.50 | |--- feature_4 <= 3.50
| | |--- feature_0 <= 1.50 | | |--- feature_0 <= 1.50
@ -89,3 +90,96 @@
| | | |--- class: 0 | | | |--- class: 0
| |--- feature_1 > 1.50 | |--- feature_1 > 1.50
| | |--- class: 0 | | |--- class: 0
=======
|--- feature_2 <= 3.50
| |--- feature_4 <= 3.50
| | |--- feature_0 <= 1.50
| | | |--- class: 0
| | |--- feature_0 > 1.50
| | | |--- feature_3 <= 3.50
| | | | |--- feature_4 <= 2.50
| | | | | |--- class: 1
| | | | |--- feature_4 > 2.50
| | | | | |--- feature_2 <= 2.50
| | | | | | |--- class: 1
| | | | | |--- feature_2 > 2.50
| | | | | | |--- class: 0
| | | |--- feature_3 > 3.50
| | | | |--- feature_3 <= 4.50
| | | | | |--- feature_1 <= 2.50
| | | | | | |--- feature_0 <= 2.50
| | | | | | | |--- feature_1 <= 1.50
| | | | | | | | |--- feature_2 <= 2.50
| | | | | | | | | |--- class: 1
| | | | | | | | |--- feature_2 > 2.50
| | | | | | | | | |--- feature_4 <= 2.00
| | | | | | | | | | |--- class: 1
| | | | | | | | | |--- feature_4 > 2.00
| | | | | | | | | | |--- class: 0
| | | | | | | |--- feature_1 > 1.50
| | | | | | | | |--- class: 0
| | | | | | |--- feature_0 > 2.50
| | | | | | | |--- feature_2 <= 2.50
| | | | | | | | |--- class: 1
| | | | | | | |--- feature_2 > 2.50
| | | | | | | | |--- feature_4 <= 2.50
| | | | | | | | | |--- class: 1
| | | | | | | | |--- feature_4 > 2.50
| | | | | | | | | |--- class: 0
| | | | | |--- feature_1 > 2.50
| | | | | | |--- feature_1 <= 3.50
| | | | | | | |--- feature_0 <= 3.50
| | | | | | | | |--- class: 0
| | | | | | | |--- feature_0 > 3.50
| | | | | | | | |--- feature_2 <= 2.50
| | | | | | | | | |--- class: 1
| | | | | | | | |--- feature_2 > 2.50
| | | | | | | | | |--- feature_4 <= 2.00
| | | | | | | | | | |--- class: 1
| | | | | | | | | |--- feature_4 > 2.00
| | | | | | | | | | |--- class: 0
| | | | | | |--- feature_1 > 3.50
| | | | | | | |--- class: 0
| | | | |--- feature_3 > 4.50
| | | | | |--- class: 0
| |--- feature_4 > 3.50
| | |--- feature_2 <= 1.50
| | | |--- feature_4 <= 4.50
| | | | |--- feature_3 <= 3.50
| | | | | |--- feature_0 <= 1.50
| | | | | | |--- class: 0
| | | | | |--- feature_0 > 1.50
| | | | | | |--- class: 1
| | | | |--- feature_3 > 3.50
| | | | | |--- feature_1 <= 2.50
| | | | | | |--- feature_0 <= 2.50
| | | | | | | |--- class: 0
| | | | | | |--- feature_0 > 2.50
| | | | | | | |--- feature_3 <= 4.50
| | | | | | | | |--- class: 1
| | | | | | | |--- feature_3 > 4.50
| | | | | | | | |--- class: 0
| | | | | |--- feature_1 > 2.50
| | | | | | |--- class: 0
| | | |--- feature_4 > 4.50
| | | | |--- class: 0
| | |--- feature_2 > 1.50
| | | |--- class: 0
|--- feature_2 > 3.50
| |--- feature_1 <= 1.50
| | |--- feature_4 <= 1.50
| | | |--- feature_2 <= 4.50
| | | | |--- feature_0 <= 1.50
| | | | | |--- class: 0
| | | | |--- feature_0 > 1.50
| | | | | |--- feature_3 <= 4.50
| | | | | | |--- class: 1
| | | | | |--- feature_3 > 4.50
| | | | | | |--- class: 0
| | | |--- feature_2 > 4.50
| | | | |--- class: 0
| | |--- feature_4 > 1.50
| | | |--- class: 0
| |--- feature_1 > 1.50
| | |--- class: 0
>>>>>>> genetic_algorithm

View File

@ -3,9 +3,9 @@ from enum import Enum
from random import randrange from random import randrange
from map.tile import Tile from map.tile import Tile
class Trashbin(Tile): class Trashbin(Tile):
def __init__(self, img, x, y, width, height, waste_type): def __init__(self, img, x, y, width, height):
super().__init__(img, x, y, width, height) super().__init__(img, x, y, width, height)
# dis_dump dis_trash mass space trash_mass trash_space
self.x = x self.x = x
self.y = y self.y = y

231
genetic_algorithm/TSP.py Normal file
View File

@ -0,0 +1,231 @@
import numpy as np, random, operator, pandas as pd, matplotlib.pyplot as plt
from path_search_algorthms.a_star import get_cost
from decision_tree import decisionTree
from settings import *
import math
# klasa tworząca miasta czy też śmietniki
class City:
def __init__(self, x, y, array):
self.x = x
self.y = y
self.array = array
# self.dist = distance
#dystans to d = sqrt(x^2 + y^2)
def distance(self, city):
#getting distance by astar gives wrong final distance (intial = final)
return get_cost(math.floor(self.x / TILESIZE), math.floor(self.y / TILESIZE), math.floor(city.x / TILESIZE), math.floor(city.y / TILESIZE), self.array)
# xDis = abs(self.x - city.x)
# yDis = abs(self.y - city.y)
# distance = np.sqrt((xDis ** 2) + (yDis ** 2))
# return distance
def __repr__(self):
return "(" + str(self.x) + "," + str(self.y) + ")"
# fitness function,
# inverse of route distance
# we want to minimize distance so the larger the fitness the better
class Fitness:
def __init__(self, route, distanceArray):
self.route = route
self.distance = 0
self.fitness = 0.0
self.distanceArray = distanceArray
def routeDistance(self):
if self.distance == 0:
pathDistance = 0
for i in range(0, len(self.route)):
fromCity = self.route[i]
toCity = None
if i + 1 < len(self.route): # for returning to point 0?
toCity = self.route[i + 1]
else:
toCity = self.route[0]
# pathDistance += fromCity.distance(toCity)
pathDistance += self.distanceArray[str(fromCity.x)+" "+str(fromCity.y)+" "+str(toCity.x)+" "+str(toCity.y)]
self.distance = pathDistance
return self.distance
def routeFitness(self):
if self.fitness == 0:
self.fitness = 1 / float(self.routeDistance())
return self.fitness
# creating one individual - single route from city to city (trash to trash)
def createRoute(cityList):
route = random.sample(cityList, len(cityList))
return route
# creating initial population of given size
def initialPopulation(popSize, cityList):
population = []
for i in range(0, popSize):
population.append(createRoute(cityList))
return population
# ranking fitness of given route, output is ordered list with route id and its fitness score
def rankRoutes(population, distanceArray):
fitnessResults = {}
for i in range(0, len(population)):
fitnessResults[i] = Fitness(population[i], distanceArray).routeFitness()
return sorted(fitnessResults.items(), key=operator.itemgetter(1), reverse=True)
# selecting "mating pool"
# we are using here "Firness proportionate selection", its fitness-weighted probability of being selected
# moreover we are using elitism to ensure that the best of the best will preserve
def selection(popRanked, eliteSize):
selectionResults = []
# roulette wheel
df = pd.DataFrame(np.array(popRanked), columns=["Index", "Fitness"])
df['cum_sum'] = df.Fitness.cumsum()
df['cum_perc'] = 100 * df.cum_sum / df.Fitness.sum()
for i in range(0, eliteSize): # elitism
selectionResults.append(popRanked[i][0])
for i in range(0,
len(popRanked) - eliteSize): # comparing randomly drawn number to weights for selection for mating pool
pick = 100 * random.random()
for i in range(0, len(popRanked)):
if pick <= df.iat[i, 3]:
selectionResults.append(popRanked[i][0])
break
return selectionResults # returns list of route IDs
# creating mating pool from list of routes IDs from "selection"
def matingPool(population, selectionResults):
matingpool = []
for i in range(0, len(selectionResults)):
index = selectionResults[i]
matingpool.append(population[index])
return matingpool
# creating new generation
# ordered crossover bc we need to include all locations exactly one time
# randomly selecting a subset of the first parent string and then filling the remainder of route
# with genes from the second parent in the order in which they appear, without duplicating any genes from the first parent
def breed(parent1, parent2):
child = []
childP1 = []
childP2 = []
geneA = int(random.random() * len(parent1))
geneB = int(random.random() * len(parent1))
startGene = min(geneA, geneB)
endGene = max(geneA, geneB)
for i in range(startGene, endGene): # ordered crossover
childP1.append(parent1[i])
childP2 = [item for item in parent2 if item not in childP1]
child = childP1 + childP2
return child
# creating whole offspring population
def breedPopulation(matingpool, eliteSize):
children = []
length = len(matingpool) - eliteSize
pool = random.sample(matingpool, len(matingpool))
# using elitism to retain best genes (routes)
for i in range(0, eliteSize):
children.append(matingpool[i])
# filling rest generation
for i in range(0, length):
child = breed(pool[i], pool[len(matingpool) - i - 1])
children.append(child)
return children
# using swap mutation
# with specified low prob we swap two cities in route
def mutate(individual, mutationRate):
for swapped in range(len(individual)):
if (random.random() < mutationRate):
swapWith = int(random.random() * len(individual))
city1 = individual[swapped]
city2 = individual[swapWith]
individual[swapped] = city2
individual[swapWith] = city1
return individual
# extending mutate function to run through new pop
def mutatePopulation(population, mutationRate):
mutatedPop = []
for ind in range(0, len(population)):
mutatedInd = mutate(population[ind], mutationRate)
mutatedPop.append(mutatedInd)
return mutatedPop
# creating new generation
def nextGeneration(currentGen, eliteSize, mutationRate, distanceArray):
popRanked = rankRoutes(currentGen, distanceArray) # rank routes in current gen
selectionResults = selection(popRanked, eliteSize) # determining potential parents
matingpool = matingPool(currentGen, selectionResults) # creating mating pool
children = breedPopulation(matingpool, eliteSize) # creating new gen
nextGeneration = mutatePopulation(children, mutationRate) # applying mutation to new gen
return nextGeneration
# tutaj ma być lista kordów potencjalnych śmietników z drzewa decyzyjnego
cityList = []
# plotting the progress
def distanceFromCityToCity(cityFrom, city, array):
return get_cost(math.floor(cityFrom.x / TILESIZE), math.floor(cityFrom.y / TILESIZE), math.floor(city.x / TILESIZE), math.floor(city.y / TILESIZE), array)
def geneticAlgorithmPlot(population, popSize, eliteSize, mutationRate, generations, array):
a_star_distances = {}
for city in population:
for target in population:
if city == target:
continue
else:
a_star_distances[str(city.x)+" "+str(city.y)+" "+str(target.x)+" "+str(target.y)] = distanceFromCityToCity(city, target, array)
pop = initialPopulation(popSize, population)
progress = []
progress.append(1 / rankRoutes(pop, a_star_distances)[0][1])
print("Initial distance: " + str(1 / rankRoutes(pop, a_star_distances)[0][1]))
for i in range(0, generations):
pop = nextGeneration(pop, eliteSize, mutationRate, a_star_distances)
progress.append(1 / rankRoutes(pop, a_star_distances)[0][1])
print("Final distance: " + str(1 / rankRoutes(pop, a_star_distances)[0][1]))
bestRouteIndex = rankRoutes(pop, a_star_distances)[0][0]
bestRoute = pop[bestRouteIndex]
plt.plot(progress)
plt.ylabel('Distance')
plt.xlabel('Generation')
plt.show()
return bestRoute
# geneticAlgorithmPlot(population=cityList, popSize=100, eliteSize=20, mutationRate=0.01, generations=1000)

469
main.py
View File

@ -1,222 +1,249 @@
import os import os
import sys import sys
from random import randint from random import randint
import math import math
import pygame as pg import pygame as pg
import numpy import numpy
from game_objects.player import Player from game_objects.player import Player
from game_objects.aiPlayer import aiPlayer from game_objects.aiPlayer import aiPlayer
from game_objects.trash import Trash from game_objects.trash import Trash
from map import map from map import map
from map import map_utils from map import map_utils
from settings import *
from path_search_algorthms import bfs from path_search_algorthms import bfs
from path_search_algorthms import a_star_controller from path_search_algorthms import a_star_controller, a_star
from decision_tree import decisionTree from decision_tree import decisionTree
from NeuralNetwork import prediction from NeuralNetwork import prediction
from game_objects.trash import Trash
from settings import * from genetic_algorithm import TSP
from game_objects import aiPlayer
import itertools
def getTree():
tree = decisionTree.tree()
decisionTree.tree_as_txt(tree) def getTree():
# decisionTree.tree_to_png(tree) tree = decisionTree.tree()
decisionTree.tree_to_structure(tree) decisionTree.tree_as_txt(tree)
drzewo = decisionTree.tree_from_structure('./decision_tree/tree_model') # decisionTree.tree_to_png(tree)
# print("Dla losowych danych predykcja czy wziąć kosz to: ") decisionTree.tree_to_structure(tree)
# dec = decisionTree.decision(drzewo, *(4,1,1,1)) drzewo = decisionTree.tree_from_structure('./decision_tree/tree_model')
# print('---') # print("Dla losowych danych predykcja czy wziąć kosz to: ")
# print(f"decision is{dec}") # dec = decisionTree.decision(drzewo, *(4,1,1,1))
# print('---') # print('---')
# print(f"decision is{dec}")
return drzewo # print('---')
return drzewo
class Game():
def __init__(self): class Game():
pg.init()
pg.font.init() def __init__(self):
self.clock = pg.time.Clock() pg.init()
self.dt = self.clock.tick(FPS) / 333.0 pg.font.init()
self.screen = pg.display.set_mode((WIDTH, HEIGHT)) self.clock = pg.time.Clock()
pg.display.set_caption("Trashmaster") self.dt = self.clock.tick(FPS) / 333.0
self.load_data() self.screen = pg.display.set_mode((WIDTH, HEIGHT))
self.init_game() pg.display.set_caption("Trashmaster")
# because dont work without data.txt self.load_data()
# self.init_bfs() self.init_game()
# self.init_a_star() self.t = aiPlayer.aiPlayer(self.player, game=self)
self.t = aiPlayer(self.player, game=self)
def init_game(self):
def init_game(self): # initialize all variables and do all the setup for a new game
# initialize all variables and do all the setup for a new game
self.text_display = ''
self.text_display = ''
# sprite groups and map array for calculations
# sprite groups and map array for calculations (self.roadTiles, self.wallTiles, self.trashbinTiles), self.mapArray = map.get_tiles()
(self.roadTiles, self.wallTiles, self.trashbinTiles), self.mapArray = map.get_tiles()
# save current map
# save current map file = open('last_map.nparr', 'wb')
file = open('last_map.nparr', 'wb') numpy.save(file, self.mapArray, allow_pickle=True)
numpy.save(file, self.mapArray, allow_pickle=True) file.close
file.close
self.trashDisplay = pg.sprite.Group()
self.trashDisplay = pg.sprite.Group() self.agentSprites = pg.sprite.Group()
self.agentSprites = pg.sprite.Group() # player obj
# player obj self.player = Player(self, 32, 32)
self.player = Player(self, 32, 32) # camera obj
# camera obj self.camera = map_utils.Camera(MAP_WIDTH_PX, MAP_HEIGHT_PX)
self.camera = map_utils.Camera(MAP_WIDTH_PX, MAP_HEIGHT_PX)
# other
# other self.debug_mode = False
self.debug_mode = False
def init_bfs(self):
def init_bfs(self): start_node = (0, 0)
start_node = (0, 0) target_node = (18, 18)
target_node = (18, 18) find_path = bfs.BreadthSearchAlgorithm(start_node, target_node, self.mapArray)
find_path = bfs.BreadthSearchAlgorithm(start_node, target_node, self.mapArray) path = find_path.bfs()
path = find_path.bfs() # print(path)
# print(path) realPath = []
realPath = [] nextNode = target_node
nextNode = target_node for i in range(len(path) - 1, 0, -1):
for i in range(len(path) - 1, 0, -1): node = path[i]
node = path[i] if node[0] == nextNode:
if node[0] == nextNode: realPath.insert(0, node[0])
realPath.insert(0, node[0]) nextNode = node[1]
nextNode = node[1] print(realPath)
print(realPath)
def init_decision_tree(self):
def init_decision_tree(self): # logika pracy z drzewem
# logika pracy z drzewem self.positive_decision = []
self.positive_decision = [] self.negative_decision = []
self.negative_decision = []
for i in self.trashbinTiles:
for i in self.trashbinTiles: atrrs_container = i.get_attributes()
atrrs_container = i.get_attributes() x, y = i.get_coords()
x, y = i.get_coords() dec = decisionTree.decision(getTree(), *atrrs_container)
dec = decisionTree.decision(getTree(), *atrrs_container) if dec[0] == 1:
if dec[0] == 1: self.positive_decision.append(i) # zmiana po to by losowało wszystkie smietniki a nie poprawne tylko, zeby ladniej bylo widac algorytm genetyczny
self.positive_decision.append(i) else:
else: self.negative_decision.append(i)
self.negative_decision.append(i)
print('positive actions')
# print('positive actions') print(len(self.positive_decision))
# for i in self.positive_actions: # print('positive actions')
# print('----') # for i in self.positive_actions:
# print(i) # print('----')
# print('----') # print(i)
# print('----')
print('positive actions') self.draw()
print(len(self.positive_decision)) def decsion_tree_move(self):
for i in self.positive_decision:
# print(i.get_coords()) for i in range(0,len(self.positive_decision)):
print('action') # print(i.get_coords())
trash_x, trash_y = i.get_coords() print('action')
action = a_star_controller.get_actions_for_target_coords(trash_x, trash_y, self)
print(action)
self.t.startAiController(action)
temp_tsp = str(self.tsp_list[i])
print('') temp_tsp = temp_tsp.strip("()")
print('--rozpoczecie sortowania smietnika--') temp_tsp = temp_tsp.split(",")
dir = "./resources/trash_dataset/test/all" trash_x = int(temp_tsp[0])
files = os.listdir(dir) trash_y = int(temp_tsp[1])
for i in range(0, 10):
random = randint(0, 48)
file = files[random] print(trash_x, trash_y)
result = prediction.getPrediction(dir + '/' + file, 'trained_nn_20.pth')
img = pg.image.load(dir + '/' + file).convert_alpha() action = a_star_controller.get_actions_for_target_coords(trash_x, trash_y, self)
img = pg.transform.scale(img, (128, 128))
trash = Trash(img, 0, 0, 128, 128) print(action)
self.trashDisplay.add(trash) self.t.startAiController(action)
self.text_display = result
self.draw() print('')
# print(result + ' ' + file) print('--rozpoczecie sortowania smietnika--')
pg.time.wait(100) dir = "./resources/trash_dataset/test/all"
self.text_display = '' files = os.listdir(dir)
self.draw() for j in range(0, 10):
random = randint(0, 48)
# print(self.positive_actions[0]) file = files[random]
result = prediction.getPrediction(dir + '/' + file, 'trained_nn_20.pth')
# self.t.startAiController(self.positive_actions[0]) img = pg.image.load(dir + '/' + file).convert_alpha()
img = pg.transform.scale(img, (128, 128))
def load_data(self): offset_x, offset_y = self.camera.offset()
game_folder = os.path.dirname(__file__) trash = Trash(img, math.floor(-offset_x * TILESIZE), math.floor(-offset_y * TILESIZE), 128, 128)
img_folder = os.path.join(game_folder, 'resources/textures') self.trashDisplay.empty()
self.trashDisplay.add(trash)
self.player_img = pg.image.load(os.path.join(img_folder, PLAYER_IMG)).convert_alpha() self.text_display = result
self.player_img = pg.transform.scale(self.player_img, (PLAYER_WIDTH, PLAYER_HEIGHT)) self.draw()
pg.time.wait(100)
def run(self): self.text_display = ''
# game loop - set self.playing = False to end the game self.trashDisplay.empty()
self.playing = True self.draw()
self.init_decision_tree()
while self.playing: # print(self.positive_actions[0])
self.dt = self.clock.tick(FPS) / 1000.0
self.events() def init_TSP(self):
self.update()
self.draw() city_list =[]
def quit(self): for i in self.positive_decision:
pg.quit() trash_x, trash_y = i.get_coords()
sys.exit() city_list.append(TSP.City(x=trash_x, y=trash_y, array=self.mapArray))
def update(self): self.tsp_list = TSP.geneticAlgorithmPlot(population=city_list, popSize=100, eliteSize=20, mutationRate=0.01, generations=500, array=self.mapArray)
# update portion of the game loop print(self.tsp_list)
self.agentSprites.update()
self.camera.update(self.player) def load_data(self):
# pygame.display.update() game_folder = os.path.dirname(__file__)
img_folder = os.path.join(game_folder, 'resources/textures')
def draw(self):
# display fps as window title self.player_img = pg.image.load(os.path.join(img_folder, PLAYER_IMG)).convert_alpha()
pg.display.set_caption("{:.2f}".format(self.clock.get_fps())) self.player_img = pg.transform.scale(self.player_img, (PLAYER_WIDTH, PLAYER_HEIGHT))
# rerender map def run(self):
map.render_tiles(self.roadTiles, self.screen, self.camera) # game loop - set self.playing = False to end the game
map.render_tiles(self.wallTiles, self.screen, self.camera, self.debug_mode) self.playing = True
map.render_tiles(self.trashbinTiles, self.screen, self.camera) self.init_decision_tree()
map.render_tiles(self.trashDisplay, self.screen, self.camera) self.init_TSP()
self.decsion_tree_move()
# draw text
text_surface = pg.font.SysFont('Comic Sans MS', 30).render(self.text_display, False, (0, 0, 0)) while self.playing:
self.screen.blit(text_surface, (0, 128)) self.dt = self.clock.tick(FPS) / 1000.0
self.events()
# rerender additional sprites self.update()
for sprite in self.agentSprites: self.draw()
self.screen.blit(sprite.image, self.camera.apply(sprite))
if self.debug_mode: def quit(self):
pg.draw.rect(self.screen, CYAN, self.camera.apply_rect(sprite.hit_rect), 1) pg.quit()
sys.exit()
self.player.hud_group.draw(self.screen)
# finally update screen def update(self):
pg.display.flip() # update portion of the game loop
self.agentSprites.update()
def events(self): self.camera.update(self.player)
for event in pg.event.get(): # pygame.display.update()
if event.type == pg.QUIT:
self.quit() def draw(self):
if event.type == pg.KEYDOWN: # display fps as window title
if event.key == pg.K_ESCAPE: pg.display.set_caption("{:.2f}".format(self.clock.get_fps()))
self.quit()
if event.key == pg.K_h: # rerender map
self.debug_mode = not self.debug_mode map.render_tiles(self.roadTiles, self.screen, self.camera)
if event.type == pg.MOUSEBUTTONUP: map.render_tiles(self.wallTiles, self.screen, self.camera, self.debug_mode)
pos = pg.mouse.get_pos() map.render_tiles(self.trashbinTiles, self.screen, self.camera)
offset_x, offset_y = self.camera.offset() map.render_tiles(self.trashDisplay, self.screen, self.camera)
clicked_coords = [math.floor(pos[0] / TILESIZE) - offset_x, math.floor(pos[1] / TILESIZE) - offset_y]
actions = a_star_controller.get_actions_by_coords(clicked_coords[0], clicked_coords[1], self) # draw text
text_surface = pg.font.SysFont('Comic Sans MS', 30).render(self.text_display, False, (255, 255, 255))
if (actions != None): self.screen.blit(text_surface, (0, 128))
self.t.startAiController(actions)
# rerender additional sprites
for sprite in self.agentSprites:
# create the game object self.screen.blit(sprite.image, self.camera.apply(sprite))
if self.debug_mode:
if __name__ == "__main__": pg.draw.rect(self.screen, CYAN, self.camera.apply_rect(sprite.hit_rect), 1)
g = Game()
# self.player.hud_group.draw(self.screen)
g.run() # finally update screen
pg.display.flip()
def events(self):
for event in pg.event.get():
if event.type == pg.QUIT:
self.quit()
if event.type == pg.KEYDOWN:
if event.key == pg.K_ESCAPE:
self.quit()
if event.key == pg.K_h:
self.debug_mode = not self.debug_mode
if event.type == pg.MOUSEBUTTONUP:
pos = pg.mouse.get_pos()
offset_x, offset_y = self.camera.offset()
clicked_coords = [math.floor(pos[0] / TILESIZE) - offset_x, math.floor(pos[1] / TILESIZE) - offset_y]
actions = a_star_controller.get_actions_by_coords(clicked_coords[0], clicked_coords[1], self)
if (actions != None):
self.t.startAiController(actions)
# create the game object
if __name__ == "__main__":
g = Game()
g.run()
g.show_go_screen() g.show_go_screen()

View File

@ -5,17 +5,6 @@ from settings import *
def get_tiles(): def get_tiles():
array = map_utils.generate_map() array = map_utils.generate_map()
# array = map_utils.get_blank_map_array()
# array[1][1] = 1
# array[1][2] = 1
# array[1][3] = 1
# array[1][4] = 1
# array[1][5] = 1
# array[1][6] = 1
# array[2][5] = 1
pattern = map_pattern.get_pattern() pattern = map_pattern.get_pattern()
tiles = map_utils.get_sprites(array, pattern) tiles = map_utils.get_sprites(array, pattern)
return tiles, array return tiles, array

View File

@ -15,13 +15,13 @@ def generate_map():
map = get_blank_map_array() map = get_blank_map_array()
# generowanie scian # generowanie scian
for i in range(0, 20): for i in range(0, WALL_NUMBER):
x = random.randint(0, MAP_WIDTH-1) x = random.randint(0, MAP_WIDTH-1)
y = random.randint(0, MAP_HEIGHT-1) y = random.randint(0, MAP_HEIGHT-1)
map[y][x] = 1 map[y][x] = 1
# generowanie smietnikow # generowanie smietnikow
for i in range(0, 10): for i in range(0, TRASHBIN_NUMBER):
x = random.randint(0, MAP_WIDTH-1) x = random.randint(0, MAP_WIDTH-1)
y = random.randint(0, MAP_HEIGHT-1) y = random.randint(0, MAP_HEIGHT-1)
map[y][x] = 2 map[y][x] = 2
@ -53,7 +53,7 @@ def get_sprites(map, pattern):
elif tileId == 2: elif tileId == 2:
trashbinId = random.randint(0, 4) trashbinId = random.randint(0, 4)
tile = Tile(pattern[0], offsetX, offsetY, TILE_SIZE_PX, TILE_SIZE_PX) tile = Tile(pattern[0], offsetX, offsetY, TILE_SIZE_PX, TILE_SIZE_PX)
trashbin = Trashbin(trashbin_pattern[trashbinId], offsetX, offsetY, 32, 30, trashbinId) trashbin = Trashbin(trashbin_pattern[trashbinId], offsetX, offsetY, 32, 30)
roadTiles.add(tile) roadTiles.add(tile)
trashbinTiles.add(trashbin) trashbinTiles.add(trashbin)
trashbins.append(trashbin) trashbins.append(trashbin)
@ -94,9 +94,3 @@ class Camera:
self.camera = pg.Rect(x, y, self.width, self.height) self.camera = pg.Rect(x, y, self.width, self.height)

11
mapa.py
View File

@ -2,17 +2,6 @@ import pygame as pg
import pytmx import pytmx
# config
# TILE_SIZE = 16
# def preparedMap(screenSize):
# tileImage = pg.image.load('tile1.png')
# surface = pg.Surface(screenSize)
# for x in range(0, screenSize[0], TILE_SIZE):
# for y in range(0, screenSize[1], TILE_SIZE):
# surface.blit(tileImage, (x, y))
# return surface
class TiledMap: class TiledMap:
# loading file # loading file

View File

@ -4,6 +4,8 @@ from path_search_algorthms import a_star_utils as utils
def get_cost(start_x: int, start_y: int, target_x: int, target_y: int, array): def get_cost(start_x: int, start_y: int, target_x: int, target_y: int, array):
actions = search_path(start_x, start_y, utils.Rotation.NONE, target_x, target_y, array) actions = search_path(start_x, start_y, utils.Rotation.NONE, target_x, target_y, array)
if actions is None:
return 1
return len(actions) return len(actions)
@ -72,4 +74,3 @@ def trace_path(end_node: utils.Node):
path.append("forward") path.append("forward")
return path return path

View File

@ -92,7 +92,9 @@ def get_rotate_change(rotationA: Rotation, rotationB: Rotation) -> int:
# get new rotation for target_node as neighbour of start_node # get new rotation for target_node as neighbour of start_node
def get_needed_rotation(start_node: Node, target_node: Node) -> Rotation: def get_needed_rotation(start_node: Node or bool, target_node: Node) -> Rotation:
if(start_node == False):
return target_node.rotation
if (start_node.x - target_node.x > 0): if (start_node.x - target_node.x > 0):
return Rotation.LEFT return Rotation.LEFT
if (start_node.x - target_node.x < 0): if (start_node.x - target_node.x < 0):

View File

@ -7,7 +7,7 @@ RED = (255, 0, 0)
#game settings #game settings
WIDTH = 1024+200 WIDTH = 1024
HEIGHT = 768 HEIGHT = 768
FPS = 60 FPS = 60
@ -26,10 +26,13 @@ PLAYER_HIT_RECT = pg.Rect(0, 0, 50, 50)
PLAYER_WIDTH = 64 PLAYER_WIDTH = 64
PLAYER_HEIGHT = 32 PLAYER_HEIGHT = 32
#map settings #map settings x 16 y 12
MAP_WIDTH = 16 MAP_WIDTH = 25
MAP_HEIGHT = 12 MAP_HEIGHT = 25
TILE_SIZE_PX = 64 TILE_SIZE_PX = 64
MAP_WIDTH_PX = MAP_WIDTH * TILE_SIZE_PX MAP_WIDTH_PX = MAP_WIDTH * TILE_SIZE_PX
MAP_HEIGHT_PX = MAP_HEIGHT * TILE_SIZE_PX MAP_HEIGHT_PX = MAP_HEIGHT * TILE_SIZE_PX
TRASHBIN_NUMBER = 70
WALL_NUMBER = 50