Merge branch 'master' into genetic_algorithm
3
.gitignore
vendored
@ -145,3 +145,6 @@ cython_debug/
|
|||||||
|
|
||||||
# local sandbox
|
# local sandbox
|
||||||
sandbox/
|
sandbox/
|
||||||
|
/algorithms/learn/decision_tree/decistion_tree.png
|
||||||
|
/resources/data/neural_network/specificity/train
|
||||||
|
/resources/data/neural_network/series/train/
|
BIN
algorithms/learn/decision_tree/decision_tree.joblib
Normal file
@ -1,24 +1,25 @@
|
|||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
from matplotlib import pyplot
|
|
||||||
from joblib import dump, load
|
from joblib import dump, load
|
||||||
from sklearn import tree
|
from sklearn import tree
|
||||||
from sklearn.feature_extraction import DictVectorizer
|
from sklearn.feature_extraction import DictVectorizer
|
||||||
|
|
||||||
from objects.mines.disarming.mine_parameters import MineParameters
|
from disarming.parameters.mine_parameters import MineParameters
|
||||||
from objects.mines.disarming.parameter_json import generate_data
|
from disarming.parameters.parameter_json import generate_data
|
||||||
|
|
||||||
|
|
||||||
class DecisionTree:
|
class DecisionTree:
|
||||||
def __init__(self, clf_source: str = None, vec_source: str = None):
|
def __init__(self, load_from_file: bool = False):
|
||||||
if clf_source is not None and vec_source is not None:
|
if load_from_file:
|
||||||
|
clf_source = r"algorithms/learn/decision_tree/decision_tree.joblib"
|
||||||
|
vec_source = r"algorithms/learn/decision_tree/dict_vectorizer.joblib"
|
||||||
self.load(clf_source, vec_source)
|
self.load(clf_source, vec_source)
|
||||||
else:
|
else:
|
||||||
self.clf = None
|
self.clf = None
|
||||||
self.vec = None
|
self.vec = None
|
||||||
|
|
||||||
def build(self, training_file: str, depth: int):
|
def build(self, training_file: str, depth: int):
|
||||||
path = os.path.join("..", "..", "resources", "data", training_file)
|
path = os.path.join("../..", "..", "resources", "data", "decision_tree", training_file)
|
||||||
|
|
||||||
samples = list()
|
samples = list()
|
||||||
results = list()
|
results = list()
|
||||||
@ -40,12 +41,12 @@ class DecisionTree:
|
|||||||
print(tree.export_text(self.clf, feature_names=self.vec.get_feature_names()))
|
print(tree.export_text(self.clf, feature_names=self.vec.get_feature_names()))
|
||||||
|
|
||||||
# plot a tree (not necessary)
|
# plot a tree (not necessary)
|
||||||
fig = pyplot.figure(figsize=(50, 40))
|
# fig = pyplot.figure(figsize=(50, 40))
|
||||||
_ = tree.plot_tree(self.clf,
|
# _ = tree.plot_tree(self.clf,
|
||||||
feature_names=self.vec.get_feature_names(),
|
# feature_names=self.vec.get_feature_names(),
|
||||||
class_names=self.clf.classes_,
|
# class_names=self.clf.classes_,
|
||||||
filled=True)
|
# filled=True)
|
||||||
fig.savefig("decistion_tree.png")
|
# fig.savefig("decistion_tree.png")
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
dump(self.clf, 'decision_tree.joblib')
|
dump(self.clf, 'decision_tree.joblib')
|
||||||
@ -84,8 +85,8 @@ class DecisionTree:
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# generate_data("training_set.txt", 12000)
|
generate_data("training_set.txt", 4500)
|
||||||
decision_tree = DecisionTree()
|
decision_tree = DecisionTree()
|
||||||
decision_tree.build("training_set.txt", 15)
|
decision_tree.build("training_set.txt", 15)
|
||||||
decision_tree.test()
|
decision_tree.test()
|
||||||
# decision_tree.save()
|
decision_tree.save()
|
BIN
algorithms/learn/decision_tree/dict_vectorizer.joblib
Normal file
135
algorithms/learn/neural_network/neural_network.py
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
import numpy as np
|
||||||
|
import joblib
|
||||||
|
import pathlib
|
||||||
|
import tensorflow as tf
|
||||||
|
|
||||||
|
from enum import Enum
|
||||||
|
from tensorflow import keras
|
||||||
|
from tensorflow.keras import layers
|
||||||
|
from tensorflow.keras.models import Sequential
|
||||||
|
|
||||||
|
|
||||||
|
# int value is a number of classes
|
||||||
|
class NNType(Enum):
|
||||||
|
SERIES = "series", 4,
|
||||||
|
SPECIFICITY = "specificity", 3
|
||||||
|
|
||||||
|
|
||||||
|
class NeuralNetwork:
|
||||||
|
def __init__(self, network_type: NNType, load_from_file: bool = False, img_height=180, img_width=180):
|
||||||
|
self.type = network_type
|
||||||
|
self.training_data_dir = pathlib.Path(fr"../../../resources/data/neural_network/{self.type.value[0]}/train")
|
||||||
|
|
||||||
|
self.img_height = img_height
|
||||||
|
self.img_width = img_width
|
||||||
|
|
||||||
|
if load_from_file:
|
||||||
|
saved_model_path = fr"algorithms/learn/neural_network/{self.type.value[0]}/saved_model.h5"
|
||||||
|
classes_path = fr"algorithms/learn/neural_network/{self.type.value[0]}/saved_model_classes.joblib"
|
||||||
|
self.load(saved_model_path, classes_path)
|
||||||
|
else:
|
||||||
|
self.model = None
|
||||||
|
self.class_names = None
|
||||||
|
|
||||||
|
def build(self, epochs=15, batch_size=32):
|
||||||
|
num_classes = self.type.value[1]
|
||||||
|
|
||||||
|
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
|
||||||
|
self.training_data_dir,
|
||||||
|
validation_split=0.2,
|
||||||
|
subset="training",
|
||||||
|
seed=123,
|
||||||
|
image_size=(self.img_height, self.img_width),
|
||||||
|
batch_size=batch_size)
|
||||||
|
|
||||||
|
self.class_names = train_ds.class_names
|
||||||
|
|
||||||
|
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
|
||||||
|
self.training_data_dir,
|
||||||
|
validation_split=0.2,
|
||||||
|
subset="validation",
|
||||||
|
seed=123,
|
||||||
|
image_size=(self.img_height, self.img_width),
|
||||||
|
batch_size=batch_size)
|
||||||
|
|
||||||
|
autotune = tf.data.AUTOTUNE
|
||||||
|
|
||||||
|
train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=autotune)
|
||||||
|
val_ds = val_ds.cache().prefetch(buffer_size=autotune)
|
||||||
|
|
||||||
|
data_augmentation = keras.Sequential(
|
||||||
|
[
|
||||||
|
layers.experimental.preprocessing.RandomFlip("horizontal",
|
||||||
|
input_shape=(self.img_height,
|
||||||
|
self.img_width,
|
||||||
|
3)),
|
||||||
|
layers.experimental.preprocessing.RandomRotation(0.1),
|
||||||
|
layers.experimental.preprocessing.RandomZoom(0.1),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
model = Sequential([
|
||||||
|
data_augmentation,
|
||||||
|
layers.experimental.preprocessing.Rescaling(1. / 255),
|
||||||
|
layers.Conv2D(16, 3, padding='same', activation='relu'),
|
||||||
|
layers.MaxPooling2D(),
|
||||||
|
layers.Conv2D(32, 3, padding='same', activation='relu'),
|
||||||
|
layers.MaxPooling2D(),
|
||||||
|
layers.Conv2D(64, 3, padding='same', activation='relu'),
|
||||||
|
layers.MaxPooling2D(),
|
||||||
|
layers.Dropout(0.2),
|
||||||
|
layers.Flatten(),
|
||||||
|
layers.Dense(128, activation='relu'),
|
||||||
|
layers.Dense(num_classes)
|
||||||
|
])
|
||||||
|
|
||||||
|
model.compile(optimizer='adam',
|
||||||
|
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
|
||||||
|
metrics=['accuracy'])
|
||||||
|
|
||||||
|
model.summary()
|
||||||
|
model.fit(
|
||||||
|
train_ds,
|
||||||
|
validation_data=val_ds,
|
||||||
|
epochs=epochs
|
||||||
|
)
|
||||||
|
|
||||||
|
self.model = model
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
self.model.save(fr"{self.type.value[0]}/saved_model.h5")
|
||||||
|
joblib.dump(self.class_names, fr"{self.type.value[0]}/saved_model_classes.joblib")
|
||||||
|
|
||||||
|
def load(self, model_path, classes_path):
|
||||||
|
self.model = tf.keras.models.load_model(model_path)
|
||||||
|
self.class_names = joblib.load(classes_path)
|
||||||
|
|
||||||
|
def get_answer(self, image_path):
|
||||||
|
img = keras.preprocessing.image.load_img(
|
||||||
|
image_path, target_size=(self.img_height, self.img_width)
|
||||||
|
)
|
||||||
|
|
||||||
|
img_array = keras.preprocessing.image.img_to_array(img)
|
||||||
|
img_array = tf.expand_dims(img_array, 0)
|
||||||
|
|
||||||
|
predictions = self.model.predict(img_array)
|
||||||
|
score = tf.nn.softmax(predictions[0])
|
||||||
|
|
||||||
|
# returns class, condifdence
|
||||||
|
return self.class_names[np.argmax(score)], 100 * np.max(score)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Building and saving a new model:
|
||||||
|
|
||||||
|
# (requires a valid training set in resources/data/neural_network/train)
|
||||||
|
# neural_network = NeuralNetwork(NNType.SERIES)
|
||||||
|
# neural_network.build(epochs=10)
|
||||||
|
# neural_network.save()
|
||||||
|
|
||||||
|
# Loading a model from file:
|
||||||
|
neural_network = NeuralNetwork(NNType.SPECIFICITY, load_from_file=True)
|
||||||
|
|
||||||
|
# Test
|
||||||
|
image = r"../../../resources/data/neural_network/specificity/disarm/tanks/1-35-British-Tank-FV-214-Conqueror-MK-II-Amusing-Hobby-35A027-AH-35A027_b_0.JPG"
|
||||||
|
neural_network.get_answer(image)
|
BIN
algorithms/learn/neural_network/series/saved_model.h5
Normal file
BIN
algorithms/learn/neural_network/specificity/saved_model.h5
Normal file
@ -3,9 +3,9 @@ import pygame
|
|||||||
import project_constants as const
|
import project_constants as const
|
||||||
from assets import asset_constants as asset
|
from assets import asset_constants as asset
|
||||||
|
|
||||||
from objects.mines.mine_models.standard_mine import StandardMine
|
from objects.mine_models.standard_mine import StandardMine
|
||||||
from objects.mines.mine_models.chained_mine import ChainedMine
|
from objects.mine_models.chained_mine import ChainedMine
|
||||||
from objects.mines.mine_models.time_mine import TimeMine
|
from objects.mine_models.time_mine import TimeMine
|
||||||
|
|
||||||
|
|
||||||
# ================================= #
|
# ================================= #
|
||||||
|
90
disarming/disarming_handler.py
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import os
|
||||||
|
import copy
|
||||||
|
import random
|
||||||
|
|
||||||
|
from disarming.parameters.hash_function import SeriesHash, SpecificityHash
|
||||||
|
from objects.mine_models.mine import Mine
|
||||||
|
from algorithms.learn.decision_tree.decision_tree import DecisionTree
|
||||||
|
from algorithms.learn.neural_network.neural_network import NNType, NeuralNetwork
|
||||||
|
|
||||||
|
SERIES_IMAGES_PATH = r"resources/data/neural_network/series/disarm"
|
||||||
|
SPECIFICITY_IMAGES_PATH = r"resources/data/neural_network/specificity/disarm"
|
||||||
|
|
||||||
|
class_to_series = \
|
||||||
|
{SeriesHash[name].value[2]: SeriesHash[name].value[1] for name, _ in SeriesHash.__members__.items()}
|
||||||
|
|
||||||
|
class_to_specificity = \
|
||||||
|
{SpecificityHash[name].value[2]: SpecificityHash[name].value[1] for name, _ in SpecificityHash.__members__.items()}
|
||||||
|
|
||||||
|
|
||||||
|
class DisarmingHandler:
|
||||||
|
def __init__(self, mine: Mine):
|
||||||
|
self.mine = mine
|
||||||
|
self.mine_params = dict()
|
||||||
|
|
||||||
|
self.series_img = None
|
||||||
|
self.specificity_img = None
|
||||||
|
|
||||||
|
self.recognized_series = None
|
||||||
|
self.recognized_specificity = None
|
||||||
|
|
||||||
|
self.correct_wire = None
|
||||||
|
self.chosen_wire = None
|
||||||
|
|
||||||
|
self._set_mine_params()
|
||||||
|
self._set_correct_wire()
|
||||||
|
|
||||||
|
def _set_mine_params(self):
|
||||||
|
self.mine_params = self.mine.investigate()
|
||||||
|
|
||||||
|
def _set_correct_wire(self):
|
||||||
|
self.correct_wire = self.mine.wire
|
||||||
|
|
||||||
|
def get_mine_params(self):
|
||||||
|
return [self.mine_params["mine_type"], self.mine_params["weight"], self.mine_params["danger_cls"],
|
||||||
|
self.mine_params["indicator"], self.mine_params["series"], self.mine_params["specificity"]]
|
||||||
|
|
||||||
|
def pick_series_image(self):
|
||||||
|
series_class = SeriesHash[self.mine_params["series"].upper().replace(" ", "_")].value[2]
|
||||||
|
imgs_dir = os.path.join(SERIES_IMAGES_PATH, series_class)
|
||||||
|
|
||||||
|
self.series_img = os.path.join(
|
||||||
|
imgs_dir, random.choice([x for x in os.listdir(imgs_dir) if os.path.isfile(os.path.join(imgs_dir, x))]))
|
||||||
|
return self.series_img
|
||||||
|
|
||||||
|
def pick_specificity_image(self):
|
||||||
|
specificity_class = SpecificityHash[self.mine_params["specificity"].upper().replace(" ", "_")].value[2]
|
||||||
|
|
||||||
|
imgs_dir = os.path.join(SPECIFICITY_IMAGES_PATH, specificity_class)
|
||||||
|
|
||||||
|
self.specificity_img = os.path.join(
|
||||||
|
imgs_dir, random.choice([x for x in os.listdir(imgs_dir) if os.path.isfile(os.path.join(imgs_dir, x))]))
|
||||||
|
|
||||||
|
return self.specificity_img
|
||||||
|
|
||||||
|
def recognize_series(self):
|
||||||
|
nn = NeuralNetwork(NNType.SERIES, load_from_file=True)
|
||||||
|
answer, confidence = nn.get_answer(self.series_img)
|
||||||
|
self.recognized_series = class_to_series[answer]
|
||||||
|
|
||||||
|
return self.recognized_series, self.mine_params["series"] == self.recognized_series
|
||||||
|
|
||||||
|
def recognize_specificity(self):
|
||||||
|
nn = NeuralNetwork(NNType.SPECIFICITY, load_from_file=True)
|
||||||
|
answer, confidence = nn.get_answer(self.specificity_img)
|
||||||
|
self.recognized_specificity = class_to_specificity[answer]
|
||||||
|
|
||||||
|
return self.recognized_specificity, self.mine_params["specificity"] == self.recognized_specificity
|
||||||
|
|
||||||
|
def choose_wire(self):
|
||||||
|
dt = DecisionTree(load_from_file=True)
|
||||||
|
agent_params = copy.deepcopy(self.mine_params)
|
||||||
|
agent_params["series"] = self.recognized_series
|
||||||
|
agent_params["specificity"] = self.recognized_specificity
|
||||||
|
|
||||||
|
self.chosen_wire = dt.get_answer(agent_params)[0]
|
||||||
|
|
||||||
|
return self.chosen_wire
|
||||||
|
|
||||||
|
def defuse(self):
|
||||||
|
return self.mine.disarm(self.chosen_wire)
|
@ -5,6 +5,9 @@ class Wire(Enum):
|
|||||||
BLUE = 1, "blue"
|
BLUE = 1, "blue"
|
||||||
GREEN = 2, "green"
|
GREEN = 2, "green"
|
||||||
RED = 3, "red"
|
RED = 3, "red"
|
||||||
|
YELLOW = 4, "yellow"
|
||||||
|
WHITE = 5, "white"
|
||||||
|
PURPLE = 6, "purple"
|
||||||
|
|
||||||
|
|
||||||
class TypeHash(Enum):
|
class TypeHash(Enum):
|
||||||
@ -23,14 +26,10 @@ class DangerClassHash(Enum):
|
|||||||
|
|
||||||
|
|
||||||
class SeriesHash(Enum):
|
class SeriesHash(Enum):
|
||||||
TCH_2990TONER = 128, "TCH 2990toner"
|
TCH_2990TONER = 220, "TCH 2990toner", "T"
|
||||||
TCH_2990INKJET = 110, "TCH 2990inkjet"
|
SWX_5000 = 168, "SWX 5000", "S"
|
||||||
TVY_2400H = 100, "TVY 2400h"
|
WORKHORSE_3200 = 94, "WORKHORSE 3200", "W"
|
||||||
SWX_5000 = 80, "SWX 5000"
|
FX_500 = 1, "FX 500", "F"
|
||||||
SWX_4000 = 50, "SWX 4000"
|
|
||||||
WORKHORSE_3200 = 30, "WORKHORSE 3200"
|
|
||||||
FX_500 = 15, "FX 500"
|
|
||||||
TVY_2400 = 0, "TVY 2400"
|
|
||||||
|
|
||||||
|
|
||||||
class IndicatorHash(Enum):
|
class IndicatorHash(Enum):
|
||||||
@ -42,13 +41,9 @@ class IndicatorHash(Enum):
|
|||||||
|
|
||||||
|
|
||||||
class SpecificityHash(Enum):
|
class SpecificityHash(Enum):
|
||||||
ANTI_AIRCRAFT = 55, "anti aircraft"
|
ANTI_AIRCRAFT = 512, "anti aircraft", "planes"
|
||||||
ANTI_PERSONNEL = 43, "anti personnel"
|
DEPTH_MINE = 256, "depth mine", "ships"
|
||||||
DEPTH_MINE = 37, "depth mine"
|
ANTI_TANK = 16, "anti tank", "tanks"
|
||||||
ANTI_TANK = 26, "anti tank"
|
|
||||||
PROXIMITY_MINE = 18, "proximity mine"
|
|
||||||
PRESSURE_MINE = 9, "pressure mine"
|
|
||||||
FRAGMENTATION_MINE = 0, "fragmentation mine"
|
|
||||||
|
|
||||||
|
|
||||||
class WeightHash(Enum):
|
class WeightHash(Enum):
|
||||||
@ -68,10 +63,16 @@ MAX_VALUE = max([elem.value[0] for elem in TypeHash]) \
|
|||||||
|
|
||||||
|
|
||||||
def _get_wire_color(hash_sum):
|
def _get_wire_color(hash_sum):
|
||||||
if hash_sum < 0.43 * MAX_VALUE:
|
if hash_sum < 0.20 * MAX_VALUE:
|
||||||
return Wire.BLUE
|
return Wire.BLUE
|
||||||
elif hash_sum <= 0.56 * MAX_VALUE:
|
elif hash_sum <= 0.38 * MAX_VALUE:
|
||||||
return Wire.GREEN
|
return Wire.GREEN
|
||||||
|
elif hash_sum <= 0.50 * MAX_VALUE:
|
||||||
|
return Wire.YELLOW
|
||||||
|
elif hash_sum <= 0.60 * MAX_VALUE:
|
||||||
|
return Wire.WHITE
|
||||||
|
elif hash_sum <= 0.80 * MAX_VALUE:
|
||||||
|
return Wire.PURPLE
|
||||||
else:
|
else:
|
||||||
return Wire.RED
|
return Wire.RED
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
import random
|
import random
|
||||||
from objects.mines.disarming import hash_function as hf
|
from disarming.parameters import hash_function as hf
|
||||||
|
|
||||||
|
|
||||||
class MineParameters:
|
class MineParameters:
|
@ -1,10 +1,10 @@
|
|||||||
import json
|
import json
|
||||||
import objects.mines.disarming.mine_parameters as param
|
import disarming.parameters.mine_parameters as param
|
||||||
import os
|
import os
|
||||||
import project_constants as const
|
import project_constants as const
|
||||||
|
|
||||||
# this module is self contained, used to generate a json file
|
# this module is self contained, used to generate a json file
|
||||||
DIR_DATA = os.path.join(const.ROOT_DIR, "resources", "data")
|
DIR_DATA = os.path.join(const.ROOT_DIR, "resources", "data", "decision_tree")
|
||||||
|
|
||||||
|
|
||||||
# just to show, how mine parameters works
|
# just to show, how mine parameters works
|
@ -1,8 +1,10 @@
|
|||||||
|
|
||||||
import pygame
|
import pygame
|
||||||
import pygame_gui
|
import pygame_gui
|
||||||
from project_constants import SCREEN_WIDTH, SCREEN_HEIGHT, V_NAME_OF_WINDOW
|
|
||||||
from assets.asset_constants import ASSET_CONCRETE
|
|
||||||
|
|
||||||
|
from project_constants import SCREEN_WIDTH, SCREEN_HEIGHT, V_NAME_OF_WINDOW
|
||||||
|
from objects.mine_models.mine import Mine
|
||||||
|
from disarming.disarming_handler import DisarmingHandler
|
||||||
|
|
||||||
# =========== #
|
# =========== #
|
||||||
# == const == #
|
# == const == #
|
||||||
@ -77,7 +79,7 @@ class SampleWindow:
|
|||||||
# main attributes
|
# main attributes
|
||||||
self.running = True
|
self.running = True
|
||||||
self.clock = pygame.time.Clock()
|
self.clock = pygame.time.Clock()
|
||||||
self.manager = pygame_gui.UIManager(screen_size, 'theme.json') # TODO : change theme path
|
self.manager = pygame_gui.UIManager(screen_size, 'disarming/theme.json') # TODO : change theme path
|
||||||
# main attributes
|
# main attributes
|
||||||
|
|
||||||
def gui():
|
def gui():
|
||||||
@ -206,7 +208,7 @@ class SampleWindow:
|
|||||||
(x_cables, y_cables_label1),
|
(x_cables, y_cables_label1),
|
||||||
size_cable_label
|
size_cable_label
|
||||||
),
|
),
|
||||||
text="CORRECT CABLE",
|
text="CORRECT WIRE",
|
||||||
manager=self.manager,
|
manager=self.manager,
|
||||||
object_id="description"
|
object_id="description"
|
||||||
)
|
)
|
||||||
@ -215,7 +217,7 @@ class SampleWindow:
|
|||||||
(x_cables, y_cables_label2),
|
(x_cables, y_cables_label2),
|
||||||
size_cable_label
|
size_cable_label
|
||||||
),
|
),
|
||||||
text="CHOSEN CABLE",
|
text="CHOSEN WIRE",
|
||||||
manager=self.manager,
|
manager=self.manager,
|
||||||
object_id="description"
|
object_id="description"
|
||||||
)
|
)
|
||||||
@ -276,6 +278,16 @@ class SampleWindow:
|
|||||||
manager=self.manager,
|
manager=self.manager,
|
||||||
object_id="empty_field"
|
object_id="empty_field"
|
||||||
)
|
)
|
||||||
|
surf = pygame.Surface(size_image)
|
||||||
|
surf.fill((20, 20, 20))
|
||||||
|
pygame_gui.elements.UIImage(
|
||||||
|
image_surface=surf,
|
||||||
|
relative_rect=pygame.Rect(
|
||||||
|
(x_image1, y_image),
|
||||||
|
size_image
|
||||||
|
),
|
||||||
|
manager=self.manager
|
||||||
|
)
|
||||||
|
|
||||||
def image2():
|
def image2():
|
||||||
pygame_gui.elements.UILabel(
|
pygame_gui.elements.UILabel(
|
||||||
@ -315,6 +327,16 @@ class SampleWindow:
|
|||||||
manager=self.manager,
|
manager=self.manager,
|
||||||
object_id="empty_field"
|
object_id="empty_field"
|
||||||
)
|
)
|
||||||
|
surf = pygame.Surface(size_image)
|
||||||
|
surf.fill((20, 20, 20))
|
||||||
|
pygame_gui.elements.UIImage(
|
||||||
|
image_surface=surf,
|
||||||
|
relative_rect=pygame.Rect(
|
||||||
|
(x_image2, y_image),
|
||||||
|
size_image
|
||||||
|
),
|
||||||
|
manager=self.manager
|
||||||
|
)
|
||||||
|
|
||||||
params_desc()
|
params_desc()
|
||||||
params_values()
|
params_values()
|
||||||
@ -391,25 +413,32 @@ class SampleWindow:
|
|||||||
object_id="field"
|
object_id="field"
|
||||||
)
|
)
|
||||||
|
|
||||||
def show_pic_series(self, pic: pygame.Surface):
|
def blit_pic(self, x_image, pic):
|
||||||
|
|
||||||
|
# initializing surface with background
|
||||||
surf = pygame.Surface(size_image)
|
surf = pygame.Surface(size_image)
|
||||||
surf.blit(pygame.transform.scale(pic, size_image), (0, 0))
|
surf.fill((20, 20, 20))
|
||||||
pygame_gui.elements.UIImage(
|
|
||||||
image_surface=surf,
|
# scaling size & coords
|
||||||
relative_rect=pygame.Rect(
|
bigger = max(pic.get_size()[0], pic.get_size()[1])
|
||||||
(x_image1, y_image),
|
scaling_factor = (height_image - 10) / bigger
|
||||||
size_image
|
|
||||||
),
|
length_pic = int(pic.get_size()[0]*scaling_factor)
|
||||||
manager=self.manager
|
height_pic = int(pic.get_size()[1]*scaling_factor)
|
||||||
|
size_pic = (length_pic, height_pic)
|
||||||
|
|
||||||
|
coords_pic = (
|
||||||
|
int((length_image-length_pic) / 2),
|
||||||
|
int((height_image-height_pic) / 2)
|
||||||
)
|
)
|
||||||
|
|
||||||
def show_pic_spec(self, pic: pygame.Surface):
|
# blitting the image onto background
|
||||||
surf = pygame.Surface(size_image)
|
surf.blit(pygame.transform.scale(pic, size_pic), coords_pic)
|
||||||
surf.blit(pygame.transform.scale(pic, size_image), (0, 0))
|
|
||||||
pygame_gui.elements.UIImage(
|
pygame_gui.elements.UIImage(
|
||||||
image_surface=surf,
|
image_surface=surf,
|
||||||
relative_rect=pygame.Rect(
|
relative_rect=pygame.Rect(
|
||||||
(x_image2, y_image),
|
(x_image, y_image),
|
||||||
size_image
|
size_image
|
||||||
),
|
),
|
||||||
manager=self.manager
|
manager=self.manager
|
||||||
@ -501,49 +530,66 @@ class SampleWindow:
|
|||||||
# == run == #
|
# == run == #
|
||||||
# ========= #
|
# ========= #
|
||||||
|
|
||||||
def run(self):
|
def run(self, mine: Mine):
|
||||||
|
timed_event = pygame.USEREVENT + 1
|
||||||
|
pygame.time.set_timer(timed_event, 6000)
|
||||||
|
|
||||||
|
step = 0
|
||||||
|
handler = DisarmingHandler(mine)
|
||||||
|
|
||||||
while self.running:
|
while self.running:
|
||||||
|
|
||||||
time_delta = self.clock.tick(60) / 1000.0
|
time_delta = self.clock.tick(60) / 1000.0
|
||||||
|
|
||||||
keystate = pygame.key.get_pressed()
|
|
||||||
|
|
||||||
# all events except QUIT are for testing
|
|
||||||
for event in pygame.event.get():
|
for event in pygame.event.get():
|
||||||
|
|
||||||
if event.type == pygame.QUIT:
|
if event.type == pygame.QUIT:
|
||||||
self.running = False
|
self.running = False
|
||||||
if keystate[pygame.K_a]:
|
|
||||||
self.show_params("hello", "yello", "gel", "jello", "yum", "hello")
|
if event.type == timed_event:
|
||||||
if keystate[pygame.K_s]:
|
if step == 0: # just the params
|
||||||
self.show_series("workhorse 3200wx", True)
|
params = handler.get_mine_params()
|
||||||
if keystate[pygame.K_d]:
|
self.show_params(params[0], params[1], params[2], params[3], params[4], params[5])
|
||||||
self.show_spec("anti aircraft", False)
|
elif step == 1: # correct cable
|
||||||
if keystate[pygame.K_f]:
|
self.show_cable_calculated(handler.correct_wire)
|
||||||
self.show_cable_calculated("red")
|
elif step == 2: # loading the letter image
|
||||||
if keystate[pygame.K_g]:
|
img = pygame.image.load(handler.pick_series_image())
|
||||||
self.show_cable_chosen("blue")
|
self.blit_pic(x_image1, img)
|
||||||
if keystate[pygame.K_q]:
|
elif step == 3: # recognising the letter
|
||||||
self.show_pic_series(ASSET_CONCRETE)
|
answer, is_correct = handler.recognize_series()
|
||||||
if keystate[pygame.K_w]:
|
self.show_series(answer, is_correct)
|
||||||
self.show_pic_spec(ASSET_CONCRETE)
|
elif step == 4: # loading spec image
|
||||||
|
img = pygame.image.load(handler.pick_specificity_image())
|
||||||
|
self.blit_pic(x_image2, img)
|
||||||
|
elif step == 5: # recognising spec image
|
||||||
|
answer, is_correct = handler.recognize_specificity()
|
||||||
|
self.show_spec(answer, is_correct)
|
||||||
|
elif step == 6: # showing the chosen cable
|
||||||
|
self.show_cable_chosen(handler.choose_wire())
|
||||||
|
else:
|
||||||
|
self.running = False
|
||||||
|
|
||||||
|
step += 1
|
||||||
|
|
||||||
self.manager.update(time_delta)
|
self.manager.update(time_delta)
|
||||||
self.window_surface.blit(self.background, (0, 0))
|
self.window_surface.blit(self.background, (0, 0))
|
||||||
self.manager.draw_ui(self.window_surface)
|
self.manager.draw_ui(self.window_surface)
|
||||||
|
|
||||||
pygame.display.update()
|
pygame.display.update()
|
||||||
|
return handler.defuse()
|
||||||
|
|
||||||
|
|
||||||
def disarming_popup():
|
def disarming_popup(mine: Mine = None):
|
||||||
# run the pop-up
|
# run the pop-up
|
||||||
app = SampleWindow()
|
app = SampleWindow()
|
||||||
app.run()
|
result = app.run(mine)
|
||||||
|
|
||||||
# bring display back to normal
|
# bring display back to normal
|
||||||
pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
|
pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
|
||||||
pygame.display.set_caption(V_NAME_OF_WINDOW)
|
pygame.display.set_caption(V_NAME_OF_WINDOW)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
pygame.init()
|
pygame.init()
|
@ -71,6 +71,27 @@
|
|||||||
{
|
{
|
||||||
"dark_bg": "#804e46"
|
"dark_bg": "#804e46"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"yellow":
|
||||||
|
{
|
||||||
|
"colours":
|
||||||
|
{
|
||||||
|
"dark_bg": "#7d803e"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"purple":
|
||||||
|
{
|
||||||
|
"colours":
|
||||||
|
{
|
||||||
|
"dark_bg": "#733c78"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"white":
|
||||||
|
{
|
||||||
|
"colours":
|
||||||
|
{
|
||||||
|
"dark_bg": "#7d7d7d"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
2
game.py
@ -7,7 +7,7 @@ from algorithms.search import a_star
|
|||||||
|
|
||||||
from minefield import Minefield
|
from minefield import Minefield
|
||||||
|
|
||||||
from objects.mines.mine_models.time_mine import TimeMine
|
from objects.mine_models.time_mine import TimeMine
|
||||||
|
|
||||||
from ui.ui_components_manager import UiComponentsManager
|
from ui.ui_components_manager import UiComponentsManager
|
||||||
from ui.text_box import TextBox
|
from ui.text_box import TextBox
|
||||||
|
@ -7,9 +7,9 @@ import project_constants as const
|
|||||||
from objects.tile import Tile
|
from objects.tile import Tile
|
||||||
|
|
||||||
# import mine models
|
# import mine models
|
||||||
from objects.mines.mine_models.standard_mine import StandardMine
|
from objects.mine_models.standard_mine import StandardMine
|
||||||
from objects.mines.mine_models.time_mine import TimeMine
|
from objects.mine_models.time_mine import TimeMine
|
||||||
from objects.mines.mine_models.chained_mine import ChainedMine
|
from objects.mine_models.chained_mine import ChainedMine
|
||||||
|
|
||||||
|
|
||||||
class JsonGenerator:
|
class JsonGenerator:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import project_constants as const
|
import project_constants as const
|
||||||
from objects import tile as tl, agent as ag
|
from objects import tile as tl, agent as ag
|
||||||
from objects.mines.mine_models.time_mine import TimeMine
|
from objects.mine_models.time_mine import TimeMine
|
||||||
import json_generator as jg
|
import json_generator as jg
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,7 +3,9 @@ from assets import asset_constants as asset
|
|||||||
import json
|
import json
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from pygame import transform
|
from pygame import transform
|
||||||
from algorithms.learn.decision_tree import DecisionTree
|
|
||||||
|
import disarming.popup as popup
|
||||||
|
from algorithms.learn.decision_tree.decision_tree import DecisionTree
|
||||||
|
|
||||||
|
|
||||||
# Class of our agent, initialization of it
|
# Class of our agent, initialization of it
|
||||||
@ -21,21 +23,16 @@ class Agent:
|
|||||||
self.row, self.column = int(self.row), int(self.column)
|
self.row, self.column = int(self.row), int(self.column)
|
||||||
self.position = [self.row, self.column]
|
self.position = [self.row, self.column]
|
||||||
self.on_screen_coordinates = const.get_tile_coordinates(tuple(self.position))
|
self.on_screen_coordinates = const.get_tile_coordinates(tuple(self.position))
|
||||||
self.decision_tree = DecisionTree(const.ROOT_DIR + "/algorithms/learn/decision_tree.joblib",
|
|
||||||
const.ROOT_DIR + "/algorithms/learn/dict_vectorizer.joblib")
|
|
||||||
self.direction = const.Direction(data["agents_initial_state"]["direction"])
|
self.direction = const.Direction(data["agents_initial_state"]["direction"])
|
||||||
self.rotation_angle = -const.Direction(self.direction).value * 90
|
self.rotation_angle = -const.Direction(self.direction).value * 90
|
||||||
self.going_forward = False
|
self.going_forward = False
|
||||||
self.rotating_left = False
|
self.rotating_left = False
|
||||||
self.rotating_right = False
|
self.rotating_right = False
|
||||||
|
|
||||||
def defuse_a_mine(self, mine):
|
@staticmethod
|
||||||
mine_params = mine.investigate()
|
def defuse_a_mine(mine):
|
||||||
chosen_wire = self.decision_tree.get_answer(mine_params)
|
is_success = popup.disarming_popup(mine)
|
||||||
# TODO temporarily printing chosen wire
|
return is_success
|
||||||
print("agent's chosen wire: " + str(chosen_wire[0]))
|
|
||||||
sleep(3)
|
|
||||||
return mine.disarm(chosen_wire)
|
|
||||||
|
|
||||||
def update_and_draw(self, window, delta_time, minefield):
|
def update_and_draw(self, window, delta_time, minefield):
|
||||||
self.update(delta_time, minefield)
|
self.update(delta_time, minefield)
|
||||||
|
0
objects/mine_models/__init__.py
Normal file
@ -2,7 +2,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from .mine import Mine
|
from .mine import Mine
|
||||||
from objects.mines.disarming.hash_function import TypeHash
|
from disarming.parameters.hash_function import TypeHash
|
||||||
|
|
||||||
|
|
||||||
class ChainedMine(Mine):
|
class ChainedMine(Mine):
|
@ -4,7 +4,7 @@ from abc import ABC, abstractmethod
|
|||||||
# type hints
|
# type hints
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
from objects.mines.disarming.mine_parameters import MineParameters
|
from disarming.parameters.mine_parameters import MineParameters
|
||||||
|
|
||||||
# Mine cannot be instantiated
|
# Mine cannot be instantiated
|
||||||
# all abstract methods must be implemented in derived classes
|
# all abstract methods must be implemented in derived classes
|
||||||
@ -34,7 +34,4 @@ class Mine(ABC):
|
|||||||
del mine_parameters["wire"]
|
del mine_parameters["wire"]
|
||||||
self.wire = wire
|
self.wire = wire
|
||||||
|
|
||||||
# TODO temporarily printing parameters and right wire
|
|
||||||
print("parameters:", mine_parameters, "\nright wire: " + wire)
|
|
||||||
|
|
||||||
return mine_parameters
|
return mine_parameters
|
@ -1,5 +1,5 @@
|
|||||||
from .mine import Mine
|
from .mine import Mine
|
||||||
from objects.mines.disarming.hash_function import TypeHash
|
from disarming.parameters.hash_function import TypeHash
|
||||||
|
|
||||||
|
|
||||||
class StandardMine(Mine):
|
class StandardMine(Mine):
|
@ -1,5 +1,5 @@
|
|||||||
from .mine import Mine
|
from .mine import Mine
|
||||||
from objects.mines.disarming.hash_function import TypeHash
|
from disarming.parameters.hash_function import TypeHash
|
||||||
|
|
||||||
|
|
||||||
class TimeMine(Mine):
|
class TimeMine(Mine):
|
4500
resources/data/decision_tree/training_set.txt
Normal file
BIN
resources/data/neural_network/series/disarm/F/0.jpg
Normal file
After Width: | Height: | Size: 958 B |
BIN
resources/data/neural_network/series/disarm/F/1.jpg
Normal file
After Width: | Height: | Size: 896 B |
BIN
resources/data/neural_network/series/disarm/F/10.jpg
Normal file
After Width: | Height: | Size: 893 B |
BIN
resources/data/neural_network/series/disarm/F/100.jpg
Normal file
After Width: | Height: | Size: 987 B |
BIN
resources/data/neural_network/series/disarm/F/101.jpg
Normal file
After Width: | Height: | Size: 916 B |
BIN
resources/data/neural_network/series/disarm/F/102.jpg
Normal file
After Width: | Height: | Size: 912 B |
BIN
resources/data/neural_network/series/disarm/F/103.jpg
Normal file
After Width: | Height: | Size: 927 B |
BIN
resources/data/neural_network/series/disarm/F/104.jpg
Normal file
After Width: | Height: | Size: 900 B |
BIN
resources/data/neural_network/series/disarm/F/105.jpg
Normal file
After Width: | Height: | Size: 849 B |
BIN
resources/data/neural_network/series/disarm/F/106.jpg
Normal file
After Width: | Height: | Size: 889 B |
BIN
resources/data/neural_network/series/disarm/F/107.jpg
Normal file
After Width: | Height: | Size: 925 B |
BIN
resources/data/neural_network/series/disarm/F/108.jpg
Normal file
After Width: | Height: | Size: 910 B |
BIN
resources/data/neural_network/series/disarm/F/109.jpg
Normal file
After Width: | Height: | Size: 908 B |
BIN
resources/data/neural_network/series/disarm/F/11.jpg
Normal file
After Width: | Height: | Size: 923 B |
BIN
resources/data/neural_network/series/disarm/F/110.jpg
Normal file
After Width: | Height: | Size: 992 B |
BIN
resources/data/neural_network/series/disarm/F/111.jpg
Normal file
After Width: | Height: | Size: 899 B |
BIN
resources/data/neural_network/series/disarm/F/112.jpg
Normal file
After Width: | Height: | Size: 924 B |
BIN
resources/data/neural_network/series/disarm/F/113.jpg
Normal file
After Width: | Height: | Size: 833 B |
BIN
resources/data/neural_network/series/disarm/F/114.jpg
Normal file
After Width: | Height: | Size: 839 B |
BIN
resources/data/neural_network/series/disarm/F/115.jpg
Normal file
After Width: | Height: | Size: 884 B |
BIN
resources/data/neural_network/series/disarm/F/116.jpg
Normal file
After Width: | Height: | Size: 826 B |
BIN
resources/data/neural_network/series/disarm/F/117.jpg
Normal file
After Width: | Height: | Size: 838 B |
BIN
resources/data/neural_network/series/disarm/F/118.jpg
Normal file
After Width: | Height: | Size: 915 B |
BIN
resources/data/neural_network/series/disarm/F/119.jpg
Normal file
After Width: | Height: | Size: 883 B |
BIN
resources/data/neural_network/series/disarm/F/12.jpg
Normal file
After Width: | Height: | Size: 960 B |
BIN
resources/data/neural_network/series/disarm/F/120.jpg
Normal file
After Width: | Height: | Size: 946 B |
BIN
resources/data/neural_network/series/disarm/F/121.jpg
Normal file
After Width: | Height: | Size: 998 B |
BIN
resources/data/neural_network/series/disarm/F/122.jpg
Normal file
After Width: | Height: | Size: 928 B |
BIN
resources/data/neural_network/series/disarm/F/123.jpg
Normal file
After Width: | Height: | Size: 925 B |
BIN
resources/data/neural_network/series/disarm/F/124.jpg
Normal file
After Width: | Height: | Size: 953 B |
BIN
resources/data/neural_network/series/disarm/F/125.jpg
Normal file
After Width: | Height: | Size: 1009 B |
BIN
resources/data/neural_network/series/disarm/F/126.jpg
Normal file
After Width: | Height: | Size: 996 B |
BIN
resources/data/neural_network/series/disarm/F/127.jpg
Normal file
After Width: | Height: | Size: 953 B |
BIN
resources/data/neural_network/series/disarm/F/128.jpg
Normal file
After Width: | Height: | Size: 981 B |
BIN
resources/data/neural_network/series/disarm/F/129.jpg
Normal file
After Width: | Height: | Size: 1017 B |
BIN
resources/data/neural_network/series/disarm/F/13.jpg
Normal file
After Width: | Height: | Size: 930 B |
BIN
resources/data/neural_network/series/disarm/F/130.jpg
Normal file
After Width: | Height: | Size: 955 B |
BIN
resources/data/neural_network/series/disarm/F/131.jpg
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/data/neural_network/series/disarm/F/132.jpg
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/data/neural_network/series/disarm/F/133.jpg
Normal file
After Width: | Height: | Size: 958 B |
BIN
resources/data/neural_network/series/disarm/F/134.jpg
Normal file
After Width: | Height: | Size: 966 B |
BIN
resources/data/neural_network/series/disarm/F/135.jpg
Normal file
After Width: | Height: | Size: 882 B |
BIN
resources/data/neural_network/series/disarm/F/136.jpg
Normal file
After Width: | Height: | Size: 927 B |
BIN
resources/data/neural_network/series/disarm/F/137.jpg
Normal file
After Width: | Height: | Size: 907 B |
BIN
resources/data/neural_network/series/disarm/F/138.jpg
Normal file
After Width: | Height: | Size: 949 B |
BIN
resources/data/neural_network/series/disarm/F/139.jpg
Normal file
After Width: | Height: | Size: 1014 B |
BIN
resources/data/neural_network/series/disarm/F/14.jpg
Normal file
After Width: | Height: | Size: 962 B |
BIN
resources/data/neural_network/series/disarm/F/140.jpg
Normal file
After Width: | Height: | Size: 976 B |
BIN
resources/data/neural_network/series/disarm/F/141.jpg
Normal file
After Width: | Height: | Size: 948 B |
BIN
resources/data/neural_network/series/disarm/F/142.jpg
Normal file
After Width: | Height: | Size: 868 B |
BIN
resources/data/neural_network/series/disarm/F/143.jpg
Normal file
After Width: | Height: | Size: 936 B |
BIN
resources/data/neural_network/series/disarm/F/144.jpg
Normal file
After Width: | Height: | Size: 852 B |
BIN
resources/data/neural_network/series/disarm/F/145.jpg
Normal file
After Width: | Height: | Size: 800 B |
BIN
resources/data/neural_network/series/disarm/F/146.jpg
Normal file
After Width: | Height: | Size: 806 B |
BIN
resources/data/neural_network/series/disarm/F/147.jpg
Normal file
After Width: | Height: | Size: 991 B |
BIN
resources/data/neural_network/series/disarm/F/148.jpg
Normal file
After Width: | Height: | Size: 993 B |
BIN
resources/data/neural_network/series/disarm/F/149.jpg
Normal file
After Width: | Height: | Size: 881 B |
BIN
resources/data/neural_network/series/disarm/F/15.jpg
Normal file
After Width: | Height: | Size: 1020 B |
BIN
resources/data/neural_network/series/disarm/F/150.jpg
Normal file
After Width: | Height: | Size: 889 B |
BIN
resources/data/neural_network/series/disarm/F/151.jpg
Normal file
After Width: | Height: | Size: 961 B |
BIN
resources/data/neural_network/series/disarm/F/152.jpg
Normal file
After Width: | Height: | Size: 867 B |
BIN
resources/data/neural_network/series/disarm/F/153.jpg
Normal file
After Width: | Height: | Size: 973 B |
BIN
resources/data/neural_network/series/disarm/F/154.jpg
Normal file
After Width: | Height: | Size: 1004 B |
BIN
resources/data/neural_network/series/disarm/F/155.jpg
Normal file
After Width: | Height: | Size: 865 B |
BIN
resources/data/neural_network/series/disarm/F/156.jpg
Normal file
After Width: | Height: | Size: 850 B |
BIN
resources/data/neural_network/series/disarm/F/157.jpg
Normal file
After Width: | Height: | Size: 941 B |
BIN
resources/data/neural_network/series/disarm/F/158.jpg
Normal file
After Width: | Height: | Size: 911 B |
BIN
resources/data/neural_network/series/disarm/F/159.jpg
Normal file
After Width: | Height: | Size: 976 B |
BIN
resources/data/neural_network/series/disarm/F/16.jpg
Normal file
After Width: | Height: | Size: 991 B |
BIN
resources/data/neural_network/series/disarm/F/160.jpg
Normal file
After Width: | Height: | Size: 965 B |