development #12

Merged
s452701 merged 9 commits from development into master 2021-06-21 17:12:29 +02:00
11 changed files with 50188 additions and 52 deletions
Showing only changes of commit 40f620b3ec - Show all commits

View File

@ -1,12 +1,12 @@
import pygame import pygame
from settings import SCREEN_WIDTH, SCREEN_HEIGHT
from survival.components.inventory_component import InventoryComponent from survival.components.inventory_component import InventoryComponent
from survival.game.game_map import GameMap from survival.game.game_map import GameMap
from survival.generators.building_generator import BuildingGenerator from survival.generators.building_generator import BuildingGenerator
from survival.generators.player_generator import PlayerGenerator from survival.generators.player_generator import PlayerGenerator
from survival.generators.resource_generator import ResourceGenerator from survival.generators.resource_generator import ResourceGenerator
from survival.generators.world_generator import WorldGenerator from survival.generators.world_generator import WorldGenerator
from survival.settings import SCREEN_WIDTH, SCREEN_HEIGHT
from survival.systems.draw_system import DrawSystem from survival.systems.draw_system import DrawSystem

View File

@ -1,48 +0,0 @@
import json
import os
from sklearn import tree
from sklearn.feature_extraction import DictVectorizer
from survival.components.resource_component import ResourceComponent
class DecisionTree:
def __init__(self):
self.clf = None
self.vec = None
def build(self, depth: int):
path = os.path.join("../..", "data.txt")
samples = list()
results = list()
with open(path, "r") as training_file:
for sample in training_file:
sample, result = self.process_input(sample)
samples.append(sample)
results.append(result)
self.vec = DictVectorizer()
self.clf = tree.DecisionTreeClassifier(max_depth=depth)
self.clf = self.clf.fit(self.vec.fit_transform(samples).toarray(), results)
# print(tree.export_text(self.clf, feature_names=self.vec.get_feature_names()))
def predict_answer(self, resource: ResourceComponent):
params = {
"weight": resource.weight,
"eatable": resource.eatable,
"toughness": resource.toughness
}
return self.clf.predict(self.vec.transform(params).toarray())
@staticmethod
def process_input(line):
data = json.loads(line.strip())
result = data['resource']
del data['resource']
sample = data
return sample, result

Binary file not shown.

View File

@ -0,0 +1,60 @@
import json
from joblib import dump, load
from matplotlib import pyplot as plt
from sklearn import tree
from sklearn.feature_extraction import DictVectorizer
class DecisionTree:
def __init__(self):
self.clf = None
self.vec = None
def build(self, depth: int):
path = "tree_data.json"
samples = []
results = []
with open(path, "r") as training_file:
for sample in training_file:
sample, result = self.process_input(sample)
samples.append(sample)
results.append(result)
self.vec = DictVectorizer()
self.clf = tree.DecisionTreeClassifier(max_depth=depth)
self.clf = self.clf.fit(self.vec.fit_transform(samples).toarray(), results)
def save_model(self, clf_file, vec_file):
dump(self.clf, clf_file)
dump(self.vec, vec_file)
def load_model(self, clf_file, vec_file):
self.clf = load(clf_file)
self.vec = load(vec_file)
def predict_answer(self, params):
return self.clf.predict(self.vec.transform(params).toarray())
def plot_tree(self):
print('Plotting tree...')
fig = plt.figure(figsize=(36, 27))
_ = tree.plot_tree(self.clf,
feature_names=self.vec.get_feature_names(),
filled=True)
fig.savefig("decistion_tree.png")
print('Success!')
@staticmethod
def process_input(line):
data = json.loads(line.strip())
result = data['result']
del data['result']
del data['food_result']
del data['water_result']
del data['wood_result']
sample = data
return sample, result

View File

@ -0,0 +1,124 @@
import random
from typing import Dict
from survival.ai.decision_tree.decision_tree import DecisionTree
from survival.generators.resource_type import ResourceType
class TreeDataGenerator:
INV_RANGE = (1, 100)
VISIBLE = (True, False)
DISTANCE_RANGE = (3, 7)
DISTANCE_FACTOR = 0.2
COUNT = (1, 2, 3)
def generate(self, count=1000):
full_data = []
self.process(count, full_data)
self.write_data_to_file(full_data)
return full_data
def process(self, count, full_data):
for i in range(count):
# if i % 10000 == 0:
# print(i)
package = {}
# Create resource data for each resource type.
for resource in ResourceType:
package[resource] = self.create_resource_data()
# Get the resource with highest result among all generated resource types.
best_resource = self.get_best_resource(package)
# Unpack packaged resources.
(food, water, wood) = (
package[ResourceType.FOOD], package[ResourceType.WATER], package[ResourceType.WOOD])
# Create dictionary filled with data.
data = {"food_inv": food[0], 'food_visible': str(food[1]), 'food_distance': food[2],
'food_count': food[3], 'food_result': food[4],
'water_inv': water[0], 'water_visible': str(water[1]), 'water_distance': water[2],
'water_count': water[3], 'water_result': water[4],
'wood_inv': wood[0], 'wood_visible': str(wood[1]), 'wood_distance': wood[2],
'wood_count': wood[3], 'wood_result': wood[4],
'result': best_resource.name.lower()}
full_data.append(data)
@staticmethod
def write_data_to_file(full_data):
print("Writing to file...")
# Open the target file to which the data will be saved and write all the data to it.
with open('tree_data.json', 'w') as f:
for data in full_data:
data_str = str(data).replace("'", '"').replace('"False"', 'false').replace('"True"', 'true')
f.write(data_str)
f.write('\n')
print("Success!")
def create_resource_data(self):
is_visible = random.choice(self.VISIBLE)
inventory = random.randint(min(self.INV_RANGE), max(self.INV_RANGE))
if is_visible:
cnt = random.choice(self.COUNT)
distance = random.randint(min(self.DISTANCE_RANGE), max(self.DISTANCE_RANGE))
else:
cnt = 0
distance = 0
# Equation determining the results processed by decision tree.
result = (self.INV_RANGE[1] / inventory) * (1 * cnt if is_visible else 0.9) + (
max(self.DISTANCE_RANGE) / distance if is_visible else 0.5) * self.DISTANCE_FACTOR
return [inventory, is_visible, distance, cnt, result]
@staticmethod
def get_best_resource(package: Dict) -> ResourceType:
best_resource = None
for resource, data in package.items():
if best_resource is None or data[:-1] < package[best_resource][:-1]:
best_resource = resource
return best_resource
@staticmethod
def print_data(full_data):
for data in full_data:
print(TreeDataGenerator.format_words(["Data", "Apple", "Water", "Wood"]))
print(TreeDataGenerator.format_words(["Inventory", data["food_inv"], data["water_inv"], data["wood_inv"]]))
print(TreeDataGenerator.format_words(
["Visible", data["food_visible"], data["water_visible"], data["wood_visible"]]))
print(TreeDataGenerator.format_words(
["Distance", data["food_distance"], data["water_distance"], data["wood_distance"]]))
print(
TreeDataGenerator.format_words(["Count", data["food_count"], data["water_count"], data["wood_count"]]))
print(TreeDataGenerator.format_words(
["Result", round(data["food_result"], 3), round(data["water_result"], 3),
round(data["wood_result"], 3)]))
print(f'Best resource: {data["result"]}')
print('--------------------------------------------------------------')
@staticmethod
def format_words(words):
return '{:>12} {:>12} {:>12} {:>12}'.format(words[0], words[1], words[2], words[3])
# Train tree
generator = TreeDataGenerator()
data = generator.generate(50000)
generator.print_data(data)
tree = DecisionTree()
tree.build(1000)
tree.plot_tree()
tree.save_model('classifier.joblib', 'vectorizer.joblib')
# ----------------------------------------------------------- #
# Use trained tree
# tree = DecisionTree()
# tree.load_model('classifier.joblib', 'vectorizer.joblib')
#
# answ = tree.predict_answer({'food_inv': 40, 'water_inv': 10, 'wood_inv': 20,
# 'food_distance': 2, 'water_distance': -1, 'wood_distance': 4,
# 'food_visible': True, 'water_visible': False, 'wood_visible': True,
# 'food_count': 1, 'water_count': 1, 'wood_count': 1})
# print(answ)

Binary file not shown.

After

Width:  |  Height:  |  Size: 722 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -1,6 +1,6 @@
from pygame.rect import Rect from pygame.rect import Rect
from survival import SCREEN_WIDTH, SCREEN_HEIGHT from survival.settings import SCREEN_WIDTH, SCREEN_HEIGHT
class Camera: class Camera:

View File

@ -1,4 +1,4 @@
from survival import esper, PlayerGenerator, ResourceGenerator, SCREEN_WIDTH, SCREEN_HEIGHT from survival import esper, ResourceGenerator, PlayerGenerator
from survival.components.consumption_component import ConsumptionComponent from survival.components.consumption_component import ConsumptionComponent
from survival.components.direction_component import DirectionChangeComponent from survival.components.direction_component import DirectionChangeComponent
from survival.components.inventory_component import InventoryComponent from survival.components.inventory_component import InventoryComponent
@ -12,7 +12,7 @@ from survival.esper import World
from survival.game.camera import Camera from survival.game.camera import Camera
from survival.game.game_map import GameMap from survival.game.game_map import GameMap
from survival.generators.resource_type import ResourceType from survival.generators.resource_type import ResourceType
from survival.settings import PLAYER_START_POSITION, STARTING_RESOURCES_AMOUNT from survival.settings import PLAYER_START_POSITION, STARTING_RESOURCES_AMOUNT, SCREEN_WIDTH, SCREEN_HEIGHT
from survival.systems.automation_system import AutomationSystem from survival.systems.automation_system import AutomationSystem
from survival.systems.camera_system import CameraSystem from survival.systems.camera_system import CameraSystem
from survival.systems.collision_system import CollisionSystem from survival.systems.collision_system import CollisionSystem