coordinated all changes regarding decision_tree functionality
This commit is contained in:
parent
9b20be5248
commit
f6ff6e548c
Binary file not shown.
@ -4,7 +4,8 @@ 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 mines.disarming.mine_parameters import MineParameters
|
from objects.mines.disarming.mine_parameters import MineParameters
|
||||||
|
from objects.mines.disarming.parameter_json import generate_data
|
||||||
|
|
||||||
|
|
||||||
class DecisionTree:
|
class DecisionTree:
|
||||||
@ -61,7 +62,7 @@ class DecisionTree:
|
|||||||
print(f"Answer: {answer}\nCorrect: {correct}")
|
print(f"Answer: {answer}\nCorrect: {correct}")
|
||||||
mistakes += 1
|
mistakes += 1
|
||||||
|
|
||||||
print(f"Accuracy: {100 - (mistakes / 1000)}")
|
print(f"Accuracy: {100 - (mistakes / 10)}")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _process_input_line(line):
|
def _process_input_line(line):
|
||||||
@ -74,7 +75,8 @@ class DecisionTree:
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
# generate_data("training_set.txt", 20000)
|
||||||
decision_tree = DecisionTree()
|
decision_tree = DecisionTree()
|
||||||
decision_tree.build("params3.txt", 15)
|
decision_tree.build("training_set.txt", 15)
|
||||||
decision_tree.test()
|
decision_tree.test()
|
||||||
decision_tree.save()
|
decision_tree.save()
|
||||||
|
Binary file not shown.
25
game.py
25
game.py
@ -114,15 +114,21 @@ class Game:
|
|||||||
|
|
||||||
# draws a random mine to disarm (in auto mode)
|
# draws a random mine to disarm (in auto mode)
|
||||||
def set_random_mine_as_target(self):
|
def set_random_mine_as_target(self):
|
||||||
self.goal = choice(self.minefield.get_active_mines()).position
|
if any(self.minefield.get_active_mines()):
|
||||||
|
self.goal = choice(self.minefield.get_active_mines()).position
|
||||||
|
|
||||||
# display new destination
|
# display new destination
|
||||||
self.input_box_row.set_texts(user_input=str(self.goal[0]))
|
self.input_box_row.set_texts(user_input=str(self.goal[0]))
|
||||||
self.input_box_column.set_texts(user_input=str(self.goal[1]))
|
self.input_box_column.set_texts(user_input=str(self.goal[1]))
|
||||||
|
|
||||||
# prevents highlighting input_box_row,
|
# prevents highlighting input_box_row,
|
||||||
# couldn't find any better solution w/o major Game class changes
|
# couldn't find any better solution w/o major Game class changes
|
||||||
self.input_box_row.set_is_selected(False)
|
self.input_box_row.set_is_selected(False)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
# gets action sequence for agent
|
# gets action sequence for agent
|
||||||
def get_action_sequence(self, target_type: str = "tile"):
|
def get_action_sequence(self, target_type: str = "tile"):
|
||||||
@ -138,6 +144,11 @@ class Game:
|
|||||||
toy=self.goal[1]
|
toy=self.goal[1]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# returns a mine on a given position
|
||||||
|
def get_mine(self, position):
|
||||||
|
row, column = position
|
||||||
|
return self.minefield.matrix[row][column].mine
|
||||||
|
|
||||||
# initializes attributes before game loop begins
|
# initializes attributes before game loop begins
|
||||||
def initialize_before_game_loop(self):
|
def initialize_before_game_loop(self):
|
||||||
self.agent_action = None
|
self.agent_action = None
|
||||||
|
19
main.py
19
main.py
@ -71,7 +71,7 @@ def main():
|
|||||||
# getting action sequence for agent
|
# getting action sequence for agent
|
||||||
if auto and running:
|
if auto and running:
|
||||||
in_menu = False
|
in_menu = False
|
||||||
game.set_random_mine_as_target()
|
auto = game.set_random_mine_as_target()
|
||||||
action_sequence = game.get_action_sequence("mine")
|
action_sequence = game.get_action_sequence("mine")
|
||||||
|
|
||||||
elif running:
|
elif running:
|
||||||
@ -125,15 +125,23 @@ def main():
|
|||||||
# clean up after game loop
|
# clean up after game loop
|
||||||
game.agent_take_last_action()
|
game.agent_take_last_action()
|
||||||
game.cleanup_after_game_loop()
|
game.cleanup_after_game_loop()
|
||||||
|
game.draw_minefield()
|
||||||
|
pygame.display.flip()
|
||||||
|
|
||||||
|
if auto:
|
||||||
|
if not game.agent.defuse_a_mine(game.get_mine(game.goal)):
|
||||||
|
print("BOOOOOOM\n\n")
|
||||||
|
is_game_over = True
|
||||||
|
|
||||||
|
else:
|
||||||
|
print("guess you will live a little longer...\n\n")
|
||||||
|
|
||||||
# reset in_menu flag
|
# reset in_menu flag
|
||||||
in_menu = True
|
in_menu = True
|
||||||
|
|
||||||
is_game_over = game.time_mine_exploded()
|
|
||||||
|
|
||||||
# TODO temporarily disabling game over screen
|
# TODO temporarily disabling game over screen
|
||||||
# if you want to enable game over comment line below
|
# if you want to enable game over uncomment line below
|
||||||
is_game_over = False
|
# is_game_over = game.time_mine_exploded()
|
||||||
|
|
||||||
while running and is_game_over:
|
while running and is_game_over:
|
||||||
events = pygame.event.get()
|
events = pygame.event.get()
|
||||||
@ -152,6 +160,7 @@ def main():
|
|||||||
game.cleanup_after_game_loop()
|
game.cleanup_after_game_loop()
|
||||||
is_game_over = False
|
is_game_over = False
|
||||||
in_menu = True
|
in_menu = True
|
||||||
|
auto = False
|
||||||
|
|
||||||
# updating graphics
|
# updating graphics
|
||||||
pygame.display.flip()
|
pygame.display.flip()
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import project_constants as const
|
import project_constants as const
|
||||||
from assets import asset_constants as asset
|
from assets import asset_constants as asset
|
||||||
import json
|
import json
|
||||||
|
from time import sleep
|
||||||
from pygame import transform
|
from pygame import transform
|
||||||
|
from algorithms.learn.decision_tree import DecisionTree
|
||||||
|
|
||||||
|
|
||||||
# Class of our agent, initialization of it
|
# Class of our agent, initialization of it
|
||||||
@ -19,13 +21,22 @@ 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.direction = const.Direction()
|
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):
|
||||||
|
mine_params = mine.investigate()
|
||||||
|
chosen_wire = self.decision_tree.get_answer(mine_params)
|
||||||
|
# TODO temporarily printing chosen wire
|
||||||
|
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)
|
||||||
self.draw(window)
|
self.draw(window)
|
||||||
|
@ -18,18 +18,19 @@ class DangerClassHash(Enum):
|
|||||||
WEAPON_OF_MASS_DESTRUCTION = 32, "weapon of mass destruction"
|
WEAPON_OF_MASS_DESTRUCTION = 32, "weapon of mass destruction"
|
||||||
RADIOACTIVE = 16, "radioactive"
|
RADIOACTIVE = 16, "radioactive"
|
||||||
CASUAL_DEVASTATOR = 8, "casual devastator"
|
CASUAL_DEVASTATOR = 8, "casual devastator"
|
||||||
|
LITTLE_BOY = 4, "little boy"
|
||||||
CHERRY_BOMB = 0, "cherry bomb"
|
CHERRY_BOMB = 0, "cherry bomb"
|
||||||
|
|
||||||
|
|
||||||
class SeriesHash(Enum):
|
class SeriesHash(Enum):
|
||||||
TCH_2990TONER = 65, "TCH_2990toner"
|
TCH_2990TONER = 128, "TCH_2990toner"
|
||||||
TCH_2990INKJET = 64, "TCH_2990inkjet"
|
TCH_2990INKJET = 64, "TCH_2990inkjet"
|
||||||
TVY_2400H = 55, "TVY_2400h"
|
TVY_2400H = 48, "TVY_2400h"
|
||||||
SWX_5000 = 53, "SWX_5000"
|
SWX_5000 = 32, "SWX_5000"
|
||||||
SWX_4000 = 50, "SWX_4000"
|
SWX_4000 = 16, "SWX_4000"
|
||||||
WORKHORSE_3200 = 43, "WORKHORSE_3200"
|
WORKHORSE_3200 = 8, "WORKHORSE_3200"
|
||||||
FX_500 = 40, "FX_500"
|
FX_500 = 4, "FX_500"
|
||||||
TVY_2400 = 23, "TVY_2400"
|
TVY_2400 = 0, "TVY_2400"
|
||||||
|
|
||||||
|
|
||||||
class IndicatorHash(Enum):
|
class IndicatorHash(Enum):
|
||||||
@ -50,11 +51,20 @@ class SpecificityHash(Enum):
|
|||||||
FRAGMENTATION_MINE = 0, "fragmentation_mine"
|
FRAGMENTATION_MINE = 0, "fragmentation_mine"
|
||||||
|
|
||||||
|
|
||||||
|
class WeightHash(Enum):
|
||||||
|
FAT_MAN = 32, "fat_man"
|
||||||
|
EXTRA_LARGE = 24, "extra_large"
|
||||||
|
TOTAL_AVERAGE = 16, "total_average"
|
||||||
|
SLIM_FIT = 8, "slim_fit"
|
||||||
|
BREAD_CRUMB = 0, "bread_crumb"
|
||||||
|
|
||||||
|
|
||||||
MAX_VALUE = max([elem.value[0] for elem in TypeHash]) \
|
MAX_VALUE = max([elem.value[0] for elem in TypeHash]) \
|
||||||
+ max([elem.value[0] for elem in DangerClassHash]) \
|
+ max([elem.value[0] for elem in DangerClassHash]) \
|
||||||
+ max([elem.value[0] for elem in SeriesHash]) \
|
+ max([elem.value[0] for elem in SeriesHash]) \
|
||||||
+ max([elem.value[0] for elem in IndicatorHash]) \
|
+ max([elem.value[0] for elem in IndicatorHash]) \
|
||||||
+ max([elem.value[0] for elem in SpecificityHash])
|
+ max([elem.value[0] for elem in SpecificityHash]) \
|
||||||
|
+ max([elem.value[0] for elem in WeightHash])
|
||||||
|
|
||||||
|
|
||||||
def _get_wire_color(hash_sum):
|
def _get_wire_color(hash_sum):
|
||||||
@ -67,15 +77,16 @@ def _get_wire_color(hash_sum):
|
|||||||
|
|
||||||
|
|
||||||
# STRING ARGUMENTS
|
# STRING ARGUMENTS
|
||||||
def get_wire_from_str(mine_type: str, danger_cls: str, series: str, indicator: str, specificity: str):
|
def get_wire_from_str(mine_type: str, danger_cls: str, series: str, indicator: str, specificity: str, weight: str):
|
||||||
|
|
||||||
type_hash = TypeHash[mine_type.upper().replace(" ", "_")].value[0]
|
type_hash = TypeHash[mine_type.upper().replace(" ", "_")].value[0]
|
||||||
danger_cls_hash = DangerClassHash[danger_cls.upper().replace(" ", "_")].value[0]
|
danger_cls_hash = DangerClassHash[danger_cls.upper().replace(" ", "_")].value[0]
|
||||||
series_hash = SeriesHash[series.upper().replace(" ", "_")].value[0]
|
series_hash = SeriesHash[series.upper().replace(" ", "_")].value[0]
|
||||||
indicator_hash = IndicatorHash[indicator.upper().replace(" ", "_")].value[0]
|
indicator_hash = IndicatorHash[indicator.upper().replace(" ", "_")].value[0]
|
||||||
specificity_hash = SpecificityHash[specificity.upper().replace(" ", "_")].value[0]
|
specificity_hash = SpecificityHash[specificity.upper().replace(" ", "_")].value[0]
|
||||||
|
weight_hash = WeightHash[weight.upper().replace(" ", "_")].value[0]
|
||||||
|
|
||||||
hash_sum = type_hash + danger_cls_hash + series_hash + indicator_hash + specificity_hash
|
hash_sum = type_hash + danger_cls_hash + series_hash + indicator_hash + specificity_hash + weight_hash
|
||||||
return _get_wire_color(hash_sum)
|
return _get_wire_color(hash_sum)
|
||||||
|
|
||||||
|
|
||||||
@ -85,7 +96,10 @@ def get_wire_from_enums(
|
|||||||
danger_cls: DangerClassHash,
|
danger_cls: DangerClassHash,
|
||||||
series: SeriesHash,
|
series: SeriesHash,
|
||||||
indicator: IndicatorHash,
|
indicator: IndicatorHash,
|
||||||
specificity: SpecificityHash):
|
specificity: SpecificityHash,
|
||||||
|
weight: WeightHash):
|
||||||
|
|
||||||
|
hash_list = [mine_type, danger_cls, series, indicator, specificity, weight]
|
||||||
|
hash_sum = sum([enum.value[0] for enum in hash_list])
|
||||||
|
|
||||||
hash_sum = mine_type.value[0] + danger_cls.value[0] + series.value[0] + indicator.value[0] + specificity.value[0]
|
|
||||||
return _get_wire_color(hash_sum)
|
return _get_wire_color(hash_sum)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import random
|
import random
|
||||||
from mines.disarming import hash_function as hf
|
from objects.mines.disarming import hash_function as hf
|
||||||
|
|
||||||
|
|
||||||
class MineParameters:
|
class MineParameters:
|
||||||
@ -11,20 +11,22 @@ class MineParameters:
|
|||||||
self.series = random.choice(list(hf.SeriesHash))
|
self.series = random.choice(list(hf.SeriesHash))
|
||||||
self.indicator = random.choice(list(hf.IndicatorHash))
|
self.indicator = random.choice(list(hf.IndicatorHash))
|
||||||
self.specificity = random.choice(list(hf.SpecificityHash))
|
self.specificity = random.choice(list(hf.SpecificityHash))
|
||||||
|
self.weight = random.choice(list(hf.WeightHash))
|
||||||
else:
|
else:
|
||||||
self.mine_type = jdict["mine_type"]
|
self.mine_type = jdict["mine_type"]
|
||||||
self.danger_cls = jdict["danger_cls"]
|
self.danger_cls = jdict["danger_cls"]
|
||||||
self.series = jdict["series"]
|
self.series = jdict["series"]
|
||||||
self.specificity = jdict["specificity"]
|
self.specificity = jdict["specificity"]
|
||||||
self.indicator = jdict["indicator"]
|
self.indicator = jdict["indicator"]
|
||||||
|
self.weight = jdict["weight"]
|
||||||
|
|
||||||
if mine_type is not None:
|
if mine_type is not None:
|
||||||
self.mine_type = mine_type
|
self.mine_type = mine_type
|
||||||
|
|
||||||
def jsonifyable_dict(self):
|
def jsonifyable_dict(self, with_wire=True):
|
||||||
wire = hf.get_wire_from_enums(
|
wire = hf.get_wire_from_enums(
|
||||||
self.mine_type, self.danger_cls, self.series,
|
self.mine_type, self.danger_cls, self.series,
|
||||||
self.indicator, self.specificity
|
self.indicator, self.specificity, self.weight
|
||||||
)
|
)
|
||||||
|
|
||||||
jdict = {
|
jdict = {
|
||||||
@ -33,13 +35,17 @@ class MineParameters:
|
|||||||
"series": self.series.value[1],
|
"series": self.series.value[1],
|
||||||
"specificity": self.specificity.value[1],
|
"specificity": self.specificity.value[1],
|
||||||
"indicator": self.indicator.value[1],
|
"indicator": self.indicator.value[1],
|
||||||
"wire": wire.value[1]
|
"weight": self.weight.value[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if with_wire:
|
||||||
|
jdict["wire"] = wire.value[1]
|
||||||
|
|
||||||
return jdict
|
return jdict
|
||||||
|
|
||||||
def get_parameters(self):
|
def get_parameters(self):
|
||||||
return self.mine_type, self.danger_cls, self.series,\
|
return self.mine_type, self.danger_cls, self.series,\
|
||||||
self.specificity, self.indicator
|
self.specificity, self.indicator, self.weight
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import json
|
import json
|
||||||
import objects.mines.disarming.mine_parameters as param
|
import objects.mines.disarming.mine_parameters as param
|
||||||
import os
|
import os
|
||||||
|
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("../../../resources", "data")
|
DIR_DATA = os.path.join(const.ROOT_DIR, "resources", "data")
|
||||||
|
|
||||||
|
|
||||||
# just to show, how mine parameters works
|
# just to show, how mine parameters works
|
||||||
@ -40,7 +41,7 @@ def generate_data(file_name: str, lines: int):
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
generate_data("params4.txt", 1000)
|
generate_data("training_set.txt", 20000)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -2,17 +2,21 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from .mine import Mine
|
from .mine import Mine
|
||||||
|
from objects.mines.disarming.hash_function import TypeHash
|
||||||
|
|
||||||
|
|
||||||
class ChainedMine(Mine):
|
class ChainedMine(Mine):
|
||||||
def __init__(self, position, predecessor: ChainedMine = None, active=True):
|
def __init__(self, position, predecessor: ChainedMine = None, active=True):
|
||||||
self.predecessor = predecessor
|
|
||||||
self.type = "chained"
|
self.type = "chained"
|
||||||
super().__init__(position, active)
|
self.predecessor = predecessor
|
||||||
|
super().__init__(TypeHash.CHAINED, position, active)
|
||||||
|
|
||||||
def disarm(self):
|
def disarm(self, wire):
|
||||||
if self.predecessor is None or not self.predecessor.active:
|
if self.predecessor is None or not self.predecessor.active:
|
||||||
super().disarm()
|
return super().disarm(wire)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# boom?
|
return False
|
||||||
pass
|
|
||||||
|
def investigate(self):
|
||||||
|
return super().investigate()
|
||||||
|
@ -4,16 +4,37 @@ 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
|
||||||
|
|
||||||
# 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
|
||||||
|
|
||||||
|
|
||||||
class Mine(ABC):
|
class Mine(ABC):
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def __init__(self, position: Tuple[int, int], active=True):
|
def __init__(self, _type, position: Tuple[int, int], active=True):
|
||||||
|
self.enum_type = _type
|
||||||
self.position = position
|
self.position = position
|
||||||
|
self.wire = None
|
||||||
self.active = active
|
self.active = active
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def disarm(self):
|
def disarm(self, wire):
|
||||||
self.active = False
|
if wire == self.wire:
|
||||||
|
self.active = False
|
||||||
|
return True
|
||||||
|
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def investigate(self):
|
||||||
|
mine_parameters = MineParameters(mine_type=self.enum_type).jsonifyable_dict()
|
||||||
|
wire = mine_parameters["wire"]
|
||||||
|
del mine_parameters["wire"]
|
||||||
|
self.wire = wire
|
||||||
|
|
||||||
|
# TODO temporarily printing parameters and right wire
|
||||||
|
print("parameters:", mine_parameters, "\nright wire: " + wire)
|
||||||
|
|
||||||
|
return mine_parameters
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
from .mine import Mine
|
from .mine import Mine
|
||||||
|
from objects.mines.disarming.hash_function import TypeHash
|
||||||
|
|
||||||
|
|
||||||
class StandardMine(Mine):
|
class StandardMine(Mine):
|
||||||
def __init__(self, position, active=True):
|
def __init__(self, position, active=True):
|
||||||
self.type = "standard"
|
self.type = "standard"
|
||||||
super().__init__(position, active)
|
super().__init__(TypeHash.STANDARD, position, active)
|
||||||
|
|
||||||
def disarm(self):
|
def disarm(self, wire):
|
||||||
super().disarm()
|
return super().disarm(wire)
|
||||||
|
|
||||||
|
def investigate(self):
|
||||||
|
return super().investigate()
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from .mine import Mine
|
from .mine import Mine
|
||||||
|
from objects.mines.disarming.hash_function import TypeHash
|
||||||
|
|
||||||
|
|
||||||
class TimeMine(Mine):
|
class TimeMine(Mine):
|
||||||
@ -6,7 +7,10 @@ class TimeMine(Mine):
|
|||||||
self.type = "time"
|
self.type = "time"
|
||||||
self.timer = timer
|
self.timer = timer
|
||||||
self.starting_time = timer
|
self.starting_time = timer
|
||||||
super().__init__(position, active)
|
super().__init__(TypeHash.TIME, position, active)
|
||||||
|
|
||||||
def disarm(self):
|
def disarm(self, wire):
|
||||||
super().disarm()
|
return super().disarm(wire)
|
||||||
|
|
||||||
|
def investigate(self):
|
||||||
|
return super().investigate()
|
||||||
|
@ -21,7 +21,8 @@ from ui.input_box import InputBox
|
|||||||
V_NAME_OF_WINDOW = "MineFusion TM"
|
V_NAME_OF_WINDOW = "MineFusion TM"
|
||||||
V_FPS = 60
|
V_FPS = 60
|
||||||
|
|
||||||
DIR_ASSETS = os.path.join("resources", "assets")
|
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
DIR_ASSETS = os.path.join(ROOT_DIR, "resources", "assets")
|
||||||
|
|
||||||
TURN_INTERVAL = 0.3 # interval between two turns in seconds
|
TURN_INTERVAL = 0.3 # interval between two turns in seconds
|
||||||
|
|
||||||
@ -157,54 +158,6 @@ HIGHLIGHT = pygame.transform.scale(
|
|||||||
)
|
)
|
||||||
HIGHLIGHT.set_alpha(100)
|
HIGHLIGHT.set_alpha(100)
|
||||||
|
|
||||||
_gui_width = V_SIDE_MENU_WIDTH
|
|
||||||
_ib_height, _bt_height = V_INPUT_BOX_HEIGHT, V_BUTTON_HEIGHT
|
|
||||||
_gui_x = V_TILE_AREA_WIDTH + 2 * V_SCREEN_PADDING + V_NUMBER_PADDING
|
|
||||||
_gui_y = SCREEN.get_height() / 2 - (2 * _ib_height + 2 * _bt_height + 30) / 2
|
|
||||||
|
|
||||||
INPUT_ROW = InputBox(
|
|
||||||
position=(_gui_x, _gui_y),
|
|
||||||
dimensions=(_gui_width, _ib_height),
|
|
||||||
text="row",
|
|
||||||
box_color=(100, 200, 100),
|
|
||||||
bottom_strip_color=(120, 220, 120),
|
|
||||||
inner_box_color=(120, 220, 120),
|
|
||||||
outline_color=(80, 180, 80),
|
|
||||||
outline_additional_pixel=True,
|
|
||||||
valid_input_characters="1234567890",
|
|
||||||
input_centered=True,
|
|
||||||
clear_input_on_click=True
|
|
||||||
)
|
|
||||||
INPUT_COLUMN = InputBox(
|
|
||||||
position=(_gui_x, _gui_y + _ib_height + 10),
|
|
||||||
dimensions=(_gui_width, _ib_height),
|
|
||||||
text="column",
|
|
||||||
box_color=(100, 200, 100),
|
|
||||||
bottom_strip_color=(120, 220, 120),
|
|
||||||
inner_box_color=(120, 220, 120),
|
|
||||||
outline_color=(80, 180, 80),
|
|
||||||
outline_additional_pixel=True,
|
|
||||||
valid_input_characters="1234567890",
|
|
||||||
input_centered=True,
|
|
||||||
clear_input_on_click=True
|
|
||||||
)
|
|
||||||
RANDOM_BUTTON = Button(
|
|
||||||
position=(_gui_x, _gui_y + 2 * _ib_height + 20),
|
|
||||||
dimensions=(_gui_width, _bt_height),
|
|
||||||
text="random",
|
|
||||||
box_color=(100, 200, 100),
|
|
||||||
outline_color=(80, 180, 80),
|
|
||||||
outline_additional_pixel=True
|
|
||||||
)
|
|
||||||
OK_BUTTON = Button(
|
|
||||||
position=(_gui_x, _gui_y + 2 * _ib_height + _bt_height + 30),
|
|
||||||
dimensions=(_gui_width, _bt_height),
|
|
||||||
text="ok",
|
|
||||||
box_color=(100, 200, 100),
|
|
||||||
outline_color=(80, 180, 80),
|
|
||||||
outline_additional_pixel=True
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# ============== #
|
# ============== #
|
||||||
# ==== MAPS ==== #
|
# ==== MAPS ==== #
|
||||||
|
@ -1,200 +0,0 @@
|
|||||||
{"mine_type": "chained", "danger_cls": "weapon of mass destruction", "series": "SWX_5000", "specificity": "depth_mine", "indicator": "blue", "wire": "green"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "big bang", "series": "FX_500", "specificity": "fragmentation_mine", "indicator": "white", "wire": "green"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "weapon of mass destruction", "series": "TCH_2990inkjet", "specificity": "anti_tank", "indicator": "red", "wire": "green"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "cherry bomb", "series": "SWX_5000", "specificity": "anti_tank", "indicator": "red", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "big bang", "series": "SWX_5000", "specificity": "proximity_mine", "indicator": "green", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "weapon of mass destruction", "series": "TVY_2400h", "specificity": "proximity_mine", "indicator": "red", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "casual devastator", "series": "SWX_4000", "specificity": "pressure_mine", "indicator": "red", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "weapon of mass destruction", "series": "WORKHORSE_3200", "specificity": "fragmentation_mine", "indicator": "red", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "weapon of mass destruction", "series": "TVY_2400", "specificity": "anti_tank", "indicator": "green", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "big bang", "series": "SWX_4000", "specificity": "fragmentation_mine", "indicator": "red", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "weapon of mass destruction", "series": "TCH_2990toner", "specificity": "anti_tank", "indicator": "white", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "casual devastator", "series": "TVY_2400", "specificity": "anti_aircraft", "indicator": "blue", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "cherry bomb", "series": "SWX_4000", "specificity": "anti_tank", "indicator": "green", "wire": "green"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "radioactive", "series": "SWX_4000", "specificity": "anti_tank", "indicator": "red", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "radioactive", "series": "TCH_2990inkjet", "specificity": "proximity_mine", "indicator": "blue", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "radioactive", "series": "TCH_2990toner", "specificity": "anti_tank", "indicator": "blue", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "cherry bomb", "series": "TVY_2400", "specificity": "anti_aircraft", "indicator": "red", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "weapon of mass destruction", "series": "TVY_2400", "specificity": "anti_tank", "indicator": "red", "wire": "red"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "weapon of mass destruction", "series": "TVY_2400", "specificity": "pressure_mine", "indicator": "red", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "radioactive", "series": "TVY_2400", "specificity": "proximity_mine", "indicator": "white", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "radioactive", "series": "FX_500", "specificity": "anti_tank", "indicator": "blue", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "weapon of mass destruction", "series": "SWX_5000", "specificity": "anti_tank", "indicator": "blue", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "casual devastator", "series": "TVY_2400", "specificity": "pressure_mine", "indicator": "red", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "big bang", "series": "SWX_4000", "specificity": "anti_personnel", "indicator": "blue", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "big bang", "series": "TVY_2400", "specificity": "proximity_mine", "indicator": "red", "wire": "red"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "weapon of mass destruction", "series": "SWX_4000", "specificity": "anti_tank", "indicator": "white", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "weapon of mass destruction", "series": "TVY_2400h", "specificity": "pressure_mine", "indicator": "green", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "casual devastator", "series": "TCH_2990toner", "specificity": "pressure_mine", "indicator": "white", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "casual devastator", "series": "SWX_5000", "specificity": "anti_tank", "indicator": "white", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "weapon of mass destruction", "series": "FX_500", "specificity": "anti_personnel", "indicator": "blue", "wire": "green"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "cherry bomb", "series": "FX_500", "specificity": "proximity_mine", "indicator": "white", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "casual devastator", "series": "TVY_2400h", "specificity": "proximity_mine", "indicator": "green", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "weapon of mass destruction", "series": "TVY_2400h", "specificity": "anti_personnel", "indicator": "green", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "cherry bomb", "series": "SWX_5000", "specificity": "anti_aircraft", "indicator": "red", "wire": "red"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "weapon of mass destruction", "series": "TVY_2400", "specificity": "fragmentation_mine", "indicator": "white", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "weapon of mass destruction", "series": "TVY_2400h", "specificity": "pressure_mine", "indicator": "red", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "casual devastator", "series": "WORKHORSE_3200", "specificity": "anti_tank", "indicator": "red", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "casual devastator", "series": "TVY_2400h", "specificity": "anti_tank", "indicator": "red", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "casual devastator", "series": "TVY_2400h", "specificity": "proximity_mine", "indicator": "yellow", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "casual devastator", "series": "TVY_2400", "specificity": "proximity_mine", "indicator": "yellow", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "cherry bomb", "series": "FX_500", "specificity": "fragmentation_mine", "indicator": "yellow", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "weapon of mass destruction", "series": "TCH_2990inkjet", "specificity": "depth_mine", "indicator": "yellow", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "big bang", "series": "TCH_2990inkjet", "specificity": "depth_mine", "indicator": "white", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "cherry bomb", "series": "TCH_2990toner", "specificity": "pressure_mine", "indicator": "yellow", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "casual devastator", "series": "TVY_2400", "specificity": "anti_tank", "indicator": "green", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "casual devastator", "series": "FX_500", "specificity": "anti_personnel", "indicator": "yellow", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "radioactive", "series": "SWX_4000", "specificity": "depth_mine", "indicator": "green", "wire": "green"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "cherry bomb", "series": "FX_500", "specificity": "fragmentation_mine", "indicator": "green", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "radioactive", "series": "TCH_2990toner", "specificity": "anti_tank", "indicator": "yellow", "wire": "green"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "casual devastator", "series": "TVY_2400h", "specificity": "anti_personnel", "indicator": "green", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "casual devastator", "series": "TVY_2400", "specificity": "anti_aircraft", "indicator": "white", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "weapon of mass destruction", "series": "TCH_2990toner", "specificity": "pressure_mine", "indicator": "blue", "wire": "red"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "big bang", "series": "TCH_2990inkjet", "specificity": "anti_personnel", "indicator": "red", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "radioactive", "series": "TCH_2990inkjet", "specificity": "anti_personnel", "indicator": "green", "wire": "red"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "casual devastator", "series": "SWX_5000", "specificity": "anti_aircraft", "indicator": "green", "wire": "green"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "cherry bomb", "series": "TVY_2400", "specificity": "depth_mine", "indicator": "red", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "cherry bomb", "series": "SWX_5000", "specificity": "fragmentation_mine", "indicator": "blue", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "weapon of mass destruction", "series": "SWX_5000", "specificity": "anti_aircraft", "indicator": "red", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "cherry bomb", "series": "TCH_2990inkjet", "specificity": "anti_personnel", "indicator": "yellow", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "radioactive", "series": "TVY_2400", "specificity": "anti_tank", "indicator": "blue", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "weapon of mass destruction", "series": "TVY_2400h", "specificity": "fragmentation_mine", "indicator": "green", "wire": "red"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "casual devastator", "series": "SWX_4000", "specificity": "anti_personnel", "indicator": "green", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "casual devastator", "series": "FX_500", "specificity": "anti_tank", "indicator": "white", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "radioactive", "series": "WORKHORSE_3200", "specificity": "anti_aircraft", "indicator": "red", "wire": "green"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "casual devastator", "series": "TCH_2990inkjet", "specificity": "anti_tank", "indicator": "white", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "cherry bomb", "series": "SWX_4000", "specificity": "pressure_mine", "indicator": "green", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "casual devastator", "series": "TCH_2990toner", "specificity": "anti_personnel", "indicator": "green", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "casual devastator", "series": "FX_500", "specificity": "fragmentation_mine", "indicator": "yellow", "wire": "green"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "weapon of mass destruction", "series": "TCH_2990toner", "specificity": "anti_personnel", "indicator": "red", "wire": "green"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "casual devastator", "series": "TVY_2400h", "specificity": "anti_aircraft", "indicator": "green", "wire": "green"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "cherry bomb", "series": "WORKHORSE_3200", "specificity": "depth_mine", "indicator": "green", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "radioactive", "series": "FX_500", "specificity": "anti_aircraft", "indicator": "red", "wire": "red"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "radioactive", "series": "FX_500", "specificity": "pressure_mine", "indicator": "yellow", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "cherry bomb", "series": "WORKHORSE_3200", "specificity": "proximity_mine", "indicator": "white", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "casual devastator", "series": "TVY_2400", "specificity": "pressure_mine", "indicator": "white", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "weapon of mass destruction", "series": "TVY_2400h", "specificity": "anti_tank", "indicator": "red", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "big bang", "series": "TVY_2400", "specificity": "depth_mine", "indicator": "white", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "big bang", "series": "SWX_4000", "specificity": "anti_tank", "indicator": "blue", "wire": "green"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "weapon of mass destruction", "series": "WORKHORSE_3200", "specificity": "depth_mine", "indicator": "blue", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "weapon of mass destruction", "series": "TCH_2990inkjet", "specificity": "proximity_mine", "indicator": "green", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "radioactive", "series": "WORKHORSE_3200", "specificity": "anti_personnel", "indicator": "red", "wire": "red"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "radioactive", "series": "TCH_2990toner", "specificity": "pressure_mine", "indicator": "blue", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "radioactive", "series": "WORKHORSE_3200", "specificity": "proximity_mine", "indicator": "white", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "big bang", "series": "SWX_4000", "specificity": "pressure_mine", "indicator": "blue", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "cherry bomb", "series": "TCH_2990toner", "specificity": "anti_tank", "indicator": "yellow", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "radioactive", "series": "SWX_5000", "specificity": "depth_mine", "indicator": "green", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "weapon of mass destruction", "series": "WORKHORSE_3200", "specificity": "anti_personnel", "indicator": "yellow", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "big bang", "series": "TCH_2990inkjet", "specificity": "anti_tank", "indicator": "white", "wire": "red"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "cherry bomb", "series": "SWX_5000", "specificity": "pressure_mine", "indicator": "white", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "casual devastator", "series": "SWX_4000", "specificity": "proximity_mine", "indicator": "blue", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "cherry bomb", "series": "SWX_5000", "specificity": "anti_tank", "indicator": "red", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "cherry bomb", "series": "SWX_5000", "specificity": "depth_mine", "indicator": "blue", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "cherry bomb", "series": "WORKHORSE_3200", "specificity": "fragmentation_mine", "indicator": "green", "wire": "green"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "casual devastator", "series": "TVY_2400", "specificity": "anti_aircraft", "indicator": "red", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "weapon of mass destruction", "series": "TCH_2990inkjet", "specificity": "anti_personnel", "indicator": "red", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "weapon of mass destruction", "series": "SWX_4000", "specificity": "fragmentation_mine", "indicator": "yellow", "wire": "red"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "cherry bomb", "series": "TCH_2990inkjet", "specificity": "pressure_mine", "indicator": "blue", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "weapon of mass destruction", "series": "FX_500", "specificity": "proximity_mine", "indicator": "white", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "big bang", "series": "TCH_2990toner", "specificity": "pressure_mine", "indicator": "white", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "big bang", "series": "FX_500", "specificity": "anti_personnel", "indicator": "red", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "big bang", "series": "FX_500", "specificity": "fragmentation_mine", "indicator": "blue", "wire": "green"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "cherry bomb", "series": "SWX_4000", "specificity": "fragmentation_mine", "indicator": "green", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "casual devastator", "series": "WORKHORSE_3200", "specificity": "proximity_mine", "indicator": "white", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "big bang", "series": "TVY_2400h", "specificity": "pressure_mine", "indicator": "yellow", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "cherry bomb", "series": "SWX_5000", "specificity": "pressure_mine", "indicator": "yellow", "wire": "green"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "radioactive", "series": "TCH_2990toner", "specificity": "depth_mine", "indicator": "green", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "cherry bomb", "series": "WORKHORSE_3200", "specificity": "pressure_mine", "indicator": "blue", "wire": "green"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "casual devastator", "series": "WORKHORSE_3200", "specificity": "pressure_mine", "indicator": "white", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "big bang", "series": "SWX_4000", "specificity": "pressure_mine", "indicator": "red", "wire": "green"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "casual devastator", "series": "FX_500", "specificity": "depth_mine", "indicator": "red", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "big bang", "series": "TCH_2990inkjet", "specificity": "anti_aircraft", "indicator": "white", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "big bang", "series": "FX_500", "specificity": "pressure_mine", "indicator": "blue", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "casual devastator", "series": "TCH_2990inkjet", "specificity": "proximity_mine", "indicator": "blue", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "radioactive", "series": "TCH_2990inkjet", "specificity": "anti_personnel", "indicator": "yellow", "wire": "green"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "casual devastator", "series": "WORKHORSE_3200", "specificity": "anti_tank", "indicator": "blue", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "radioactive", "series": "FX_500", "specificity": "depth_mine", "indicator": "white", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "casual devastator", "series": "FX_500", "specificity": "anti_tank", "indicator": "red", "wire": "red"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "weapon of mass destruction", "series": "FX_500", "specificity": "anti_tank", "indicator": "green", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "big bang", "series": "TVY_2400", "specificity": "anti_aircraft", "indicator": "yellow", "wire": "green"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "cherry bomb", "series": "TVY_2400h", "specificity": "pressure_mine", "indicator": "yellow", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "weapon of mass destruction", "series": "SWX_5000", "specificity": "pressure_mine", "indicator": "red", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "radioactive", "series": "FX_500", "specificity": "fragmentation_mine", "indicator": "white", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "radioactive", "series": "TCH_2990toner", "specificity": "fragmentation_mine", "indicator": "red", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "big bang", "series": "SWX_4000", "specificity": "depth_mine", "indicator": "blue", "wire": "green"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "casual devastator", "series": "SWX_5000", "specificity": "anti_tank", "indicator": "red", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "cherry bomb", "series": "SWX_4000", "specificity": "depth_mine", "indicator": "white", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "radioactive", "series": "SWX_5000", "specificity": "proximity_mine", "indicator": "red", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "big bang", "series": "FX_500", "specificity": "proximity_mine", "indicator": "green", "wire": "green"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "cherry bomb", "series": "SWX_4000", "specificity": "pressure_mine", "indicator": "red", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "cherry bomb", "series": "SWX_5000", "specificity": "pressure_mine", "indicator": "blue", "wire": "green"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "casual devastator", "series": "TVY_2400h", "specificity": "anti_personnel", "indicator": "blue", "wire": "green"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "big bang", "series": "SWX_5000", "specificity": "anti_tank", "indicator": "yellow", "wire": "green"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "big bang", "series": "TCH_2990inkjet", "specificity": "fragmentation_mine", "indicator": "green", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "casual devastator", "series": "SWX_4000", "specificity": "anti_personnel", "indicator": "white", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "big bang", "series": "TVY_2400", "specificity": "anti_aircraft", "indicator": "white", "wire": "green"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "cherry bomb", "series": "TCH_2990toner", "specificity": "fragmentation_mine", "indicator": "red", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "radioactive", "series": "SWX_4000", "specificity": "depth_mine", "indicator": "green", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "big bang", "series": "SWX_4000", "specificity": "depth_mine", "indicator": "yellow", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "big bang", "series": "TVY_2400h", "specificity": "proximity_mine", "indicator": "green", "wire": "green"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "weapon of mass destruction", "series": "TCH_2990inkjet", "specificity": "anti_personnel", "indicator": "green", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "casual devastator", "series": "FX_500", "specificity": "anti_tank", "indicator": "yellow", "wire": "red"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "cherry bomb", "series": "TVY_2400", "specificity": "fragmentation_mine", "indicator": "yellow", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "radioactive", "series": "TVY_2400", "specificity": "fragmentation_mine", "indicator": "red", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "big bang", "series": "WORKHORSE_3200", "specificity": "anti_aircraft", "indicator": "yellow", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "big bang", "series": "TVY_2400h", "specificity": "fragmentation_mine", "indicator": "blue", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "cherry bomb", "series": "SWX_4000", "specificity": "anti_personnel", "indicator": "green", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "weapon of mass destruction", "series": "TCH_2990toner", "specificity": "anti_tank", "indicator": "green", "wire": "green"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "casual devastator", "series": "TCH_2990inkjet", "specificity": "anti_aircraft", "indicator": "green", "wire": "green"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "cherry bomb", "series": "TVY_2400h", "specificity": "anti_personnel", "indicator": "yellow", "wire": "green"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "cherry bomb", "series": "WORKHORSE_3200", "specificity": "anti_aircraft", "indicator": "white", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "big bang", "series": "TVY_2400", "specificity": "depth_mine", "indicator": "blue", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "cherry bomb", "series": "TCH_2990inkjet", "specificity": "depth_mine", "indicator": "white", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "big bang", "series": "SWX_5000", "specificity": "depth_mine", "indicator": "white", "wire": "green"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "cherry bomb", "series": "SWX_5000", "specificity": "pressure_mine", "indicator": "blue", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "cherry bomb", "series": "TVY_2400h", "specificity": "proximity_mine", "indicator": "blue", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "cherry bomb", "series": "TCH_2990inkjet", "specificity": "depth_mine", "indicator": "white", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "radioactive", "series": "SWX_4000", "specificity": "proximity_mine", "indicator": "blue", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "cherry bomb", "series": "SWX_5000", "specificity": "depth_mine", "indicator": "white", "wire": "red"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "big bang", "series": "TCH_2990inkjet", "specificity": "anti_personnel", "indicator": "green", "wire": "red"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "cherry bomb", "series": "TCH_2990inkjet", "specificity": "pressure_mine", "indicator": "red", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "cherry bomb", "series": "TCH_2990inkjet", "specificity": "anti_aircraft", "indicator": "yellow", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "casual devastator", "series": "WORKHORSE_3200", "specificity": "anti_personnel", "indicator": "yellow", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "radioactive", "series": "WORKHORSE_3200", "specificity": "pressure_mine", "indicator": "yellow", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "casual devastator", "series": "SWX_4000", "specificity": "anti_aircraft", "indicator": "red", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "big bang", "series": "WORKHORSE_3200", "specificity": "anti_personnel", "indicator": "red", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "radioactive", "series": "TCH_2990inkjet", "specificity": "fragmentation_mine", "indicator": "white", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "cherry bomb", "series": "SWX_5000", "specificity": "anti_personnel", "indicator": "blue", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "big bang", "series": "SWX_4000", "specificity": "anti_personnel", "indicator": "blue", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "radioactive", "series": "FX_500", "specificity": "anti_aircraft", "indicator": "blue", "wire": "green"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "weapon of mass destruction", "series": "TCH_2990inkjet", "specificity": "anti_tank", "indicator": "yellow", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "radioactive", "series": "WORKHORSE_3200", "specificity": "anti_aircraft", "indicator": "blue", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "big bang", "series": "TVY_2400", "specificity": "anti_tank", "indicator": "red", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "casual devastator", "series": "TCH_2990toner", "specificity": "anti_tank", "indicator": "blue", "wire": "green"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "cherry bomb", "series": "SWX_5000", "specificity": "anti_tank", "indicator": "green", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "casual devastator", "series": "SWX_5000", "specificity": "pressure_mine", "indicator": "blue", "wire": "green"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "radioactive", "series": "SWX_5000", "specificity": "anti_tank", "indicator": "yellow", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "big bang", "series": "FX_500", "specificity": "anti_tank", "indicator": "green", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "big bang", "series": "SWX_4000", "specificity": "pressure_mine", "indicator": "green", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "casual devastator", "series": "SWX_5000", "specificity": "proximity_mine", "indicator": "blue", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "cherry bomb", "series": "TVY_2400h", "specificity": "depth_mine", "indicator": "yellow", "wire": "red"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "radioactive", "series": "WORKHORSE_3200", "specificity": "anti_aircraft", "indicator": "blue", "wire": "green"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "radioactive", "series": "WORKHORSE_3200", "specificity": "fragmentation_mine", "indicator": "white", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "casual devastator", "series": "SWX_5000", "specificity": "anti_tank", "indicator": "blue", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "big bang", "series": "TCH_2990inkjet", "specificity": "anti_personnel", "indicator": "green", "wire": "red"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "casual devastator", "series": "TVY_2400", "specificity": "anti_personnel", "indicator": "yellow", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "weapon of mass destruction", "series": "SWX_4000", "specificity": "anti_aircraft", "indicator": "blue", "wire": "green"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "radioactive", "series": "WORKHORSE_3200", "specificity": "anti_aircraft", "indicator": "red", "wire": "green"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "big bang", "series": "TCH_2990toner", "specificity": "anti_personnel", "indicator": "blue", "wire": "red"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "weapon of mass destruction", "series": "WORKHORSE_3200", "specificity": "pressure_mine", "indicator": "white", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "cherry bomb", "series": "TCH_2990inkjet", "specificity": "anti_personnel", "indicator": "red", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "big bang", "series": "SWX_4000", "specificity": "depth_mine", "indicator": "white", "wire": "red"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "weapon of mass destruction", "series": "TVY_2400", "specificity": "anti_tank", "indicator": "white", "wire": "blue"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "radioactive", "series": "TCH_2990inkjet", "specificity": "pressure_mine", "indicator": "blue", "wire": "blue"}
|
|
||||||
{"mine_type": "time", "danger_cls": "radioactive", "series": "TVY_2400h", "specificity": "proximity_mine", "indicator": "green", "wire": "red"}
|
|
||||||
{"mine_type": "time", "danger_cls": "radioactive", "series": "FX_500", "specificity": "fragmentation_mine", "indicator": "white", "wire": "green"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "radioactive", "series": "TCH_2990inkjet", "specificity": "anti_tank", "indicator": "red", "wire": "green"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "casual devastator", "series": "SWX_4000", "specificity": "anti_aircraft", "indicator": "red", "wire": "green"}
|
|
||||||
{"mine_type": "time", "danger_cls": "casual devastator", "series": "WORKHORSE_3200", "specificity": "depth_mine", "indicator": "red", "wire": "red"}
|
|
||||||
{"mine_type": "standard", "danger_cls": "cherry bomb", "series": "TCH_2990inkjet", "specificity": "fragmentation_mine", "indicator": "blue", "wire": "blue"}
|
|
||||||
{"mine_type": "chained", "danger_cls": "radioactive", "series": "WORKHORSE_3200", "specificity": "pressure_mine", "indicator": "yellow", "wire": "blue"}
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user