diff --git a/data/AI_data/dt_exmpls/dt_examples b/data/AI_data/dt_exmpls/dt_examples index 7f3d7d1..8da439b 100644 --- a/data/AI_data/dt_exmpls/dt_examples +++ b/data/AI_data/dt_exmpls/dt_examples @@ -1,44 +1,5 @@ -WATER|ZERO_TO_QUARTER|HALF_TO_THREE_QUARTERS|ZERO_TO_QUARTER|GE_3_LT_8|LT_3|GE_3_LT_8 -FOOD|ZERO_TO_QUARTER|QUARTER_TO_HALF|THREE_QUARTERS_TO_FULL|GE_15|GE_8_LT_15|GE_15 -WATER|ZERO_TO_QUARTER|QUARTER_TO_HALF|QUARTER_TO_HALF|LT_3|GE_3_LT_8|GE_15 -FOOD|HALF_TO_THREE_QUARTERS|ZERO_TO_QUARTER|QUARTER_TO_HALF|LT_3|LT_3|GE_8_LT_15 -WATER|QUARTER_TO_HALF|THREE_QUARTERS_TO_FULL|QUARTER_TO_HALF|GE_8_LT_15|LT_3|GE_15 -FOOD|HALF_TO_THREE_QUARTERS|QUARTER_TO_HALF|ZERO_TO_QUARTER|GE_8_LT_15|GE_8_LT_15|LT_3 -FOOD|HALF_TO_THREE_QUARTERS|QUARTER_TO_HALF|HALF_TO_THREE_QUARTERS|GE_8_LT_15|GE_3_LT_8|GE_15 -FOOD|THREE_QUARTERS_TO_FULL|QUARTER_TO_HALF|THREE_QUARTERS_TO_FULL|GE_3_LT_8|GE_15|GE_8_LT_15 -REST|ZERO_TO_QUARTER|ZERO_TO_QUARTER|QUARTER_TO_HALF|GE_15|GE_8_LT_15|GE_8_LT_15 -WATER|ZERO_TO_QUARTER|THREE_QUARTERS_TO_FULL|THREE_QUARTERS_TO_FULL|GE_8_LT_15|GE_3_LT_8|LT_3 -FOOD|HALF_TO_THREE_QUARTERS|QUARTER_TO_HALF|THREE_QUARTERS_TO_FULL|GE_15|GE_8_LT_15|GE_8_LT_15 -WATER|HALF_TO_THREE_QUARTERS|QUARTER_TO_HALF|QUARTER_TO_HALF|GE_8_LT_15|LT_3|GE_15 -WATER|ZERO_TO_QUARTER|QUARTER_TO_HALF|THREE_QUARTERS_TO_FULL|GE_15|GE_8_LT_15|GE_3_LT_8 -FOOD|THREE_QUARTERS_TO_FULL|QUARTER_TO_HALF|QUARTER_TO_HALF|LT_3|GE_8_LT_15|LT_3 -FOOD|HALF_TO_THREE_QUARTERS|QUARTER_TO_HALF|HALF_TO_THREE_QUARTERS|GE_15|GE_3_LT_8|GE_8_LT_15 -FOOD|THREE_QUARTERS_TO_FULL|HALF_TO_THREE_QUARTERS|QUARTER_TO_HALF|LT_3|GE_3_LT_8|GE_3_LT_8 -FOOD|THREE_QUARTERS_TO_FULL|THREE_QUARTERS_TO_FULL|ZERO_TO_QUARTER|GE_15|GE_15|LT_3 -FOOD|THREE_QUARTERS_TO_FULL|ZERO_TO_QUARTER|QUARTER_TO_HALF|GE_15|GE_3_LT_8|GE_3_LT_8 -WATER|QUARTER_TO_HALF|HALF_TO_THREE_QUARTERS|HALF_TO_THREE_QUARTERS|GE_8_LT_15|GE_3_LT_8|GE_3_LT_8 -WATER|ZERO_TO_QUARTER|ZERO_TO_QUARTER|THREE_QUARTERS_TO_FULL|LT_3|GE_15|LT_3 -FOOD|HALF_TO_THREE_QUARTERS|HALF_TO_THREE_QUARTERS|QUARTER_TO_HALF|LT_3|GE_8_LT_15|GE_15 -FOOD|THREE_QUARTERS_TO_FULL|ZERO_TO_QUARTER|HALF_TO_THREE_QUARTERS|GE_3_LT_8|LT_3|LT_3 -WATER|QUARTER_TO_HALF|HALF_TO_THREE_QUARTERS|HALF_TO_THREE_QUARTERS|GE_3_LT_8|GE_3_LT_8|GE_3_LT_8 -FOOD|HALF_TO_THREE_QUARTERS|ZERO_TO_QUARTER|ZERO_TO_QUARTER|GE_8_LT_15|GE_8_LT_15|GE_15 -WATER|QUARTER_TO_HALF|HALF_TO_THREE_QUARTERS|HALF_TO_THREE_QUARTERS|GE_15|GE_3_LT_8|GE_3_LT_8 -FOOD|THREE_QUARTERS_TO_FULL|QUARTER_TO_HALF|THREE_QUARTERS_TO_FULL|GE_15|GE_8_LT_15|GE_3_LT_8 -WATER|QUARTER_TO_HALF|THREE_QUARTERS_TO_FULL|QUARTER_TO_HALF|LT_3|GE_8_LT_15|GE_3_LT_8 -REST|QUARTER_TO_HALF|ZERO_TO_QUARTER|QUARTER_TO_HALF|GE_15|GE_15|GE_15 -FOOD|THREE_QUARTERS_TO_FULL|ZERO_TO_QUARTER|THREE_QUARTERS_TO_FULL|GE_15|GE_8_LT_15|GE_8_LT_15 -REST|HALF_TO_THREE_QUARTERS|HALF_TO_THREE_QUARTERS|ZERO_TO_QUARTER|GE_8_LT_15|GE_8_LT_15|GE_3_LT_8 -FOOD|HALF_TO_THREE_QUARTERS|ZERO_TO_QUARTER|ZERO_TO_QUARTER|GE_8_LT_15|GE_8_LT_15|GE_8_LT_15 -REST|ZERO_TO_QUARTER|ZERO_TO_QUARTER|QUARTER_TO_HALF|GE_3_LT_8|GE_15|GE_15 -FOOD|THREE_QUARTERS_TO_FULL|ZERO_TO_QUARTER|QUARTER_TO_HALF|GE_3_LT_8|LT_3|GE_15 -FOOD|THREE_QUARTERS_TO_FULL|HALF_TO_THREE_QUARTERS|ZERO_TO_QUARTER|GE_15|GE_15|GE_3_LT_8 -FOOD|THREE_QUARTERS_TO_FULL|ZERO_TO_QUARTER|ZERO_TO_QUARTER|GE_8_LT_15|GE_3_LT_8|GE_15 -WATER|QUARTER_TO_HALF|HALF_TO_THREE_QUARTERS|QUARTER_TO_HALF|GE_3_LT_8|GE_15|GE_15 -FOOD|ZERO_TO_QUARTER|ZERO_TO_QUARTER|THREE_QUARTERS_TO_FULL|GE_8_LT_15|LT_3|LT_3 -WATER|THREE_QUARTERS_TO_FULL|THREE_QUARTERS_TO_FULL|HALF_TO_THREE_QUARTERS|GE_3_LT_8|GE_3_LT_8|GE_3_LT_8 -FOOD|THREE_QUARTERS_TO_FULL|QUARTER_TO_HALF|THREE_QUARTERS_TO_FULL|GE_15|LT_3|GE_8_LT_15 -WATER|ZERO_TO_QUARTER|HALF_TO_THREE_QUARTERS|HALF_TO_THREE_QUARTERS|GE_3_LT_8|GE_3_LT_8|GE_15 -WATER|QUARTER_TO_HALF|THREE_QUARTERS_TO_FULL|ZERO_TO_QUARTER|GE_8_LT_15|GE_3_LT_8|GE_15 -WATER|ZERO_TO_QUARTER|QUARTER_TO_HALF|QUARTER_TO_HALF|GE_15|GE_3_LT_8|LT_3 -WATER|ZERO_TO_QUARTER|QUARTER_TO_HALF|HALF_TO_THREE_QUARTERS|GE_3_LT_8|GE_15|GE_3_LT_8 -FOOD|HALF_TO_THREE_QUARTERS|ZERO_TO_QUARTER|QUARTER_TO_HALF|GE_15|LT_3|LT_3 +WATER|ZERO_TO_QUARTER|HALF_TO_THREE_QUARTERS|QUARTER_TO_HALF|GE_3_LT_8|LT_3|GE_15|GE_15 +WATER|THREE_QUARTERS_TO_FULL|THREE_QUARTERS_TO_FULL|QUARTER_TO_HALF|GE_3_LT_8|GE_8_LT_15|GE_8_LT_15|LT_3 +FOOD|HALF_TO_THREE_QUARTERS|THREE_QUARTERS_TO_FULL|QUARTER_TO_HALF|LT_3|GE_15|GE_15|GE_3_LT_8 +WATER|HALF_TO_THREE_QUARTERS|HALF_TO_THREE_QUARTERS|THREE_QUARTERS_TO_FULL|GE_15|LT_3|GE_15|GE_15 +WATER|QUARTER_TO_HALF|HALF_TO_THREE_QUARTERS|ZERO_TO_QUARTER|GE_15|GE_15|GE_8_LT_15|GE_3_LT_8 diff --git a/src/AI/DecisionTrees/ExamplesManager.py b/src/AI/DecisionTrees/ExamplesManager.py index 824a881..328e519 100644 --- a/src/AI/DecisionTrees/ExamplesManager.py +++ b/src/AI/DecisionTrees/ExamplesManager.py @@ -3,6 +3,7 @@ from typing import Any, Union, List from src.AI.DecisionTrees.projectSpecificClasses.DistFromObject import DistFromObject from src.AI.DecisionTrees.projectSpecificClasses.PlayerStatsValue import PlayerStatsValue +from src.AI.DecisionTrees.projectSpecificClasses.SurvivalAttributesDefinitions import SurvivalAttributesDefinitions from src.AI.DecisionTrees.projectSpecificClasses.SurvivalClassification import SurvivalClassification from src.AI.DecisionTrees.projectSpecificClasses.SurvivalDTExample import SurvivalDTExample @@ -32,7 +33,7 @@ class ExamplesManager: line = line.rstrip('\n') words = line.split("|") - if len(words) != 7: + if len(words) != SurvivalAttributesDefinitions.attrsDefinitionsCount + 1: print("Not sufficient amount of words in line {}.".format(str(lineNum))) continue @@ -113,13 +114,25 @@ class ExamplesManager: print("Distance from rest place not parsed at line {}.".format(str(lineNum))) continue + # Distance from water after food + parseSuccess = False + dstFromWaterAfterFood: DistFromObject + for dstFromWaterAfterFood in DistFromObject: + if dstFromWaterAfterFood.name == words[7]: + parseSuccess = True + break + if not parseSuccess: + print("Distance from water after food not parsed at line {}.".format(str(lineNum))) + continue + example = SurvivalDTExample(classification, hungerAmount, thirstAmount, staminaAmount, dstFromFood, dstFromWater, - dstFromRest) + dstFromRest, + dstFromWaterAfterFood) examples.append(example) file.close() @@ -136,13 +149,14 @@ class ExamplesManager: example: SurvivalDTExample for example in examplesToAdd: - strToWrite = "{}|{}|{}|{}|{}|{}|{}\n".format(example.classification.name, - example.hungerVal.name, - example.thirstVal.name, - example.staminaVal.name, - example.distFromFood.name, - example.distFromWater.name, - example.distFromRestPlace.name) + strToWrite = "{}|{}|{}|{}|{}|{}|{}|{}\n".format(example.classification.name, + example.hungerVal.name, + example.thirstVal.name, + example.staminaVal.name, + example.distFromFood.name, + example.distFromWater.name, + example.distFromRestPlace.name, + example.dstFromWaterAfterFood.name) file.write(strToWrite) file.close() @@ -170,6 +184,7 @@ class ExamplesManager: random.choice(statsValues), random.choice(distances), random.choice(distances), + random.choice(distances), random.choice(distances)) # check if made example is not a duplicate diff --git a/src/AI/DecisionTrees/projectSpecificClasses/SurvivalAttributesDefinitions.py b/src/AI/DecisionTrees/projectSpecificClasses/SurvivalAttributesDefinitions.py index c641896..57da5a5 100644 --- a/src/AI/DecisionTrees/projectSpecificClasses/SurvivalAttributesDefinitions.py +++ b/src/AI/DecisionTrees/projectSpecificClasses/SurvivalAttributesDefinitions.py @@ -11,7 +11,7 @@ class SurvivalAttributesDefinitions: There are definitions of attributes like hunger, thirst, etc... """ - attrsDefinitionsCount = 6 + attrsDefinitionsCount = 7 hungerAttrDef = AttributeDefinition(0, "Hunger", [PlayerStatsValue.ZERO_TO_QUARTER, PlayerStatsValue.QUARTER_TO_HALF, @@ -33,12 +33,19 @@ class SurvivalAttributesDefinitions: DistFromObject.GE_15]) waterDistanceAttrDef = AttributeDefinition(4, "Distance from water", - [DistFromObject.LT_3, DistFromObject.GE_3_LT_8, DistFromObject.GE_8_LT_15, + [DistFromObject.LT_3, DistFromObject.GE_3_LT_8, + DistFromObject.GE_8_LT_15, DistFromObject.GE_15]) restDistanceAttrDef = AttributeDefinition(5, "Distance from rest place", [DistFromObject.LT_3, DistFromObject.GE_3_LT_8, DistFromObject.GE_8_LT_15, DistFromObject.GE_15]) + dstFromWaterAfterFood = AttributeDefinition(6, "Distance from water after food", + [DistFromObject.LT_3, DistFromObject.GE_3_LT_8, + DistFromObject.GE_8_LT_15, + DistFromObject.GE_15]) + allAttributesDefinitions = [hungerAttrDef, thirstAttrDef, staminaAttrDef, - foodDistanceAttrDef, waterDistanceAttrDef, restDistanceAttrDef] + foodDistanceAttrDef, waterDistanceAttrDef, restDistanceAttrDef, + dstFromWaterAfterFood] diff --git a/src/AI/DecisionTrees/projectSpecificClasses/SurvivalDTExample.py b/src/AI/DecisionTrees/projectSpecificClasses/SurvivalDTExample.py index d1b704c..698e70d 100644 --- a/src/AI/DecisionTrees/projectSpecificClasses/SurvivalDTExample.py +++ b/src/AI/DecisionTrees/projectSpecificClasses/SurvivalDTExample.py @@ -20,7 +20,8 @@ class SurvivalDTExample(DecisionTreeExample): def __init__(self, classification: SurvivalClassification, hungerVal: PlayerStatsValue, thirstVal: PlayerStatsValue, staminaVal: PlayerStatsValue, distFromFood: DistFromObject, distFromWater: DistFromObject, - distFromRestPlace: DistFromObject): + distFromRestPlace: DistFromObject, dstFromWaterAfterFood: DistFromObject): + self.dstFromWaterAfterFood = dstFromWaterAfterFood self.hungerVal = hungerVal self.thirstVal = thirstVal self.staminaVal = staminaVal @@ -33,7 +34,8 @@ class SurvivalDTExample(DecisionTreeExample): Attribute(SurvivalAttributesDefinitions.staminaAttrDef, staminaVal), Attribute(SurvivalAttributesDefinitions.foodDistanceAttrDef, distFromFood), Attribute(SurvivalAttributesDefinitions.waterDistanceAttrDef, distFromWater), - Attribute(SurvivalAttributesDefinitions.restDistanceAttrDef, distFromRestPlace)] + Attribute(SurvivalAttributesDefinitions.restDistanceAttrDef, distFromRestPlace), + Attribute(SurvivalAttributesDefinitions.dstFromWaterAfterFood, dstFromWaterAfterFood)] super().__init__(classification, attributes) @@ -58,6 +60,8 @@ class SurvivalDTExample(DecisionTreeExample): attrsAreEqual = False elif self.distFromRestPlace != anotherExample.distFromRestPlace: attrsAreEqual = False + elif self.dstFromWaterAfterFood != anotherExample.dstFromWaterAfterFood: + attrsAreEqual = False return attrsAreEqual @@ -69,5 +73,6 @@ class SurvivalDTExample(DecisionTreeExample): dsc += "\nDistance from food: {}".format(self.distFromFood.name) dsc += "\nDistance from water: {}".format(self.distFromWater.name) dsc += "\nDistance from rest place: {}".format(self.distFromRestPlace.name) + dsc += "\nDistance from water after food: {}".format(self.dstFromWaterAfterFood.name) return dsc diff --git a/src/AI/SurvivalDT.py b/src/AI/SurvivalDT.py index 0c42133..36de565 100644 --- a/src/AI/SurvivalDT.py +++ b/src/AI/SurvivalDT.py @@ -54,12 +54,11 @@ class SurvivalDT: dtRestPlaces.sort(key=lambda x: x.accurateDistanceFromPlayer) nearestDtRest = dtRestPlaces[0] - - currentSituation = SurvivalDTExample(None, playerStats.hungerAmount, playerStats.thirstAmount, playerStats.staminaAmount, nearestDtFood.dtDistanceFromPlayer, nearestDtWater.dtDistanceFromPlayer, - nearestDtRest.dtDistanceFromPlayer) + nearestDtRest.dtDistanceFromPlayer, + nearestDtFood.getDtDistanceFromOtherInteractable(nearestDtWater.interactable)) treeDecision, choice = self.__pickEntityAfterTreeDecision__(currentSituation, dtFoods, @@ -70,15 +69,19 @@ class SurvivalDT: if choice == map.getEntityOnCoord(player.getFacingCoord()): if treeDecision == SurvivalClassification.FOOD: dtFoods.remove(dtFoods[0]) + nearestDtFood = dtFoods[0] elif treeDecision == SurvivalClassification.WATER: dtWaters.remove(dtWaters[0]) + nearestDtWater = dtWaters[0] elif treeDecision == SurvivalClassification.REST: dtRestPlaces.remove(dtRestPlaces[0]) + nearestDtRest = dtRestPlaces[0] currentSituation = SurvivalDTExample(None, playerStats.hungerAmount, playerStats.thirstAmount, playerStats.staminaAmount, dtFoods[0].dtDistanceFromPlayer, dtWaters[0].dtDistanceFromPlayer, - dtRestPlaces[0].dtDistanceFromPlayer) + dtRestPlaces[0].dtDistanceFromPlayer, + nearestDtFood.getDtDistanceFromOtherInteractable(nearestDtWater.interactable)) treeDecision, choice = self.__pickEntityAfterTreeDecision__(currentSituation, dtFoods, dtRestPlaces, dtWaters)