development #12
@ -1,12 +1,12 @@
|
||||
import pygame
|
||||
|
||||
from settings import SCREEN_WIDTH, SCREEN_HEIGHT
|
||||
from survival.components.inventory_component import InventoryComponent
|
||||
from survival.game.game_map import GameMap
|
||||
from survival.generators.building_generator import BuildingGenerator
|
||||
from survival.generators.player_generator import PlayerGenerator
|
||||
from survival.generators.resource_generator import ResourceGenerator
|
||||
from survival.generators.world_generator import WorldGenerator
|
||||
from survival.settings import SCREEN_WIDTH, SCREEN_HEIGHT
|
||||
from survival.systems.draw_system import DrawSystem
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
BIN
survival/ai/decision_tree/classifier.joblib
Normal file
BIN
survival/ai/decision_tree/classifier.joblib
Normal file
Binary file not shown.
60
survival/ai/decision_tree/decision_tree.py
Normal file
60
survival/ai/decision_tree/decision_tree.py
Normal 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
|
124
survival/ai/decision_tree/decision_tree_data.py
Normal file
124
survival/ai/decision_tree/decision_tree_data.py
Normal 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)
|
BIN
survival/ai/decision_tree/decistion_tree.png
Normal file
BIN
survival/ai/decision_tree/decistion_tree.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 722 KiB |
50000
survival/ai/decision_tree/tree_data.json
Normal file
50000
survival/ai/decision_tree/tree_data.json
Normal file
File diff suppressed because it is too large
Load Diff
BIN
survival/ai/decision_tree/vectorizer.joblib
Normal file
BIN
survival/ai/decision_tree/vectorizer.joblib
Normal file
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
from pygame.rect import Rect
|
||||
|
||||
from survival import SCREEN_WIDTH, SCREEN_HEIGHT
|
||||
from survival.settings import SCREEN_WIDTH, SCREEN_HEIGHT
|
||||
|
||||
|
||||
class Camera:
|
||||
|
@ -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.direction_component import DirectionChangeComponent
|
||||
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.game_map import GameMap
|
||||
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.camera_system import CameraSystem
|
||||
from survival.systems.collision_system import CollisionSystem
|
||||
|
Loading…
Reference in New Issue
Block a user