diff --git a/Field.py b/Field.py index 3167904..985199f 100644 --- a/Field.py +++ b/Field.py @@ -8,6 +8,14 @@ class Field: def state(self): return self.__state + @property + def horizontal_index(self): + return self.__horizontal_index + + @property + def vertical_index(self): + return self.__vertical_index + @property def cost(self): if self.state == 'toPlow': @@ -17,20 +25,12 @@ class Field: elif self.state == 'toFertilize': return 3 elif self.state == 'toWater': - return 4 + return 200 elif self.state == 'toCut': - return 5 + return 99 else: return 0 - @property - def horizontal_index(self): - return self.__horizontal_index - - @property - def vertical_index(self): - return self.__vertical_index - @state.setter def state(self, state): if state == "toPlow" or state == "toWater" or state == "toSeed" or \ diff --git a/FindPath.py b/FindPath.py index af47d1d..630cf7c 100644 --- a/FindPath.py +++ b/FindPath.py @@ -1,21 +1,7 @@ from constants import * -from queue import Queue - - -class Node: - def __init__(self, parent: (int, int), index: (int, int)): - self.__index = index - self.__parent = parent - - def get_index(self): - return self.__index - - def get_parent(self): - return self.__parent - def whichStateLookingFor(tractor, TillageUnit): - searching_field = "toPlow" + searching_field = "none" if tractor.header and tractor.hitch == "Crop Trailer": searching_field = "toCut" elif isinstance(tractor.hitch, TillageUnit) and tractor.hitch.load == "Nothing": @@ -30,87 +16,15 @@ def whichStateLookingFor(tractor, TillageUnit): def nearestLookingField(board, tractor, TillageUnit): - horizontal_tiles_number = int(HORIZONTAL_TILES_NUMBER) - vertical_tiles_number = int(VERTICAL_TILES_NUMBER) - - print(horizontal_tiles_number, vertical_tiles_number) - a = input() end_horizontal_index = 0 end_vertical_index = 0 searching_field = whichStateLookingFor(tractor, TillageUnit) - for i in range(horizontal_tiles_number): - for j in range(vertical_tiles_number): + for i in range(0, int(HORIZONTAL_TILES_NUMBER)): + for j in range(0, int(VERTICAL_TILES_NUMBER)): field = board[i][j] if searching_field == field.state: - end_horizontal_index = field.horizontal_index - end_vertical_index = field.vertical_index - break + end_horizontal_index = field.horizontal_index / TILE_SIZE + end_vertical_index = field.vertical_index / TILE_SIZE + return end_horizontal_index, end_vertical_index - return end_horizontal_index, end_vertical_index - - -def graphsearch(tractor, board, TillageUnit, fringe: Queue, explored): - start_horizontal_index = tractor.horizontal_index - start_vertical_index = tractor.vertical_index - start_state = (start_horizontal_index, start_vertical_index) - end_state = nearestLookingField(board, tractor, TillageUnit) - print(start_state) - print(end_state) - - fringe.put(start_state) - - while True: - if fringe.empty(): - return False - - elem = fringe.get() - - if goaltest(elem, end_state): - break - #TODO - #return droga ktora musi pokonac traktor - else: - explored.append(elem) - elem = succ(start_state, end_state, tractor) - fringe.put(elem) - - -def goaltest(elem, end_state): - print('element:', elem, 'state:', end_state) - if elem == end_state: - return True - else: - return False - - -def succ(start_state, end_state, tractor): - print(tractor.horizontal_index, ' ', tractor.vertical_index) - a = input() - if start_state[1] < end_state[1]: - if tractor.direction == "RIGHT": - tractor.drive() - print("przesunalem sie w prawo") - else: - tractor.direction = "RIGHT" - - elif start_state[1] > end_state[1]: - if tractor.direction == "LEFT": - tractor.drive() - print("przesunalem sie w lewo") - else: - tractor.direction = "LEFT" - - elif start_state[0] < end_state[0]: - if tractor.direction == "DOWN": - tractor.drive() - print("przesunalem sie w dol") - else: - tractor.direction = "DOWN" - elif start_state[0] > end_state[0]: - if tractor.direction == "UP": - tractor.drive() - print("przesunalem sie w gore") - else: - tractor.direction = "UP" - else: - return tractor.horizontal_index, tractor.horizontal_index \ No newline at end of file + return end_horizontal_index, end_vertical_index \ No newline at end of file diff --git a/Testfile.py b/Testfile.py index e69de29..b18b0eb 100644 --- a/Testfile.py +++ b/Testfile.py @@ -0,0 +1,221 @@ +from itertools import product +import numpy as np +import pandas as pd +import csv +import id3test +import pprint +import sys +import pandas +from sklearn import tree +import pydotplus +from sklearn.tree import DecisionTreeClassifier +import matplotlib.pyplot as plt +import matplotlib.image as pltimg + +field_states = ['toPlow', 'toWater', 'toSeed', 'toFertilize', 'toCut'] +header = ['Equipped', 'Not Equipped'] +hitch = ['Tillage Unit', 'Crop Trailer'] +tillage_unit = ['Seeds', 'Water', 'Fertilizer', 'Nothing'] +engine_working = ['Yes', 'No'] +in_base = ['Yes', 'No'] +fuel = ['Enough', 'Not_Enough'] + +# output = list(product(field_states, header, hitch, tillage_unit, engine_working, in_base, fuel)) +output = list(product(field_states, header, hitch, tillage_unit, in_base)) + +dict = [] +# for x in range(len(output)): +# # dict.append({'field': output[x][0], 'header' : output[x][1], 'hitch' : output[x][2], +# # 'tillage_unit' : output[x][3], 'engine_working' : output[x][4], +# # 'in_base' : output[x][5], 'fuel': output[x][6]}) +# print(x+1, output[x]) + +decisions = [] +curr_decision = "Make Action" + +for x in range(len(output)): + aField = output[x][0] + aHeader = output[x][1] + aHitch = output[x][2] + aTillage_unit = output[x][3] + aIn_base = output[x][4] + + while True: + curr_decision = "Make Action" + + if aField == 'toCut': + if not aHeader == 'Equipped': + if aIn_base == 'Yes': + curr_decision = 'Change Header' + break + else: + curr_decision = 'Go To Base' + break + + if not aHitch == 'Crop Trailer': + if aIn_base == 'Yes': + curr_decision = 'Change Hitch' + break + else: + curr_decision = 'Go To Base' + break + + if aField == 'toPlow': + if aHeader == 'Equipped': + if aIn_base == "Yes": + curr_decision = 'Change Header' + break + else: + curr_decision = 'Go To Base' + break + + if not aHitch == "Tillage Unit": + if aIn_base == "Yes": + curr_decision = "Change Hitch" + break + else: + curr_decision = "Go To Base" + break + if not aTillage_unit == "Nothing": + if aIn_base == "Yes": + curr_decision = "Change Load" + break + else: + curr_decision = "Go To Base" + break + + if aField == 'toSeed': + if aHeader == 'Equipped': + if aIn_base == "Yes": + curr_decision = 'Change Header' + break + else: + curr_decision = 'Go To Base' + break + + if not aHitch == "Tillage Unit": + if aIn_base == "Yes": + curr_decision = "Change Hitch" + break + else: + curr_decision = "Go To Base" + break + if not aTillage_unit == "Seeds": + if aIn_base == "Yes": + curr_decision = "Change Load" + break + else: + curr_decision = "Go To Base" + break + + if aField == 'toWater': + if aHeader == 'Equipped': + if aIn_base == "Yes": + curr_decision = 'Change Header' + break + else: + curr_decision = 'Go To Base' + break + + if not aHitch == "Tillage Unit": + if aIn_base == "Yes": + curr_decision = "Change Hitch" + break + else: + curr_decision = "Go To Base" + break + if not aTillage_unit == "Water": + if aIn_base == "Yes": + curr_decision = "Change Load" + break + else: + curr_decision = "Go To Base" + break + + if aField == 'toFertilize': + if aHeader == 'Equipped': + if aIn_base == "Yes": + curr_decision = 'Change Header' + break + else: + curr_decision = 'Go To Base' + break + + if not aHitch == "Tillage Unit": + if aIn_base == "Yes": + curr_decision = "Change Hitch" + break + else: + curr_decision = "Go To Base" + break + if not aTillage_unit == "Fertilizer": + if aIn_base == "Yes": + curr_decision = "Change Load" + break + else: + curr_decision = "Go To Base" + break + if aIn_base == 'Yes': + curr_decision = 'Go To Field' + break + dict.append({'Field': aField, 'Header': aHeader, 'Hitch': aHitch, 'Tillage_Unit': aTillage_unit, + 'In_Base': aIn_base, 'Decision': curr_decision}) + +print(dict) + +fields = ['Field', 'Header', 'Hitch', 'Tillage_Unit', 'In_Base', 'Decision'] + +filename = "treedata\\data2.csv" + +with open(filename, 'w') as csvfile: + writer = csv.DictWriter(csvfile, fieldnames=fields) + writer.writeheader() + writer.writerows(dict) + +df = pandas.read_csv("treedata\\data2.csv") +print(df) + +# Map text values to number values +d = {'toPlow': 0, 'toWater': 1, 'toSeed': 2, 'toFertilize': 3, 'toCut': 4} +df['Field'] = df['Field'].map(d) + +d = {'Not Equipped': 0, 'Equipped': 1} +df['Header'] = df['Header'].map(d) + +d = {'Tillage Unit': 0, 'Crop Trailer': 1} +df['Hitch'] = df['Hitch'].map(d) + +d = {'Nothing': 0, 'Seeds': 1, 'Water': 2, 'Fertilizer': 3} +df['Tillage_Unit'] = df['Tillage_Unit'].map(d) + +d = {'No': 0, 'Yes': 1} +df['In_Base'] = df['In_Base'].map(d) + +d = {'Make Action': 0, 'Change Header': 1, 'Go To Base': 2, 'Change Hitch': 3, 'Change Load': 4, 'Go To Field': 5} +df['Decision'] = df['Decision'].map(d) + +# Separate the feature columns from targert columns + +features = ['Field', 'Header', 'Hitch', 'Tillage_Unit', 'In_Base'] + +X = df[features] +y = df['Decision'] + +# FIELD 'toPlow' : 0, 'toWater' : 1, 'toSeed' : 2, 'toFertilize' : 3, 'toCut' : 4 +# HEADER 'Not Equipped' : 0, 'Equipped' : 1 +# HITCH 'Tillage Unit' : 0, 'Crop Trailer' : 1 +# TILLAGE 'Nothing' : 0, 'Seeds' : 1, 'Water': 2, 'Fertilizer': 3 +# IN BASE 'No' : 0, 'Yes' : 1 + + +dtree = DecisionTreeClassifier() +dtree = dtree.fit(X, y) +data = tree.export_graphviz(dtree, out_file=None, feature_names=features) +graph = pydotplus.graph_from_dot_data(data) +graph.write_png('mydecisiontree.png') + +img = pltimg.imread('mydecisiontree.png') +imgplot = plt.imshow(img) +plt.show() + +print(dtree.predict([[0, 1, 1, 3, 0]])) diff --git a/Tractor.py b/Tractor.py index 33d77f8..90cbf70 100644 --- a/Tractor.py +++ b/Tractor.py @@ -94,8 +94,7 @@ class Tractor: @direction.setter def direction(self, direction): - if direction == "UP" or direction == "DOWN" or direction == "RIGHT" or direction == "LEFT": - self.__direction = direction + self.__direction = direction def drive(self): @@ -111,3 +110,33 @@ class Tractor: elif self.__direction == "LEFT" and self.horizontal_index > 0: self.__horizontal_index += -mRange self.reduce_fuel() + + def left_rotation(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 right_rotation(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 auto_movement(self, move): + if move == "Move": + self.drive() + elif move == "Left_Rotation": + self.left_rotation() + elif move == "Right_Rotation": + self.right_rotation() + diff --git a/constants.py b/constants.py index 402d504..a933eca 100644 --- a/constants.py +++ b/constants.py @@ -29,8 +29,14 @@ TRACTOR_WIDTH = TILE_SIZE TRACTOR_HEIGHT = TILE_SIZE #FRAMES PER SECOND -FPS = 10 +FPS = 5 #ANIMATION_PART -ANIMATION_PART = 11 +ANIMATION_PART = 1 + + +TRACTOR_DIRECTION_RIGHT = 2 +TRACTOR_DIRECTION_UP = 1 +TRACTOR_DIRECTION_DOWN = 3 +TRACTOR_DIRECTION_LEFT = 4 diff --git a/createTreeData.py b/createTreeData.py new file mode 100644 index 0000000..232b588 --- /dev/null +++ b/createTreeData.py @@ -0,0 +1,101 @@ +from itertools import product +import numpy as np +import pandas as pd +import csv +import id3test +import pprint +import sys +import pandas +from sklearn import tree +import pydotplus +from sklearn.tree import DecisionTreeClassifier +import matplotlib.pyplot as plt +import matplotlib.image as pltimg + +# stan pola: toCut, toPlow, toWater, toSeed, toFertilize +# pora dnia: dzień, noc +# pogoda: sunny, cloudy, rainy, hail +# temperatura: freezing, cold, mild, hot +# wiatr: windless, strong wind, gale +# humidy: low, high + + +field_states = ['toPlow', 'toWater', 'toSeed', 'toFertilize', 'toCut'] +day_time = ['Day', 'Night'] +weather = ['Clear Sky', 'Cloudy', 'Rainy', 'Hail'] +temperature = ['Freezing', 'Cold', 'Mild', 'Hot'] +wind = ['Windless', 'Strong Wind', 'Gale'] +humidy = ['Low', 'High'] + +output = list(product(field_states, day_time, weather, temperature, wind, humidy)) + +dict = [] + +for x in range(len(output)): + while True: + mField = output[x][0] + mDay_time = output[x][1] + mWeather = output[x][2] + mTemperature = output[x][3] + mWind = output[x][4] + mHumidy = output[x][5] + mDecision = 'null' + + # pora dnia: dzień 2, noc -2 + # pogoda: sunny+3, cloudy+3, rainy-2, hail-5 + # temperatura: freezing -3, cold-1, mild+4, hot+2 + # wiatr: windless +2, strong wind-1, gale-3 + # humidy: low+2, high-3 + + if mDay_time == 'Day': + valDay_time = 2 + else: + valDay_time = -3 + + if mWeather == 'Sunny' or 'Cloudy': + valWeather = 3 + elif mWeather == 'Rainy': + valWeather = -2 + else: + valWeather = -5 + + if mTemperature == 'Freezing': + valTemperature = -3 + elif mTemperature == 'Cold': + valTemperature = -1 + elif mTemperature == 'Mild': + valTemperature = 4 + else: + valTemperature = 2 + + if mWind == 'Windless': + valWind = +2 + elif mWind == 'Strong Wind': + valWind = -1 + else: + valWind = -3 + + if humidy == 'Low': + valHumidy = 2 + else: + valHumidy = -2 + + result = valDay_time + valWeather + valTemperature + valWind + valHumidy + if result >= 0: + mDecision = "Make Action" + else: + mDecision = "Wait" + + break + + dict.append({'Field': mField, 'Day Time': mDay_time, 'Weather': mWeather, + 'Temperature': mTemperature, 'Wind': mWind, 'Humidy': mHumidy, 'Decision': mDecision}) + +fields = ['Field', 'Day Time', 'Weather', 'Temperature', 'Wind', 'Humidy', 'Decision'] + +filename = "treedata\\data3.csv" + +with open(filename, 'w') as csvfile: + writer = csv.DictWriter(csvfile, fieldnames=fields) + writer.writeheader() + writer.writerows(dict) diff --git a/main.py b/main.py index 3b14263..ae8232c 100644 --- a/main.py +++ b/main.py @@ -1,15 +1,15 @@ import pygame import Board +import FindPath import TractorAction import drawUI -from FindPath import graphsearch +import graph +from Testfile import dtree from Tractor import Tractor from TractorLoad import TillageUnit -from animations import animationsOn, animationsOff from constants import * from manualSteering import manualSteeringDriver -from queue import Queue pygame.init() @@ -27,11 +27,13 @@ toolCounter = - 1 board = Board.generate() -tractor = Tractor(horizontal_index=-0, vertical_index=0, hitch="nothing", header=False, autodrive=False, - direction='RIGHT') +tractor = Tractor(horizontal_index=-0, vertical_index=0, hitch="nothing", header=False, autodrive=True, + direction="RIGHT") + tillageUnit = TillageUnit("Nothing") tractor.turnOnEngine() +move_list = [] clock = pygame.time.Clock() @@ -45,23 +47,27 @@ while working: field = board[tractor.horizontal_index][tractor.vertical_index] - print("curr field cost", field.cost) - print("tractor dir", tractor.direction) - if tractor.autodrive and tractor.engineWorking: - animationSpeed = ANIMATION_PART - else: - animationSpeed = 1 - print(ANIMATION_PART) + # decision = dtree.predict([field_state, day_time, weather, temperature, wind, humidy]) == 1 + # weather, temperature, wind, humidy = Weather.check_weather() + decision = 'Make Action' - if tractor.autodrive: - tractor, tillageUnit, toolCounter = TractorAction.autoToolsChange(tractor, tillageUnit, toolCounter) + if not move_list and decision == 'Make Action': field.state = TractorAction.changeFieldState(field, tractor) + istate = graph.Istate(tractor.direction, tractor.horizontal_index, tractor.vertical_index) + move_list = graph.graphsearch([], [], istate, FindPath.nearestLookingField(board, tractor, TillageUnit), board) + print(move_list) + + elif move_list: + tractor.auto_movement(move_list.pop(0)) + #TractorAction.changeFieldState(field, tractor) + + if field.horizontal_index == 0 and field.vertical_index == 0 and not move_list: + tractor, tillageUnit, toolCounter = TractorAction.autoToolsChange(tractor, tillageUnit, toolCounter) drawUI.drawUI(board, display, tractor, tractor.direction, tillageUnit, field, animationSpeed) clock.tick(FPS) - #graphsearch(tractor, board, TillageUnit, Queue(), list()) pygame.quit() -quit() +quit() \ No newline at end of file diff --git a/manualSteering.py b/manualSteering.py index 6dde77e..e5942ca 100644 --- a/manualSteering.py +++ b/manualSteering.py @@ -51,13 +51,12 @@ def manualSteeringDriver(event, board, tractor, hitchCounter, tillageUnit, loadC def manualTurning(event, tractor): - tractor.direction = "STOP" if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT and tractor.horizontal_index > 0: - tractor.direction = "LEFT" + tractor.direction = TRACTOR_DIRECTION_LEFT elif event.key == pygame.K_RIGHT and tractor.horizontal_index < HORIZONTAL_TILES_NUMBER - 1: - tractor.direction = "RIGHT" + tractor.direction = TRACTOR_DIRECTION_RIGHT elif event.key == pygame.K_UP and tractor.vertical_index > 0: - tractor.direction = "UP" + tractor.direction = TRACTOR_DIRECTION_UP elif event.key == pygame.K_DOWN and tractor.vertical_index < VERTICAL_TILES_NUMBER - 1: - tractor.direction = "DOWN" + tractor.direction = TRACTOR_DIRECTION_DOWN