diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..b920e7d Binary files /dev/null and b/.DS_Store differ diff --git a/.ipynb_checkpoints/Untitled-checkpoint.ipynb b/.ipynb_checkpoints/Untitled-checkpoint.ipynb new file mode 100644 index 0000000..d20f756 --- /dev/null +++ b/.ipynb_checkpoints/Untitled-checkpoint.ipynb @@ -0,0 +1,109 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 9, + "id": "fac14368", + "metadata": {}, + "outputs": [], + "source": [ + "dataset = pandas.read_csv('/Users/mac/Desktop/tree_dataset.csv', sep=\";\")\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4d25d809", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "663eaf94", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3c9b416", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bcfb233e", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "11f0c1a2", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b1a93eb4", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "528f6ade", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "efb466fe", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5dbe234e", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "env", + "language": "python", + "name": "env" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Untitled.ipynb b/Untitled.ipynb new file mode 100644 index 0000000..a339a94 --- /dev/null +++ b/Untitled.ipynb @@ -0,0 +1,126 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 24, + "id": "fac14368", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1]\n" + ] + } + ], + "source": [ + "from sklearn.tree import DecisionTreeClassifier, export_text, plot_tree\n", + "dataset = pandas.read_csv('/Users/mac/Desktop/tree_dataset.csv', sep=\";\")\n", + "decisions = [\"decision\"]\n", + "attributes = [\"season\", \"trash_type\", \"mass\", \"space\", \"trash_mass\"]\n", + "\n", + "x = dataset[attributes]\n", + "y = dataset[decisions]\n", + "decision_tree = DecisionTreeClassifier()\n", + "decision_tree.fit(x.values, y.values)\n", + "decision = decision_tree.predict(\n", + " [[5, 3 , 3, 1, 2]])\n", + "print(decision)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "04bbec40", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9c1d0193", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8e40a924", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b430f8b8", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "58ce5faa", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a4b72d3d", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b4e0aae9", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "74fb263f", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5dbe234e", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "env", + "language": "python", + "name": "env" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/decision_tree/decisionTree.py b/decision_tree/decisionTree.py index f15b77c..3986b0e 100644 --- a/decision_tree/decisionTree.py +++ b/decision_tree/decisionTree.py @@ -3,37 +3,26 @@ import matplotlib.pyplot as plt import pandas from sklearn.tree import DecisionTreeClassifier, export_text, plot_tree -''' -atrybuty w pliku csv muszą być integerami, wstępnie ustaliłem: -season = {"wiosna": 1, "lato": 2, "jesien":3, "zima":4} -enough_space_in_trashmaster = { "no": 1, "yes":2} -time_since_flush = [1,2,3,4,5,6,7,8,9,10] -type_of_trash = {"bio":1, "szklo":2, "plastik":3, "papier":4, "mieszane":5} -access_to_bin = { "no":1, "yes":2} -distance = [1,2,3,4,5,6,7,8,9,10] -decision = [0,1] - decyzje zostaną zmienione z tych z wagami na zero jedynkowe ze względu na pewne trudności w dalszej pracy -''' decisions = ["decision"] -attributes = ["season", "enough_space_in_trashmaster", "time_since_flush", "type_of_trash", "access_to_bin", "distance"] +attributes = ["season", "trash_type", "mass", "space", "trash_mass"] # return tree made from attributes def tree(): - dataset = pandas.read_csv('./decision_tree/drzewo_decyzyjne.csv') + dataset = pandas.read_csv('/Users/mac/Desktop/tree_dataset.csv', sep=";") x = dataset[attributes] y = dataset[decisions] decision_tree = DecisionTreeClassifier() - decision_tree = decision_tree.fit(x, y) + decision_tree = decision_tree.fit(x.values, y.values) return decision_tree # return decision made from tree and attributes -def decision(decision_tree, season, enough_space_in_trashmaster, time_since_flush, type_of_trash, access_to_bin, - distance): +def decision(decision_tree, season, trash_type, mass, space, trash_mass): decision = decision_tree.predict( - [[season, enough_space_in_trashmaster, time_since_flush, type_of_trash, access_to_bin, distance]]) + [[season, trash_type , mass, space, trash_mass]]) return decision diff --git a/decision_tree/tree_as_txt.txt b/decision_tree/tree_as_txt.txt index 28a1fd5..af74d02 100644 --- a/decision_tree/tree_as_txt.txt +++ b/decision_tree/tree_as_txt.txt @@ -1,94 +1,91 @@ -|--- feature_4 <= 1.50 -| |--- feature_5 <= 1.50 -| | |--- feature_2 <= 6.50 +|--- feature_2 <= 3.50 +| |--- feature_4 <= 3.50 +| | |--- feature_0 <= 1.50 | | | |--- class: 0 -| | |--- feature_2 > 6.50 -| | | |--- feature_0 <= 3.00 -| | | | |--- class: 1 -| | | |--- feature_0 > 3.00 -| | | | |--- class: 0 -| |--- feature_5 > 1.50 -| | |--- class: 0 -|--- feature_4 > 1.50 -| |--- feature_1 <= 1.50 -| | |--- feature_0 <= 3.50 -| | | |--- class: 0 -| | |--- feature_0 > 3.50 -| | | |--- class: 1 -| |--- feature_1 > 1.50 -| | |--- feature_0 <= 3.50 -| | | |--- feature_0 <= 1.50 -| | | | |--- feature_3 <= 2.50 +| | |--- feature_0 > 1.50 +| | | |--- feature_3 <= 3.50 +| | | | |--- feature_2 <= 2.50 | | | | | |--- class: 1 -| | | | |--- feature_3 > 2.50 -| | | | | |--- feature_3 <= 3.50 -| | | | | | |--- feature_5 <= 7.50 -| | | | | | | |--- feature_2 <= 5.50 -| | | | | | | | |--- class: 0 -| | | | | | | |--- feature_2 > 5.50 -| | | | | | | | |--- class: 1 -| | | | | | |--- feature_5 > 7.50 -| | | | | | | |--- class: 0 -| | | | | |--- feature_3 > 3.50 +| | | | |--- feature_2 > 2.50 +| | | | | |--- feature_4 <= 2.50 | | | | | | |--- class: 1 -| | | |--- feature_0 > 1.50 -| | | | |--- feature_3 <= 1.50 -| | | | | |--- feature_5 <= 2.50 -| | | | | | |--- feature_5 <= 1.50 -| | | | | | | |--- class: 1 -| | | | | | |--- feature_5 > 1.50 +| | | | | |--- feature_4 > 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_4 <= 2.50 +| | | | | | | | | |--- class: 1 +| | | | | | | | |--- feature_4 > 2.50 +| | | | | | | | | |--- feature_2 <= 2.00 +| | | | | | | | | | |--- class: 1 +| | | | | | | | | |--- feature_2 > 2.00 +| | | | | | | | | | |--- class: 0 +| | | | | | | |--- feature_1 > 1.50 +| | | | | | | | |--- class: 0 +| | | | | | |--- feature_0 > 2.50 +| | | | | | | |--- feature_4 <= 2.50 +| | | | | | | | |--- class: 1 +| | | | | | | |--- feature_4 > 2.50 +| | | | | | | | |--- feature_2 <= 2.50 +| | | | | | | | | |--- class: 1 +| | | | | | | | |--- feature_2 > 2.50 +| | | | | | | | | |--- class: 0 +| | | | | |--- feature_1 > 2.50 +| | | | | | |--- feature_0 <= 3.50 +| | | | | | | |--- class: 0 +| | | | | | |--- feature_0 > 3.50 +| | | | | | | |--- feature_1 <= 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_3 <= 4.50 | | | | | | | |--- feature_0 <= 2.50 | | | | | | | | |--- class: 0 | | | | | | | |--- feature_0 > 2.50 | | | | | | | | |--- class: 1 -| | | | | |--- feature_5 > 2.50 -| | | | | | |--- class: 1 -| | | | |--- feature_3 > 1.50 -| | | | | |--- feature_2 <= 3.50 -| | | | | | |--- feature_0 <= 2.50 -| | | | | | | |--- feature_5 <= 2.00 -| | | | | | | | |--- class: 1 -| | | | | | | |--- feature_5 > 2.00 -| | | | | | | | |--- feature_5 <= 4.00 -| | | | | | | | | |--- class: 0 -| | | | | | | | |--- feature_5 > 4.00 -| | | | | | | | | |--- feature_3 <= 2.50 -| | | | | | | | | | |--- feature_5 <= 7.00 -| | | | | | | | | | | |--- class: 0 -| | | | | | | | | | |--- feature_5 > 7.00 -| | | | | | | | | | | |--- class: 1 -| | | | | | | | | |--- feature_3 > 2.50 -| | | | | | | | | | |--- class: 1 -| | | | | | |--- feature_0 > 2.50 -| | | | | | | |--- class: 1 -| | | | | |--- feature_2 > 3.50 -| | | | | | |--- feature_5 <= 1.50 +| | | | | | |--- feature_3 > 4.50 | | | | | | | |--- class: 0 -| | | | | | |--- feature_5 > 1.50 -| | | | | | | |--- feature_3 <= 2.50 -| | | | | | | | |--- feature_5 <= 5.00 -| | | | | | | | | |--- class: 1 -| | | | | | | | |--- feature_5 > 5.00 -| | | | | | | | | |--- class: 0 -| | | | | | | |--- feature_3 > 2.50 -| | | | | | | | |--- feature_5 <= 5.50 -| | | | | | | | | |--- feature_0 <= 2.50 -| | | | | | | | | | |--- feature_2 <= 4.50 -| | | | | | | | | | | |--- class: 0 -| | | | | | | | | | |--- feature_2 > 4.50 -| | | | | | | | | | | |--- class: 0 -| | | | | | | | | |--- feature_0 > 2.50 -| | | | | | | | | | |--- feature_2 <= 4.50 -| | | | | | | | | | | |--- class: 0 -| | | | | | | | | | |--- feature_2 > 4.50 -| | | | | | | | | | | |--- truncated branch of depth 2 -| | | | | | | | |--- feature_5 > 5.50 -| | | | | | | | | |--- feature_5 <= 6.50 -| | | | | | | | | | |--- class: 1 -| | | | | | | | | |--- feature_5 > 6.50 -| | | | | | | | | | |--- feature_2 <= 8.50 -| | | | | | | | | | | |--- truncated branch of depth 3 -| | | | | | | | | | |--- feature_2 > 8.50 -| | | | | | | | | | | |--- truncated branch of depth 4 -| | |--- feature_0 > 3.50 -| | | |--- class: 1 +| | | | | |--- 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_3 <= 4.50 +| | | | | |--- feature_0 <= 1.50 +| | | | | | |--- class: 0 +| | | | | |--- feature_0 > 1.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 diff --git a/decision_tree/tree_model b/decision_tree/tree_model index ef984c8..b28c9a3 100644 Binary files a/decision_tree/tree_model and b/decision_tree/tree_model differ diff --git a/game_objects/trashbin.py b/game_objects/trashbin.py index 9b8ea8b..f6f37da 100644 --- a/game_objects/trashbin.py +++ b/game_objects/trashbin.py @@ -1,23 +1,23 @@ import pygame as pg from enum import Enum - +from random import randrange from map.tile import Tile - -class Waste_Type(Enum): - BIO = 0 - GLASS = 1 - PLASTIC = 2 - PAPER = 3 - MIX = 4 - - def __int__(self): - return self.value class Trashbin(Tile): - def __init__(self, img, x, y, width, height, waste_type: Waste_Type): + def __init__(self, img, x, y, width, height, waste_type): super().__init__(img, x, y, width, height) + # dis_dump dis_trash mass space trash_mass trash_space + self.x = x + self.y = y - self.waste_type = waste_type - self.days_after_pickup = 0 - self.max_capacity = 100 - self.used_capacity = 0 - self.access = True + self.season = randrange(4) + self.trash_type = randrange(5) + self.mass = randrange(5) + self.space = randrange(5) + self.trash_mass = randrange(5) + + + def get_coords(self): + return (self.x, self.y) + + def get_attributes(self): + return (self.season, self.trash_type, self.mass, self.space, self.trash_mass) diff --git a/main.py b/main.py index e7c2476..fe582db 100644 --- a/main.py +++ b/main.py @@ -13,17 +13,22 @@ from path_search_algorthms import a_star, a_star_utils from decision_tree import decisionTree from game_objects import aiPlayer +import itertools -def printTree(): +def getTree(): tree = decisionTree.tree() decisionTree.tree_as_txt(tree) - decisionTree.tree_to_png(tree) + # decisionTree.tree_to_png(tree) decisionTree.tree_to_structure(tree) drzewo = decisionTree.tree_from_structure('./decision_tree/tree_model') - print("Dla losowych danych predykcja czy wziąć kosz to: ") - dec = decisionTree.decision(drzewo, 4, 2, 7, 4, 2, 3) - print(dec) + # print("Dla losowych danych predykcja czy wziąć kosz to: ") + # dec = decisionTree.decision(drzewo, *(4,1,1,1)) + # print('---') + # print(f"decision is{dec}") + # print('---') + + return drzewo class Game(): @@ -31,6 +36,7 @@ class Game(): def __init__(self): pg.init() self.clock = pg.time.Clock() + self.dt = self.clock.tick(FPS) / 333.0 self.screen = pg.display.set_mode((WIDTH, HEIGHT)) pg.display.set_caption("Trashmaster") self.load_data() @@ -38,8 +44,17 @@ class Game(): # because dont work without data.txt # self.init_bfs() # self.init_a_star() + self.t = aiPlayer.aiPlayer(self.player, game=self) - self.dt = self.clock.tick(FPS) / 1000.0 + + def get_actions_by_coords(self,x,y): + pos = (x,y) + 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.search_path(math.floor(self.player.pos[0] / TILESIZE), + math.floor(self.player.pos[1] / TILESIZE), self.player.rotation(), + clicked_coords[0], clicked_coords[1], self.mapArray) + return actions def init_game(self): # initialize all variables and do all the setup for a new game @@ -47,16 +62,15 @@ class Game(): # sprite groups and map array for calculations (self.roadTiles, self.wallTiles, self.trashbinTiles), self.mapArray = map.get_tiles() self.agentSprites = pg.sprite.Group() - # player obj self.player = Player(self, 32, 32) - # camera obj self.camera = map_utils.Camera(MAP_WIDTH_PX, MAP_HEIGHT_PX) # other self.debug_mode = False + def init_bfs(self): start_node = (0, 0) target_node = (18, 18) @@ -81,6 +95,38 @@ class Game(): path = a_star.search_path(start_x, start_y, target_x, target_y, self.mapArray) print(path) + def init_decision_tree(self): + # logika pracy z drzewem + self.positive_decision = [] + self.negative_decision = [] + + self.positive_actions = [] + self.negative_actions = [] + for i in self.trashbinTiles: + atrrs_container = i.get_attributes() + x, y = i.get_coords() + dec = decisionTree.decision(getTree(), *atrrs_container) + if dec[0] == 1: + self.positive_decision.append(i) + self.positive_actions.append(self.get_actions_by_coords(x, y)) + else: + self.negative_decision.append(i) + self.negative_actions.append(i) + + # j = 0 + # for i in self.positive_actions: + + # print(f"step {j} actions is : {i}") + # j+=1 + + # vec = pg.math.Vector2 + # for i in self.positive_actions: + # self.t.startAiController(i) + # self.player.pos = vec(32, 32) + + self.t.startAiController(self.positive_actions[0]) + + def load_data(self): game_folder = path.dirname(__file__) img_folder = path.join(game_folder, 'resources/textures') @@ -91,7 +137,7 @@ class Game(): def run(self): # game loop - set self.playing = False to end the game self.playing = True - + self.init_decision_tree() while self.playing: self.dt = self.clock.tick(FPS) / 1000.0 self.events() @@ -142,24 +188,17 @@ class Game(): actions = a_star.search_path(math.floor(self.player.pos[0] / TILESIZE), math.floor(self.player.pos[1] / TILESIZE), self.player.rotation(), clicked_coords[0], clicked_coords[1], self.mapArray) - print(actions) + # print(actions) + if (actions != None): - t = aiPlayer.aiPlayer(self.player, game=self) - t.startAiController(actions) - - def show_start_screen(self): - pass - - def show_go_screen(self): - pass + self.t.startAiController(actions) + # create the game object if __name__ == "__main__": g = Game() - g.show_start_screen() - printTree() - + g.run() g.show_go_screen() \ No newline at end of file diff --git a/map/map_utils.py b/map/map_utils.py index 1a32047..1904528 100644 --- a/map/map_utils.py +++ b/map/map_utils.py @@ -21,13 +21,15 @@ def generate_map(): map[y][x] = 1 # generowanie smietnikow - for i in range(0, 5): + for i in range(0, 10): x = random.randint(0, MAP_WIDTH-1) y = random.randint(0, MAP_HEIGHT-1) map[y][x] = 2 return map +trashbins =[] + # tworzenie grup sprite'ow def get_sprites(map, pattern): roadTiles = pg.sprite.Group() @@ -54,6 +56,7 @@ def get_sprites(map, pattern): trashbin = Trashbin(trashbin_pattern[trashbinId], offsetX, offsetY, 32, 30, trashbinId) roadTiles.add(tile) trashbinTiles.add(trashbin) + trashbins.append(trashbin) return roadTiles, wallTiles, trashbinTiles