diff --git a/__pycache__/agent.cpython-310.pyc b/__pycache__/agent.cpython-310.pyc index 93ab86d..0ace537 100644 Binary files a/__pycache__/agent.cpython-310.pyc and b/__pycache__/agent.cpython-310.pyc differ diff --git a/__pycache__/astar.cpython-310.pyc b/__pycache__/astar.cpython-310.pyc index 0d8cf07..4122a47 100644 Binary files a/__pycache__/astar.cpython-310.pyc and b/__pycache__/astar.cpython-310.pyc differ diff --git a/__pycache__/drzewo_decyzyjne.cpython-310.pyc b/__pycache__/drzewo_decyzyjne.cpython-310.pyc new file mode 100644 index 0000000..00522da Binary files /dev/null and b/__pycache__/drzewo_decyzyjne.cpython-310.pyc differ diff --git a/__pycache__/mobs.cpython-310.pyc b/__pycache__/mobs.cpython-310.pyc index 8c4d775..5a482b4 100644 Binary files a/__pycache__/mobs.cpython-310.pyc and b/__pycache__/mobs.cpython-310.pyc differ diff --git a/__pycache__/nn.cpython-310.pyc b/__pycache__/nn.cpython-310.pyc index 8026956..33f3bcc 100644 Binary files a/__pycache__/nn.cpython-310.pyc and b/__pycache__/nn.cpython-310.pyc differ diff --git a/agent.py b/agent.py index 93cc93d..cba0c25 100644 --- a/agent.py +++ b/agent.py @@ -47,7 +47,7 @@ class Agent(pygame.sprite.Sprite): self._layer = AGENT_LAYER self.damage = 50*self.level - self.artifact = True + self.artifact = "tak" def update(self): diff --git a/astar.py b/astar.py index 5e95810..55c9fd4 100644 --- a/astar.py +++ b/astar.py @@ -34,7 +34,7 @@ class Astar(): def a_star(self, goal): path = [] start = (self.g.agent.rect.x//TILE_SIZE, self.g.agent.rect.y//TILE_SIZE) - print(start,goal) + #print(start,goal) open_set = [] heapq.heappush(open_set, (0, start)) # Priority queue with the start position came_from = {} diff --git a/drzewo_decyzyjne/data b/data similarity index 99% rename from drzewo_decyzyjne/data rename to data index 8e12608..bfaa9be 100644 --- a/drzewo_decyzyjne/data +++ b/data @@ -1,5 +1,5 @@ zdrowie_bohatera,moc_bohatera,moc_moba,lvl_wiekszy_bohater,mob_jest_strzelcem,zdrowie_moba,artefakt,akcja -100,tak,tak,tak,tak,100,tak,zmien_kierunek +100,tak,tak,tak,tak,100,tak,walcz 100,tak,tak,tak,tak,100,nie,zmien_kierunek 100,tak,tak,tak,tak,50,tak,zmien_kierunek 100,tak,tak,tak,tak,50,nie,zmien_kierunek diff --git a/drzewo_decyzyjne.py b/drzewo_decyzyjne.py new file mode 100644 index 0000000..d2db9ed --- /dev/null +++ b/drzewo_decyzyjne.py @@ -0,0 +1,150 @@ +import pandas as pd +import numpy as np + +class Tree(): + + + # Obliczanie entropii dla całego zbioru danych + def oblicz_calkowita_entropie(self,dane_treningowe, etykieta, lista_klas): + liczba_wierszy = dane_treningowe.shape[0] + calkowita_entropia = 0 + + for klasa in lista_klas: + liczba_wystapien_klasy = dane_treningowe[dane_treningowe[etykieta] == klasa].shape[0] + entropia_klasy = - (liczba_wystapien_klasy / liczba_wierszy) * np.log2(liczba_wystapien_klasy / liczba_wierszy) + calkowita_entropia += entropia_klasy + + return calkowita_entropia + + + # Obliczanie entropii dla przefiltrowanego zbioru danych + def oblicz_entropie(self,dane_wartosci_cechy, etykieta, lista_klas): + liczba_wystapien_cechy = dane_wartosci_cechy.shape[0] + entropia = 0 + + for klasa in lista_klas: + liczba_wystapien_klasy = dane_wartosci_cechy[dane_wartosci_cechy[etykieta] == klasa].shape[0] + entropia_klasy = 0 + + if liczba_wystapien_klasy != 0: + prawdopodobienstwo_klasy = liczba_wystapien_klasy / liczba_wystapien_cechy + entropia_klasy = - prawdopodobienstwo_klasy * np.log2(prawdopodobienstwo_klasy) + + entropia += entropia_klasy + + return entropia + + + # Obliczanie przyrostu informacji dla danej cechy + def oblicz_przyrost_informacji(self,nazwa_cechy, dane_treningowe, etykieta, lista_klas): + unikalne_wartosci_cechy = dane_treningowe[nazwa_cechy].unique() + liczba_wierszy = dane_treningowe.shape[0] + informacja_cechy = 0.0 + + for wartosc_cechy in unikalne_wartosci_cechy: + dane_wartosci_cechy = dane_treningowe[dane_treningowe[nazwa_cechy] == wartosc_cechy] + liczba_wystapien_wartosci_cechy = dane_wartosci_cechy.shape[0] + entropia_wartosci_cechy = self.oblicz_entropie(dane_wartosci_cechy, etykieta, lista_klas) + prawdopodobienstwo_wartosci_cechy = liczba_wystapien_wartosci_cechy / liczba_wierszy + informacja_cechy += prawdopodobienstwo_wartosci_cechy * entropia_wartosci_cechy + + return self.oblicz_calkowita_entropie(dane_treningowe, etykieta, lista_klas) - informacja_cechy + + + # Znajdowanie najbardziej informatywnej cechy (cechy o najwyższym przyroście informacji) + def znajdz_najbardziej_informatywna_ceche(self,dane_treningowe, etykieta, lista_klas): + lista_cech = dane_treningowe.columns.drop(etykieta) + # Etykieta nie jest cechą, więc ją usuwamy + max_przyrost_informacji = -1 + najbardziej_informatywna_cecha = None + + for cecha in lista_cech: + przyrost_informacji_cechy = self.oblicz_przyrost_informacji(cecha, dane_treningowe, etykieta, lista_klas) + + if max_przyrost_informacji < przyrost_informacji_cechy: + max_przyrost_informacji = przyrost_informacji_cechy + najbardziej_informatywna_cecha = cecha + + return najbardziej_informatywna_cecha + + + # Dodawanie węzła do drzewa + def generuj_poddrzewo(self,nazwa_cechy, dane_treningowe, etykieta, lista_klas): + slownik_licznosci_wartosci_cechy = dane_treningowe[nazwa_cechy].value_counts(sort=False) + drzewo = {} + + for wartosc_cechy, liczba in slownik_licznosci_wartosci_cechy.items(): + dane_wartosci_cechy = dane_treningowe[dane_treningowe[nazwa_cechy] == wartosc_cechy] + + przypisany_do_wezla = False + for klasa in lista_klas: + liczba_klasy = dane_wartosci_cechy[dane_wartosci_cechy[etykieta] == klasa].shape[0] + + if liczba_klasy == liczba: + drzewo[wartosc_cechy] = klasa + dane_treningowe = dane_treningowe[dane_treningowe[nazwa_cechy] != wartosc_cechy] + przypisany_do_wezla = True + if not przypisany_do_wezla: + drzewo[wartosc_cechy] = "?" + + return drzewo, dane_treningowe + + + # Wykonywanie algorytmu ID3 i generowanie drzewa + def generuj_drzewo(self,korzen, poprzednia_wartosc_cechy, dane_treningowe, etykieta, lista_klas): + if dane_treningowe.shape[0] != 0: + najbardziej_informatywna_cecha = self.znajdz_najbardziej_informatywna_ceche(dane_treningowe, etykieta, lista_klas) + drzewo, dane_treningowe = self.generuj_poddrzewo(najbardziej_informatywna_cecha, dane_treningowe, etykieta, lista_klas) + nastepny_korzen = None + + if poprzednia_wartosc_cechy is not None: + korzen[poprzednia_wartosc_cechy] = dict() + korzen[poprzednia_wartosc_cechy][najbardziej_informatywna_cecha] = drzewo + nastepny_korzen = korzen[poprzednia_wartosc_cechy][najbardziej_informatywna_cecha] + else: + korzen[najbardziej_informatywna_cecha] = drzewo + nastepny_korzen = korzen[najbardziej_informatywna_cecha] + + for wezel, galezie in list(nastepny_korzen.items()): + if galezie == "?": + dane_wartosci_cechy = dane_treningowe[dane_treningowe[najbardziej_informatywna_cecha] == wezel] + self.generuj_drzewo(nastepny_korzen, wezel, dane_wartosci_cechy, etykieta, lista_klas) + + + # Znajdowanie unikalnych klas etykiety i rozpoczęcie algorytmu + def id3(self,nasze_dane, etykieta): + dane_treningowe = nasze_dane.copy() + drzewo = {} + lista_klas = dane_treningowe[etykieta].unique() + self.generuj_drzewo(drzewo, None, dane_treningowe, etykieta, lista_klas) + return drzewo + + + # Przewidywanie na podstawie drzewa + def przewiduj(self,drzewo, instancja): + if not isinstance(drzewo, dict): + return drzewo + else: + korzen = next(iter(drzewo)) + wartosc_cechy = instancja[korzen] + if wartosc_cechy in drzewo[korzen]: + return self.przewiduj(drzewo[korzen][wartosc_cechy], instancja) + else: + return 'walcz' + + def tree(self,przyklad): + # Wczytywanie danych + nasze_dane = pd.read_csv("data") + + drzewo = self.id3(nasze_dane, 'akcja') + + return self.przewiduj(drzewo, przyklad) + + + + + + + + #print(przewiduj(drzewo, przyklad)) + #print(drzewo) diff --git a/drzewo_decyzyjne/drzewo_decyzyjne.py b/drzewo_decyzyjne/drzewo_decyzyjne.py deleted file mode 100644 index ad25102..0000000 --- a/drzewo_decyzyjne/drzewo_decyzyjne.py +++ /dev/null @@ -1,148 +0,0 @@ -import pandas as pd -import numpy as np - -# Wczytywanie danych -nasze_dane = pd.read_csv("drzewo_decyzyjne\data") - - -# Obliczanie entropii dla całego zbioru danych -def oblicz_calkowita_entropie(dane_treningowe, etykieta, lista_klas): - liczba_wierszy = dane_treningowe.shape[0] - calkowita_entropia = 0 - - for klasa in lista_klas: - liczba_wystapien_klasy = dane_treningowe[dane_treningowe[etykieta] == klasa].shape[0] - entropia_klasy = - (liczba_wystapien_klasy / liczba_wierszy) * np.log2(liczba_wystapien_klasy / liczba_wierszy) - calkowita_entropia += entropia_klasy - - return calkowita_entropia - - -# Obliczanie entropii dla przefiltrowanego zbioru danych -def oblicz_entropie(dane_wartosci_cechy, etykieta, lista_klas): - liczba_wystapien_cechy = dane_wartosci_cechy.shape[0] - entropia = 0 - - for klasa in lista_klas: - liczba_wystapien_klasy = dane_wartosci_cechy[dane_wartosci_cechy[etykieta] == klasa].shape[0] - entropia_klasy = 0 - - if liczba_wystapien_klasy != 0: - prawdopodobienstwo_klasy = liczba_wystapien_klasy / liczba_wystapien_cechy - entropia_klasy = - prawdopodobienstwo_klasy * np.log2(prawdopodobienstwo_klasy) - - entropia += entropia_klasy - - return entropia - - -# Obliczanie przyrostu informacji dla danej cechy -def oblicz_przyrost_informacji(nazwa_cechy, dane_treningowe, etykieta, lista_klas): - unikalne_wartosci_cechy = dane_treningowe[nazwa_cechy].unique() - liczba_wierszy = dane_treningowe.shape[0] - informacja_cechy = 0.0 - - for wartosc_cechy in unikalne_wartosci_cechy: - dane_wartosci_cechy = dane_treningowe[dane_treningowe[nazwa_cechy] == wartosc_cechy] - liczba_wystapien_wartosci_cechy = dane_wartosci_cechy.shape[0] - entropia_wartosci_cechy = oblicz_entropie(dane_wartosci_cechy, etykieta, lista_klas) - prawdopodobienstwo_wartosci_cechy = liczba_wystapien_wartosci_cechy / liczba_wierszy - informacja_cechy += prawdopodobienstwo_wartosci_cechy * entropia_wartosci_cechy - - return oblicz_calkowita_entropie(dane_treningowe, etykieta, lista_klas) - informacja_cechy - - -# Znajdowanie najbardziej informatywnej cechy (cechy o najwyższym przyroście informacji) -def znajdz_najbardziej_informatywna_ceche(dane_treningowe, etykieta, lista_klas): - lista_cech = dane_treningowe.columns.drop(etykieta) - # Etykieta nie jest cechą, więc ją usuwamy - max_przyrost_informacji = -1 - najbardziej_informatywna_cecha = None - - for cecha in lista_cech: - przyrost_informacji_cechy = oblicz_przyrost_informacji(cecha, dane_treningowe, etykieta, lista_klas) - - if max_przyrost_informacji < przyrost_informacji_cechy: - max_przyrost_informacji = przyrost_informacji_cechy - najbardziej_informatywna_cecha = cecha - - return najbardziej_informatywna_cecha - - -# Dodawanie węzła do drzewa -def generuj_poddrzewo(nazwa_cechy, dane_treningowe, etykieta, lista_klas): - slownik_licznosci_wartosci_cechy = dane_treningowe[nazwa_cechy].value_counts(sort=False) - drzewo = {} - - for wartosc_cechy, liczba in slownik_licznosci_wartosci_cechy.items(): - dane_wartosci_cechy = dane_treningowe[dane_treningowe[nazwa_cechy] == wartosc_cechy] - - przypisany_do_wezla = False - for klasa in lista_klas: - liczba_klasy = dane_wartosci_cechy[dane_wartosci_cechy[etykieta] == klasa].shape[0] - - if liczba_klasy == liczba: - drzewo[wartosc_cechy] = klasa - dane_treningowe = dane_treningowe[dane_treningowe[nazwa_cechy] != wartosc_cechy] - przypisany_do_wezla = True - if not przypisany_do_wezla: - drzewo[wartosc_cechy] = "?" - - return drzewo, dane_treningowe - - -# Wykonywanie algorytmu ID3 i generowanie drzewa -def generuj_drzewo(korzen, poprzednia_wartosc_cechy, dane_treningowe, etykieta, lista_klas): - if dane_treningowe.shape[0] != 0: - najbardziej_informatywna_cecha = znajdz_najbardziej_informatywna_ceche(dane_treningowe, etykieta, lista_klas) - drzewo, dane_treningowe = generuj_poddrzewo(najbardziej_informatywna_cecha, dane_treningowe, etykieta, lista_klas) - nastepny_korzen = None - - if poprzednia_wartosc_cechy is not None: - korzen[poprzednia_wartosc_cechy] = dict() - korzen[poprzednia_wartosc_cechy][najbardziej_informatywna_cecha] = drzewo - nastepny_korzen = korzen[poprzednia_wartosc_cechy][najbardziej_informatywna_cecha] - else: - korzen[najbardziej_informatywna_cecha] = drzewo - nastepny_korzen = korzen[najbardziej_informatywna_cecha] - - for wezel, galezie in list(nastepny_korzen.items()): - if galezie == "?": - dane_wartosci_cechy = dane_treningowe[dane_treningowe[najbardziej_informatywna_cecha] == wezel] - generuj_drzewo(nastepny_korzen, wezel, dane_wartosci_cechy, etykieta, lista_klas) - - -# Znajdowanie unikalnych klas etykiety i rozpoczęcie algorytmu -def id3(nasze_dane, etykieta): - dane_treningowe = nasze_dane.copy() - drzewo = {} - lista_klas = dane_treningowe[etykieta].unique() - generuj_drzewo(drzewo, None, dane_treningowe, etykieta, lista_klas) - return drzewo - - -# Przewidywanie na podstawie drzewa -def przewiduj(drzewo, instancja): - if not isinstance(drzewo, dict): - return drzewo - else: - korzen = next(iter(drzewo)) - wartosc_cechy = instancja[korzen] - if wartosc_cechy in drzewo[korzen]: - return przewiduj(drzewo[korzen][wartosc_cechy], instancja) - else: - return 'walcz' - - -drzewo = id3(nasze_dane, 'akcja') - -przyklad = {'zdrowie_bohatera': '100', - 'moc_bohatera': 'nie', - 'moc_moba': 'nie', - 'lvl_wiekszy_bohater': 'tak', - 'mob_jest_strzelcem': 'nie', - 'zdrowie_moba': '1', - 'artefakt': 'tak'} - -print(przewiduj(drzewo, przyklad)) -print(drzewo) diff --git a/main.py b/main.py index 9b4a188..2e73a3c 100644 --- a/main.py +++ b/main.py @@ -9,7 +9,7 @@ from nn import * from astar import * import math import random - +from drzewo_decyzyjne import * class Game: @@ -31,7 +31,7 @@ class Game: self.bfs = Bfs(self) self.nn = NeuralN() self.astar = Astar(self) - + self.tree = Tree() self.cell_costs = [[1 for _ in range(TILE_SIZE)] for _ in range(TILE_SIZE)] self.obstacles = [[False for _ in range(TILE_SIZE)] for _ in range(TILE_SIZE)] @@ -277,30 +277,7 @@ class Game: self.obstacles[self.najlepszaGeneracja[y+11][0]][self.najlepszaGeneracja[y+11][1]] = True self.bfs.wall_cells.append(self.bfs.get_cell_number(self.rock.x,self.rock.y)) - """ to jest tak jak bylo zmieniam tylko pozycje elementow - self.agent = Agent(self,1,1) - self.archer_ork = Archer_ork(self,10,10) - self.obstacles[10][10] = True - self.bfs.enemy_cells.append(self.bfs.get_cell_number(self.archer_ork.x,self.archer_ork.y)) - self.infantry_ork = Infantry_ork(self,10,4) - self.obstacles[10][4] = True - self.bfs.enemy_cells.append(self.bfs.get_cell_number(self.infantry_ork.x,self.infantry_ork.y)) - - self.sauron = Sauron(self, 1, 10) - self.obstacles[1][10] = True - self.bfs.enemy_cells.append(self.bfs.get_cell_number(self.sauron.x,self.sauron.y)) - self.flower = Health_flower(self, 8,2) - - for y in range (2,5): - for x in range (2): - self.grass = Grass(self,x,y) - self.cell_costs[x][y] = 5 - - for y in range(5): - self.rock = Rocks(self,3,y) - self.obstacles[3][y] = True - self.bfs.wall_cells.append(self.bfs.get_cell_number(self.rock.x,self.rock.y)) - """ + def update(self): self.all_sprites.update() @@ -327,21 +304,50 @@ class Game: mob_image = self.sauron.image_path prediction = self.prediction_road(x,y,mob_image) prediction = "SAURON" - while True: #do poprawienia poprawne rozpoznawanie póki co nie będzie działać dobrze, program się będzie zawieszać - if prediction == "SAURON" and self.agent.level < 3: - x = self.archer_ork.x - y = self.archer_ork.y - goal = x//TILE_SIZE,y//TILE_SIZE - mob_image = self.archer_ork.image_path - prediction = self.prediction_road(x,y,mob_image) - prediction = "ORK_ARCHER" - elif prediction == "SAURON" and self.agent.level >= 3: - self.obstacles[self.najlepszaGeneracja[3][0]][self.najlepszaGeneracja[3][1]] = False - self.move_agent(self.astar.a_star(goal)) - + while True: #do poprawienia poprawne rozpoznawanie + print("goal: ",goal) + if prediction == "SAURON": + if self.agent.level < self.sauron.level: + lvl = 'nie' + else: + lvl = 'tak' + przyklad = {'zdrowie_bohatera': '100', + 'moc_bohatera': 'tak', + 'moc_moba': 'tak', + 'lvl_wiekszy_bohater': lvl, + 'mob_jest_strzelcem': self.sauron.archer, + 'zdrowie_moba': '50', + 'artefakt': self.agent.artifact} + decision = self.tree.tree(przyklad) + print(decision) + if decision == "walcz": + self.obstacles[self.najlepszaGeneracja[3][0]][self.najlepszaGeneracja[3][1]] = False + self.move_agent(self.astar.a_star(goal)) + else: + x = self.archer_ork.x + y = self.archer_ork.y + goal = x//TILE_SIZE,y//TILE_SIZE + mob_image = self.archer_ork.image_path + prediction = self.prediction_road(x,y,mob_image) + prediction = "ORK_ARCHER" + elif prediction == "ORK_INFANTRY": - self.obstacles[self.najlepszaGeneracja[2][0]][self.najlepszaGeneracja[2][1]] = False - self.move_agent(self.astar.a_star(goal)) + if self.agent.level < self.infantry_ork.level: + lvl = 'nie' + else: + lvl = 'tak' + przyklad = {'zdrowie_bohatera': '100', + 'moc_bohatera': 'tak', + 'moc_moba': 'tak', + 'lvl_wiekszy_bohater': lvl, + 'mob_jest_strzelcem': self.infantry_ork.archer, + 'zdrowie_moba': '50', + 'artefakt': self.agent.artifact} + decision = self.tree.tree(przyklad) + print(decision) + if decision == "walcz": + self.obstacles[self.najlepszaGeneracja[2][0]][self.najlepszaGeneracja[2][1]] = False + self.move_agent(self.astar.a_star(goal)) if self.agent.current_health < self.agent.max_health: goal = (self.flower.x//TILE_SIZE, self.flower.y//TILE_SIZE) self.move_agent(self.astar.a_star(goal)) @@ -352,8 +358,24 @@ class Game: prediction = self.prediction_road(x,y,mob_image) prediction = "SAURON" elif prediction == "ORK_ARCHER": - self.obstacles[self.najlepszaGeneracja[1][0]][self.najlepszaGeneracja[1][1]] = False - self.move_agent(self.astar.a_star(goal)) + if self.agent.level < self.archer_ork.level: + lvl = 'nie' + else: + lvl = 'tak' + przyklad = {'zdrowie_bohatera': '100', + 'moc_bohatera': 'tak', + 'moc_moba': 'tak', + 'lvl_wiekszy_bohater': lvl, + 'mob_jest_strzelcem': self.archer_ork.archer, + 'zdrowie_moba': '50', + 'artefakt': self.agent.artifact} + decision = self.tree.tree(przyklad) + print(decision) + if decision == "walcz": + self.obstacles[self.najlepszaGeneracja[1][0]][self.najlepszaGeneracja[1][1]] = False + + self.move_agent(self.astar.a_star(goal)) + if self.agent.current_health < self.agent.max_health: goal = (self.flower.x//TILE_SIZE, self.flower.y//TILE_SIZE) self.move_agent(self.astar.a_star(goal)) @@ -387,7 +409,7 @@ class Game: print("PATH:::::",path) for cell_to_move in path: x, y = self.bfs.get_coordinates(cell_to_move) - print("Ruch do kratki : ", cell_to_move, " z x: ", x, ", y: ", y, ", agent.x: ", self.agent.rect.x, ", agent.y: ", self.agent.rect.y) + #print("Ruch do kratki : ", cell_to_move, " z x: ", x, ", y: ", y, ", agent.x: ", self.agent.rect.x, ", agent.y: ", self.agent.rect.y) if(self.bfs.get_cell_number(self.agent.rect.x,self.agent.rect.y)!=cell_to_move): if x > self.agent.rect.x: self.agent.direction = 0 @@ -414,7 +436,7 @@ class Game: self.update() self.map() - print("Polozenie agenta: agent.x: ", self.agent.rect.x, ", agent.y: ", self.agent.rect.y) + #print("Polozenie agenta: agent.x: ", self.agent.rect.x, ", agent.y: ", self.agent.rect.y) self.clock.tick(2) def map(self): # tworzenie mapy diff --git a/mobs.py b/mobs.py index d9b6def..8e3e361 100644 --- a/mobs.py +++ b/mobs.py @@ -29,6 +29,8 @@ class Archer_ork(pygame.sprite.Sprite): self.level = 1 self.damage = 50*self.level self.health = 50 + + self.archer = 'tak' class Infantry_ork(pygame.sprite.Sprite): @@ -59,6 +61,8 @@ class Infantry_ork(pygame.sprite.Sprite): self.damage = 50*self.level self.health = 100 + self.archer = 'nie' + class Sauron(pygame.sprite.Sprite): @@ -87,4 +91,6 @@ class Sauron(pygame.sprite.Sprite): self.level = 3 self.damage = 50*self.level - self.health = 150 \ No newline at end of file + self.health = 150 + + self.archer = 'nie' \ No newline at end of file diff --git a/drzewo_decyzyjne/wyglad_drzewa b/wyglad_drzewa similarity index 100% rename from drzewo_decyzyjne/wyglad_drzewa rename to wyglad_drzewa