added NotMines and few visual changes

This commit is contained in:
Bilox 2022-05-28 15:55:33 +02:00
parent 7a95cdffdc
commit 204d1ae0b1
9 changed files with 169 additions and 109 deletions

BIN
assets/sounds/notmine.wav Normal file

Binary file not shown.

BIN
assets/sprites/mines/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -82,18 +82,18 @@ class AI:
else:
self.saper.rotate(way)
self.saper.move()
elif len(self.current_map.mines)!=0:
elif len(self.current_map.encounters)!=0:
self.bfs()
def bfs(self):
dists = [] # how long way is to all mines from start([0, 0])
for mine in self.current_map.mines:
dists = [] # how long way is to all encounters from start([0, 0])
for encounter in self.current_map.encounters:
# dists.append(sqrt((self.saper.position_x-mine.position_x)**2 + (self.saper.position_y-mine.position_y)**2))
dists.append(abs(self.saper.position_x - mine.position_x) + abs(self.saper.position_y - mine.position_y))
dists.append(abs(self.saper.position_x - encounter.position_x) + abs(self.saper.position_y - encounter.position_y))
#print(dists)
ind = dists.index(min(dists)) # choose nearest mine
goal_state = [self.current_map.mines[ind].position_x, self.current_map.mines[ind].position_y]
goal_state = [self.current_map.encounters[ind].position_x, self.current_map.encounters[ind].position_y]
print(f'We go to {goal_state}')
find_path = bfs.BFS(self.saper, self.window)

View File

@ -17,116 +17,116 @@ class BFS:
if current_position[2] == 180: # jesli patrzy na polnoc
if neighbours_list[0][1] not in ['wall', 'cliff_south', 'cliff_east', 'cliff_north', 'cliff_west']:
if neighbours_list[0][1] == 'grass':
if neighbours_list[0][1] == 'slowfloor':
cost = 3
elif neighbours_list[0][1] == 'sand':
elif neighbours_list[0][1] == 'floor':
cost = 2
elif neighbours_list[0][1] == 'mine':
elif neighbours_list[0][1] == 'encounter':
cost = 0
tmp = ('forward', [current_position[0], current_position[1] - 1, 180], cost)
new_nodes.append(tmp)
if neighbours_list[1][0] not in ['wall', 'cliff_south', 'cliff_east', 'cliff_north', 'cliff_west']:
# if neighbours_list[1][0] == 'grass':
# if neighbours_list[1][0] == 'slowfloor':
# cost = 10
# elif neighbours_list[1][0] == 'sand':
# elif neighbours_list[1][0] == 'floor':
# cost = 2
# elif neighbours_list[1][0] == 'mine':
# elif neighbours_list[1][0] == 'encounter':
# cost = 0
tmp = ('left', [current_position[0], current_position[1], 270], 1)
new_nodes.append(tmp)
if neighbours_list[1][2] not in ['wall', 'cliff_south', 'cliff_east', 'cliff_north', 'cliff_west']:
# if neighbours_list[1][2] == 'grass':
# if neighbours_list[1][2] == 'slowfloor':
# cost = 10
# elif neighbours_list[1][2] == 'sand':
# elif neighbours_list[1][2] == 'floor':
# cost = 2
# elif neighbours_list[1][2] == 'mine':
# elif neighbours_list[1][2] == 'encounter':
# cost = 0
tmp = ('right', [current_position[0], current_position[1], 90], 1)
new_nodes.append(tmp)
if current_position[2] == 90: # jesli patrzy na wschod
if neighbours_list[1][2] not in ['wall', 'cliff_south', 'cliff_east', 'cliff_north', 'cliff_west']:
if neighbours_list[1][2] == 'grass':
if neighbours_list[1][2] == 'slowfloor':
cost = 3
elif neighbours_list[1][2] == 'sand':
elif neighbours_list[1][2] == 'floor':
cost = 2
elif neighbours_list[1][2] == 'mine':
elif neighbours_list[1][2] == 'encounter':
cost = 0
tmp = ('forward', [current_position[0] + 1, current_position[1], 90], cost)
new_nodes.append(tmp)
if neighbours_list[0][1] not in ['wall', 'cliff_south', 'cliff_east', 'cliff_north', 'cliff_west']:
# if neighbours_list[0][1] == 'grass':
# if neighbours_list[0][1] == 'slowfloor':
# cost = 10
# elif neighbours_list[0][1] == 'sand':
# elif neighbours_list[0][1] == 'floor':
# cost = 2
# elif neighbours_list[0][1] == 'mine':
# elif neighbours_list[0][1] == 'encounter':
# cost = 0
tmp = ('left', [current_position[0], current_position[1], 180], 1)
new_nodes.append(tmp)
if neighbours_list[2][1] not in ['wall', 'cliff_south', 'cliff_east', 'cliff_north', 'cliff_west']:
# if neighbours_list[2][1] == 'grass':
# if neighbours_list[2][1] == 'slowfloor':
# cost = 10
# elif neighbours_list[2][1] == 'sand':
# elif neighbours_list[2][1] == 'floor':
# cost = 2
# elif neighbours_list[2][1] == 'mine':
# elif neighbours_list[2][1] == 'encounter':
# cost = 0
tmp = ('right', [current_position[0], current_position[1], 0], 1)
new_nodes.append(tmp)
if current_position[2] == 0: # jesli patczy na poludzie
if neighbours_list[2][1] not in ['wall', 'cliff_south', 'cliff_east', 'cliff_north', 'cliff_west']:
if neighbours_list[2][1] == 'grass':
if neighbours_list[2][1] == 'slowfloor':
cost = 3
elif neighbours_list[2][1] == 'sand':
elif neighbours_list[2][1] == 'floor':
cost = 2
elif neighbours_list[2][1] == 'mine':
elif neighbours_list[2][1] == 'encounter':
cost = 0
tmp = ('forward', [current_position[0], current_position[1] + 1, 0], cost)
new_nodes.append(tmp)
if neighbours_list[1][2] not in ['wall', 'cliff_south', 'cliff_east', 'cliff_north', 'cliff_west']:
# if neighbours_list[1][2] == 'grass':
# if neighbours_list[1][2] == 'slowfloor':
# cost = 10
# elif neighbours_list[1][2] == 'sand':
# elif neighbours_list[1][2] == 'floor':
# cost = 2
# elif neighbours_list[1][2] == 'mine':
# elif neighbours_list[1][2] == 'encounter':
# cost = 0
tmp = ('left', [current_position[0], current_position[1], 90], 1)
new_nodes.append(tmp)
if neighbours_list[1][0] not in ['wall', 'cliff_south', 'cliff_east', 'cliff_north', 'cliff_west']:
# if neighbours_list[1][0] == 'grass':
# if neighbours_list[1][0] == 'slowfloor':
# cost = 10
# elif neighbours_list[1][0] == 'sand':
# elif neighbours_list[1][0] == 'floor':
# cost = 2
# elif neighbours_list[1][0] == 'mine':
# elif neighbours_list[1][0] == 'encounter':
# cost = 0
tmp = ('right', [current_position[0], current_position[1], 270], 1)
new_nodes.append(tmp)
if current_position[2] == 270: # jesli patczy na wschod
if neighbours_list[1][0] not in ['wall', 'cliff_south', 'cliff_east', 'cliff_north', 'cliff_west']:
if neighbours_list[1][0] == 'grass':
if neighbours_list[1][0] == 'slowfloor':
cost = 3
elif neighbours_list[1][0] == 'sand':
elif neighbours_list[1][0] == 'floor':
cost = 2
elif neighbours_list[1][0] == 'mine':
elif neighbours_list[1][0] == 'encounter':
cost = 0
tmp = ('forward', [current_position[0] - 1, current_position[1], 270], cost)
new_nodes.append(tmp)
if neighbours_list[2][1] not in ['wall', 'cliff_south', 'cliff_east', 'cliff_north', 'cliff_west']:
# if neighbours_list[2][1] == 'grass':
# if neighbours_list[2][1] == 'slowfloor':
# cost = 10
# elif neighbours_list[2][1] == 'sand':
# elif neighbours_list[2][1] == 'floor':
# cost = 2
# elif neighbours_list[2][1] == 'mine':
# elif neighbours_list[2][1] == 'encounter':
# cost = 0
tmp = ('left', [current_position[0], current_position[1], 0], 1)
new_nodes.append(tmp)
if neighbours_list[0][1] not in ['wall', 'cliff_south', 'cliff_east', 'cliff_north', 'cliff_west']:
# if neighbours_list[0][1] == 'grass':
# if neighbours_list[0][1] == 'slowfloor':
# cost = 10
# elif neighbours_list[0][1] == 'sand':
# elif neighbours_list[0][1] == 'floor':
# cost = 2
# elif neighbours_list[0][1] == 'mine':
# elif neighbours_list[0][1] == 'encounter':
# cost = 0
tmp = ('right', [current_position[0], current_position[1], 180], 1)
new_nodes.append(tmp)

View File

@ -1,3 +1,4 @@
from tkinter import EventType
import pygame
from classes import system
from random import randrange
@ -5,41 +6,61 @@ from classes import decisionTrees
pygame.mixer.init()
class NotMine():
# mina
class Mine:
position_x: int
position_y: int
size: int
ismine: bool
image: pygame.surface.Surface
font: pygame.font.Font
done_text: pygame.surface.Surface
def __init__(self, position_x, position_y, size, ismine):
self.position_x = position_x
self.position_y = position_y
self.size = size
self.ismine = ismine
self.image = pygame.image.load("assets/sprites/notmines/" + str(randrange(1, 2)) + ".png")
self.image = pygame.transform.scale(self.image, (self.size, self.size))
self.font = pygame.font.SysFont('Comic Sans MS', int(self.size * 0.3))
self.done_text = self.font.render("", False, (255,0,0))
def draw(self, window):
position_on_screen = (self.size * self.position_x, self.size * self.position_y)
window.blit(self.image, position_on_screen)
window.blit(self.done_text, (position_on_screen[0] + self.size / 4, position_on_screen[1] - self.size / 8))
class Mine():
position_x: int
position_y: int
size: int
ismine: bool
image: pygame.surface.Surface
font: pygame.font.Font
image_text: pygame.surface.Surface
timer_text: pygame.surface.Surface
diff_text: pygame.surface.Surface
timer_event: pygame.USEREVENT
font: pygame.font.Font
difficulty: int = 1
weight: float = 1.0
explosion_timer: int = 100
def __init__(self, position_x, position_y, size, difficulty=1, weight=1.0, timer=100):
def __init__(self, position_x, position_y, size, ismine, difficulty=1, weight=1.0, timer=100):
self.position_x = position_x
self.position_y = position_y
self.size = size
self.ismine = ismine
self.weight = weight
self.explosion_timer = timer
self.difficulty = difficulty
if self.difficulty == 2:
self.image = pygame.image.load("assets/sprites/mine2.png")
elif self.difficulty == 3:
self.image = pygame.image.load("assets/sprites/mine3.png")
elif self.difficulty == 4:
self.image = pygame.image.load("assets/sprites/mine4.png")
else:
self.image = pygame.image.load("assets/sprites/mine_fun_sized.png")
self.image = pygame.image.load("assets/sprites/mines/" + str(randrange(1, 2)) + ".png")
self.image = pygame.transform.scale(self.image, (self.size, self.size))
self.font = pygame.font.SysFont('Comic Sans MS', int(self.size * 0.4))
self.image_text = self.font.render(str(self.weight), False, (0, 0, 0))
self.font = pygame.font.SysFont('Comic Sans MS', int(self.size * 0.3))
self.image_text = self.font.render(str(self.weight), False, (255, 0, 0))
self.timer_text = self.font.render(str(self.explosion_timer), False, (255, 0, 0))
self.difficulty_text = self.font.render(str(self.difficulty), False, (255, 0, 0))
timer_interval = 1000
self.timer_event = pygame.USEREVENT + 1
pygame.time.set_timer(self.timer_event, timer_interval)
@ -50,6 +71,9 @@ class Mine:
window.blit(self.image, position_on_screen)
window.blit(self.image_text, (position_on_screen[0] + self.size / 4, position_on_screen[1] + self.size / 2))
window.blit(self.timer_text, (position_on_screen[0] + self.size / 4, position_on_screen[1] - self.size / 8))
window.blit(self.difficulty_text, (position_on_screen[0] + self.size / 1.5, position_on_screen[1] + self.size / 6 ))
class Cliff:
@ -94,7 +118,9 @@ class Map:
terrain_matrix: list
cliffs = []
encounters = []
mines = []
notmines = []
def __init__(self, window: system.Window, tile_size: int = 64, tiles_x: int = 8, tiles_y: int = 8):
self.window = window
@ -104,7 +130,7 @@ class Map:
# dodanie grafik wszystkich typów terenu do jednej listy
self.tile_palette = [None] * 20
image = pygame.image.load("assets/sprites/sand.png")
image = pygame.image.load("assets/sprites/grass.png")
image = pygame.transform.scale(image, (tile_size, tile_size))
self.tile_palette[0] = image
@ -112,7 +138,7 @@ class Map:
image = pygame.transform.scale(image, (tile_size, tile_size))
self.tile_palette[10] = image
image = pygame.image.load("assets/sprites/grass.png")
image = pygame.image.load("assets/sprites/slowgrass.png")
image = pygame.transform.scale(image, (tile_size, tile_size))
self.tile_palette[5] = image
@ -165,11 +191,20 @@ class Map:
ok = False
break
if ok and randrange(10) == 0 and not (i < 2 and j < 3):
#zależnie od wylosowanej liczby mina lub niemina
if randrange(0, 10) > 3:
ismine = True
difficulty = randrange(0, 4) + 1
weight = randrange(10, 31) / 10
timer = randrange(100, 200)
mine = Mine(j, i, self.tile_size, difficulty, weight, timer)
mine = Mine(j, i, self.tile_size, ismine, difficulty, weight, timer)
self.mines.append(mine)
self.encounters.append(mine)
else:
ismine = False
notmine = NotMine(j, i, self.tile_size, ismine)
self.notmines.append(notmine)
self.encounters.append(notmine)
def draw_tiles(self):
# narysowanie na ekranie terenu
@ -181,10 +216,14 @@ class Map:
def draw_objects(self):
for mine in self.mines:
mine.draw(self.window.window)
for notmine in self.notmines:
notmine.draw(self.window.window)
for cliff in self.cliffs:
cliff.draw(self.window.window)
# broń
class Weapon:
size: int
@ -368,7 +407,7 @@ class Minesweeper:
if move_legal:
if self.current_map.terrain_matrix[next_y][next_x] > 4:
self.speed = 0.5
pygame.mixer.Channel(1).set_volume(0.3)
pygame.mixer.Channel(1).set_volume(0.01) #from 0.3
pygame.mixer.Channel(1).play(pygame.mixer.Sound("assets/sounds/moving.wav"))
if dir == 0:
self.position_y += 1
@ -386,23 +425,44 @@ class Minesweeper:
self.position_x += 1
self.offset_x = -self.size
else:
pygame.mixer.Channel(2).set_volume(0.5)
pygame.mixer.Channel(2).set_volume(0.01) #from 0.5
pygame.mixer.Channel(2).play(pygame.mixer.Sound("assets/sounds/collision.wav"))
def pick_up(self, model):
if self.offset_x != 0 or self.offset_y != 0:
return
for mine in self.current_map.mines:
if (self.position_x, self.position_y) == (mine.position_x, mine.position_y):
tree = decisionTrees.DecisionTrees()
for encounter in self.current_map.encounters:
if (self.position_x, self.position_y) == (encounter.position_x, encounter.position_y):
#tutaj będzie sprawdzanie zdjęcia i na podstawie tego przypisywane true albo false do decisionismine
decisionismine = encounter.ismine
#wykryto błędnie
if decisionismine != encounter.ismine:
print("ERROR: Decision was not right")
self.current_map.encounters.clear()
break
#wykryto poprawnie, że mina
elif decisionismine:
print("Mine? - Yes")
tree = decisionTrees.DecisionTrees()
decision = tree.return_predict(model)
print("Decision : ", decision, "\n")
self.current_map.mines.remove(mine)
pygame.mixer.Channel(3).set_volume(0.7)
self.current_map.mines.remove(encounter)
self.current_map.encounters.remove(encounter)
pygame.mixer.Channel(3).set_volume(0.01) #from 0.7
pygame.mixer.Channel(3).play(pygame.mixer.Sound("assets/sounds/pickup.wav"))
break
#wykryto poprawnie, że niemina
else:
print("Mine? - No")
encounter.done_text = encounter.font.render("X", False, (255,0,0))
self.current_map.encounters.remove(encounter)
pygame.mixer.Channel(3).set_volume(0.01)
pygame.mixer.Channel(3).play(pygame.mixer.Sound("assets/sounds/notmine.wav"))
break
def drop_bombs(self):
pass
@ -427,9 +487,9 @@ class Minesweeper:
elif self.current_map.terrain_matrix[posy][posx] > 9:
sensor_list[i][j] = "wall"
elif self.current_map.terrain_matrix[posy][posx] > 4:
sensor_list[i][j] = "grass"
sensor_list[i][j] = "slowfloor"
else:
sensor_list[i][j] = "sand"
sensor_list[i][j] = "floor"
for cliff in self.current_map.cliffs:
if (posx, posy) == (cliff.position_x, cliff.position_y):
if cliff.rotation == 0:
@ -441,9 +501,9 @@ class Minesweeper:
elif cliff.rotation == 270:
sensor_list[i][j] = "cliff_west"
break
for mine in self.current_map.mines:
if (posx, posy) == (mine.position_x, mine.position_y):
sensor_list[i][j] = "mine"
for encounter in self.current_map.encounters:
if (posx, posy) == (encounter.position_x, encounter.position_y):
sensor_list[i][j] = "encounter"
break
return sensor_list

View File

@ -12,7 +12,7 @@ import pandas as pd
from classes import system, minesweeper, ai, decisionTrees
# ustalenie wielkości pojedyńczych kawałków mapy, oraz wielkości mapy
TILE_SIZE = 64
TILE_SIZE = 96
TILES_X = int(12)
TILES_Y = int(10)

View File

@ -1,31 +1,31 @@
[
{"current_level": 1, "leaf_id": "2365989b-d788-11ec-ad21-989096c0661b", "parents": "root", "rule": "else: return 'detonate'", "feature_idx": -1, "feature_name": "", "instances": 200, "metric": 0, "return_statement": 0, "tree_id": 0},
{"current_level": 1, "leaf_id": "23660db8-d788-11ec-bced-989096c0661b", "parents": "root", "rule": "if obj[4]<=80.67436609605278:", "feature_idx": 4, "feature_name": "Random_detonation_chance", "instances": 200, "metric": 0.9964625048848765, "return_statement": 0, "tree_id": 0},
{"current_level": 2, "leaf_id": "2375e9de-d788-11ec-b6b3-989096c0661b", "parents": "23660db8-d788-11ec-bced-989096c0661b", "rule": "else: return 'detonate'", "feature_idx": -1, "feature_name": "", "instances": 161, "metric": 0, "return_statement": 0, "tree_id": 0},
{"current_level": 2, "leaf_id": "23765f02-d788-11ec-a11c-989096c0661b", "parents": "23660db8-d788-11ec-bced-989096c0661b", "rule": "if obj[2]<=0:", "feature_idx": 2, "feature_name": "Protection_from_defuse", "instances": 161, "metric": 0.9203523274205176, "return_statement": 0, "tree_id": 0},
{"current_level": 3, "leaf_id": "23843fa3-d788-11ec-a4cb-989096c0661b", "parents": "23765f02-d788-11ec-a11c-989096c0661b", "rule": "else: return 'detonate'", "feature_idx": -1, "feature_name": "", "instances": 135, "metric": 0, "return_statement": 0, "tree_id": 0},
{"current_level": 3, "leaf_id": "2384dbcd-d788-11ec-9ba5-989096c0661b", "parents": "23765f02-d788-11ec-a11c-989096c0661b", "rule": "if obj[3]<=7:", "feature_idx": 3, "feature_name": "Meters_under_the_ground", "instances": 135, "metric": 0.7364977795505669, "return_statement": 0, "tree_id": 0},
{"current_level": 4, "leaf_id": "238e9e6b-d788-11ec-a378-989096c0661b", "parents": "2384dbcd-d788-11ec-9ba5-989096c0661b", "rule": "else: return 'defuse'", "feature_idx": -1, "feature_name": "", "instances": 116, "metric": 0, "return_statement": 0, "tree_id": 0},
{"current_level": 4, "leaf_id": "238f3a74-d788-11ec-9bce-989096c0661b", "parents": "2384dbcd-d788-11ec-9ba5-989096c0661b", "rule": "if obj[1]<=1997.8794790831414:", "feature_idx": 1, "feature_name": "Year(older_more_difficult)", "instances": 116, "metric": 0.3936164041111624, "return_statement": 0, "tree_id": 0},
{"current_level": 5, "leaf_id": "2396b383-d788-11ec-8968-989096c0661b", "parents": "238f3a74-d788-11ec-9bce-989096c0661b", "rule": "else: return 'defuse'", "feature_idx": -1, "feature_name": "", "instances": 97, "metric": 0, "return_statement": 0, "tree_id": 0},
{"current_level": 5, "leaf_id": "2397289c-d788-11ec-b91c-989096c0661b", "parents": "238f3a74-d788-11ec-9bce-989096c0661b", "rule": "if obj[5]<=2:", "feature_idx": 5, "feature_name": "Detonation_power_in_m", "instances": 97, "metric": 0.445693177722561, "return_statement": 0, "tree_id": 0},
{"current_level": 6, "leaf_id": "239af870-d788-11ec-bbcb-989096c0661b", "parents": "2397289c-d788-11ec-b91c-989096c0661b", "rule": "else: return 'defuse'", "feature_idx": -1, "feature_name": "", "instances": 65, "metric": 0, "return_statement": 0, "tree_id": 0},
{"current_level": 6, "leaf_id": "239b6d8d-d788-11ec-8837-989096c0661b", "parents": "2397289c-d788-11ec-b91c-989096c0661b", "rule": "if obj[0]>3:", "feature_idx": 0, "feature_name": "Size(bigger_more_difficult)", "instances": 65, "metric": 0.33352200393097664, "return_statement": 0, "tree_id": 0},
{"current_level": 7, "leaf_id": "239b9498-d788-11ec-8f14-989096c0661b", "parents": "239b6d8d-d788-11ec-8837-989096c0661b", "rule": "return 'defuse'", "feature_idx": 0, "feature_name": "Size(bigger_more_difficult)", "instances": 65, "metric": 0, "return_statement": 1, "tree_id": 0},
{"current_level": 6, "leaf_id": "239e053c-d788-11ec-9160-989096c0661b", "parents": "2397289c-d788-11ec-b91c-989096c0661b", "rule": "if obj[0]<=3:", "feature_idx": 0, "feature_name": "Size(bigger_more_difficult)", "instances": 65, "metric": 0.33352200393097664, "return_statement": 0, "tree_id": 0},
{"current_level": 7, "leaf_id": "239e053d-d788-11ec-8738-989096c0661b", "parents": "239e053c-d788-11ec-9160-989096c0661b", "rule": "return 'defuse'", "feature_idx": 0, "feature_name": "Size(bigger_more_difficult)", "instances": 65, "metric": 0, "return_statement": 1, "tree_id": 0},
{"current_level": 5, "leaf_id": "23a24a5e-d788-11ec-a4d3-989096c0661b", "parents": "238f3a74-d788-11ec-9bce-989096c0661b", "rule": "if obj[5]>2:", "feature_idx": 5, "feature_name": "Detonation_power_in_m", "instances": 97, "metric": 0.445693177722561, "return_statement": 0, "tree_id": 0},
{"current_level": 6, "leaf_id": "23a61a8f-d788-11ec-a496-989096c0661b", "parents": "23a24a5e-d788-11ec-a4d3-989096c0661b", "rule": "else: return 'defuse'", "feature_idx": -1, "feature_name": "", "instances": 32, "metric": 0, "return_statement": 0, "tree_id": 0},
{"current_level": 6, "leaf_id": "23a6b685-d788-11ec-9255-989096c0661b", "parents": "23a24a5e-d788-11ec-a4d3-989096c0661b", "rule": "if obj[0]<=7:", "feature_idx": 0, "feature_name": "Size(bigger_more_difficult)", "instances": 32, "metric": 0.6252624052234231, "return_statement": 0, "tree_id": 0},
{"current_level": 7, "leaf_id": "23a6b686-d788-11ec-ae9e-989096c0661b", "parents": "23a6b685-d788-11ec-9255-989096c0661b", "rule": "return 'defuse'", "feature_idx": 0, "feature_name": "Size(bigger_more_difficult)", "instances": 32, "metric": 0, "return_statement": 1, "tree_id": 0},
{"current_level": 6, "leaf_id": "23a90020-d788-11ec-9c68-989096c0661b", "parents": "23a24a5e-d788-11ec-a4d3-989096c0661b", "rule": "if obj[0]>7:", "feature_idx": 0, "feature_name": "Size(bigger_more_difficult)", "instances": 32, "metric": 0.6252624052234231, "return_statement": 0, "tree_id": 0},
{"current_level": 7, "leaf_id": "23a90021-d788-11ec-9a09-989096c0661b", "parents": "23a90020-d788-11ec-9c68-989096c0661b", "rule": "return 'defuse'", "feature_idx": 0, "feature_name": "Size(bigger_more_difficult)", "instances": 32, "metric": 0, "return_statement": 1, "tree_id": 0},
{"current_level": 4, "leaf_id": "23aef2b5-d788-11ec-a1db-989096c0661b", "parents": "2384dbcd-d788-11ec-9ba5-989096c0661b", "rule": "if obj[1]>1997.8794790831414:", "feature_idx": 1, "feature_name": "Year(older_more_difficult)", "instances": 116, "metric": 0.3936164041111624, "return_statement": 0, "tree_id": 0},
{"current_level": 5, "leaf_id": "23aef2b6-d788-11ec-b971-989096c0661b", "parents": "23aef2b5-d788-11ec-a1db-989096c0661b", "rule": "return 'defuse'", "feature_idx": 1, "feature_name": "Year(older_more_difficult)", "instances": 116, "metric": 0, "return_statement": 1, "tree_id": 0},
{"current_level": 3, "leaf_id": "23b2e9bf-d788-11ec-b73d-989096c0661b", "parents": "23765f02-d788-11ec-a11c-989096c0661b", "rule": "if obj[3]>7:", "feature_idx": 3, "feature_name": "Meters_under_the_ground", "instances": 135, "metric": 0.7364977795505669, "return_statement": 0, "tree_id": 0},
{"current_level": 4, "leaf_id": "23b2e9c0-d788-11ec-82d9-989096c0661b", "parents": "23b2e9bf-d788-11ec-b73d-989096c0661b", "rule": "return 'detonate'", "feature_idx": 3, "feature_name": "Meters_under_the_ground", "instances": 135, "metric": 0, "return_statement": 1, "tree_id": 0},
{"current_level": 2, "leaf_id": "23b6e0c5-d788-11ec-8b0a-989096c0661b", "parents": "23660db8-d788-11ec-bced-989096c0661b", "rule": "if obj[2]>0:", "feature_idx": 2, "feature_name": "Protection_from_defuse", "instances": 161, "metric": 0.9203523274205176, "return_statement": 0, "tree_id": 0},
{"current_level": 3, "leaf_id": "23b6e0c6-d788-11ec-a0d1-989096c0661b", "parents": "23b6e0c5-d788-11ec-8b0a-989096c0661b", "rule": "return 'detonate'", "feature_idx": 2, "feature_name": "Protection_from_defuse", "instances": 161, "metric": 0, "return_statement": 1, "tree_id": 0},
{"current_level": 1, "leaf_id": "23bad7d9-d788-11ec-bd81-989096c0661b", "parents": "root", "rule": "if obj[4]>80.67436609605278:", "feature_idx": 4, "feature_name": "Random_detonation_chance", "instances": 200, "metric": 0.9964625048848765, "return_statement": 0, "tree_id": 0},
{"current_level": 2, "leaf_id": "23bad7da-d788-11ec-a18d-989096c0661b", "parents": "23bad7d9-d788-11ec-bd81-989096c0661b", "rule": "return 'detonate'", "feature_idx": 4, "feature_name": "Random_detonation_chance", "instances": 200, "metric": 0, "return_statement": 1, "tree_id": 0}
{"current_level": 1, "leaf_id": "657140df-de8d-11ec-9c63-d43d7ef1576e", "parents": "root", "rule": "else: return 'detonate'", "feature_idx": -1, "feature_name": "", "instances": 200, "metric": 0, "return_statement": 0, "tree_id": 0},
{"current_level": 1, "leaf_id": "6572790a-de8d-11ec-ac91-d43d7ef1576e", "parents": "root", "rule": "if obj[4]<=80.67436609605278:", "feature_idx": 4, "feature_name": "Random_detonation_chance", "instances": 200, "metric": 0.9964625048848765, "return_statement": 0, "tree_id": 0},
{"current_level": 2, "leaf_id": "6581b986-de8d-11ec-9198-d43d7ef1576e", "parents": "6572790a-de8d-11ec-ac91-d43d7ef1576e", "rule": "else: return 'detonate'", "feature_idx": -1, "feature_name": "", "instances": 161, "metric": 0, "return_statement": 0, "tree_id": 0},
{"current_level": 2, "leaf_id": "6582f1e8-de8d-11ec-9c53-d43d7ef1576e", "parents": "6572790a-de8d-11ec-ac91-d43d7ef1576e", "rule": "if obj[2]<=0:", "feature_idx": 2, "feature_name": "Protection_from_defuse", "instances": 161, "metric": 0.9203523274205176, "return_statement": 0, "tree_id": 0},
{"current_level": 3, "leaf_id": "65905ed3-de8d-11ec-b36a-d43d7ef1576e", "parents": "6582f1e8-de8d-11ec-9c53-d43d7ef1576e", "rule": "else: return 'detonate'", "feature_idx": -1, "feature_name": "", "instances": 135, "metric": 0, "return_statement": 0, "tree_id": 0},
{"current_level": 3, "leaf_id": "659196b8-de8d-11ec-b5e3-d43d7ef1576e", "parents": "6582f1e8-de8d-11ec-9c53-d43d7ef1576e", "rule": "if obj[3]<=7:", "feature_idx": 3, "feature_name": "Meters_under_the_ground", "instances": 135, "metric": 0.7364977795505669, "return_statement": 0, "tree_id": 0},
{"current_level": 4, "leaf_id": "659b5a72-de8d-11ec-af31-d43d7ef1576e", "parents": "659196b8-de8d-11ec-b5e3-d43d7ef1576e", "rule": "else: return 'defuse'", "feature_idx": -1, "feature_name": "", "instances": 116, "metric": 0, "return_statement": 0, "tree_id": 0},
{"current_level": 4, "leaf_id": "659c924b-de8d-11ec-ba5c-d43d7ef1576e", "parents": "659196b8-de8d-11ec-b5e3-d43d7ef1576e", "rule": "if obj[1]<=1997.8794790831414:", "feature_idx": 1, "feature_name": "Year(older_more_difficult)", "instances": 116, "metric": 0.3936164041111624, "return_statement": 0, "tree_id": 0},
{"current_level": 5, "leaf_id": "65a396a0-de8d-11ec-a956-d43d7ef1576e", "parents": "659c924b-de8d-11ec-ba5c-d43d7ef1576e", "rule": "else: return 'defuse'", "feature_idx": -1, "feature_name": "", "instances": 97, "metric": 0, "return_statement": 0, "tree_id": 0},
{"current_level": 5, "leaf_id": "65a4a8a9-de8d-11ec-8c86-d43d7ef1576e", "parents": "659c924b-de8d-11ec-ba5c-d43d7ef1576e", "rule": "if obj[5]<=2:", "feature_idx": 5, "feature_name": "Detonation_power_in_m", "instances": 97, "metric": 0.445693177722561, "return_statement": 0, "tree_id": 0},
{"current_level": 6, "leaf_id": "65a851b0-de8d-11ec-ad73-d43d7ef1576e", "parents": "65a4a8a9-de8d-11ec-8c86-d43d7ef1576e", "rule": "else: return 'defuse'", "feature_idx": -1, "feature_name": "", "instances": 65, "metric": 0, "return_statement": 0, "tree_id": 0},
{"current_level": 6, "leaf_id": "65a9899b-de8d-11ec-af58-d43d7ef1576e", "parents": "65a4a8a9-de8d-11ec-8c86-d43d7ef1576e", "rule": "if obj[0]>3:", "feature_idx": 0, "feature_name": "Size(bigger_more_difficult)", "instances": 65, "metric": 0.33352200393097664, "return_statement": 0, "tree_id": 0},
{"current_level": 7, "leaf_id": "65a9899c-de8d-11ec-a96c-d43d7ef1576e", "parents": "65a9899b-de8d-11ec-af58-d43d7ef1576e", "rule": "return 'defuse'", "feature_idx": 0, "feature_name": "Size(bigger_more_difficult)", "instances": 65, "metric": 0, "return_statement": 1, "tree_id": 0},
{"current_level": 6, "leaf_id": "65abfae1-de8d-11ec-aaaa-d43d7ef1576e", "parents": "65a4a8a9-de8d-11ec-8c86-d43d7ef1576e", "rule": "if obj[0]<=3:", "feature_idx": 0, "feature_name": "Size(bigger_more_difficult)", "instances": 65, "metric": 0.33352200393097664, "return_statement": 0, "tree_id": 0},
{"current_level": 7, "leaf_id": "65abfae2-de8d-11ec-8f35-d43d7ef1576e", "parents": "65abfae1-de8d-11ec-aaaa-d43d7ef1576e", "rule": "return 'defuse'", "feature_idx": 0, "feature_name": "Size(bigger_more_difficult)", "instances": 65, "metric": 0, "return_statement": 1, "tree_id": 0},
{"current_level": 5, "leaf_id": "65b06753-de8d-11ec-9af2-d43d7ef1576e", "parents": "659c924b-de8d-11ec-ba5c-d43d7ef1576e", "rule": "if obj[5]>2:", "feature_idx": 5, "feature_name": "Detonation_power_in_m", "instances": 97, "metric": 0.445693177722561, "return_statement": 0, "tree_id": 0},
{"current_level": 6, "leaf_id": "65b41086-de8d-11ec-b9c3-d43d7ef1576e", "parents": "65b06753-de8d-11ec-9af2-d43d7ef1576e", "rule": "else: return 'defuse'", "feature_idx": -1, "feature_name": "", "instances": 32, "metric": 0, "return_statement": 0, "tree_id": 0},
{"current_level": 6, "leaf_id": "65b548ec-de8d-11ec-8daf-d43d7ef1576e", "parents": "65b06753-de8d-11ec-9af2-d43d7ef1576e", "rule": "if obj[0]<=7:", "feature_idx": 0, "feature_name": "Size(bigger_more_difficult)", "instances": 32, "metric": 0.6252624052234231, "return_statement": 0, "tree_id": 0},
{"current_level": 7, "leaf_id": "65b548ed-de8d-11ec-a6f9-d43d7ef1576e", "parents": "65b548ec-de8d-11ec-8daf-d43d7ef1576e", "rule": "return 'defuse'", "feature_idx": 0, "feature_name": "Size(bigger_more_difficult)", "instances": 32, "metric": 0, "return_statement": 1, "tree_id": 0},
{"current_level": 6, "leaf_id": "65b792b4-de8d-11ec-ae1b-d43d7ef1576e", "parents": "65b06753-de8d-11ec-9af2-d43d7ef1576e", "rule": "if obj[0]>7:", "feature_idx": 0, "feature_name": "Size(bigger_more_difficult)", "instances": 32, "metric": 0.6252624052234231, "return_statement": 0, "tree_id": 0},
{"current_level": 7, "leaf_id": "65b792b5-de8d-11ec-8bb4-d43d7ef1576e", "parents": "65b792b4-de8d-11ec-ae1b-d43d7ef1576e", "rule": "return 'defuse'", "feature_idx": 0, "feature_name": "Size(bigger_more_difficult)", "instances": 32, "metric": 0, "return_statement": 1, "tree_id": 0},
{"current_level": 4, "leaf_id": "65be48e0-de8d-11ec-b4ae-d43d7ef1576e", "parents": "659196b8-de8d-11ec-b5e3-d43d7ef1576e", "rule": "if obj[1]>1997.8794790831414:", "feature_idx": 1, "feature_name": "Year(older_more_difficult)", "instances": 116, "metric": 0.3936164041111624, "return_statement": 0, "tree_id": 0},
{"current_level": 5, "leaf_id": "65be48e1-de8d-11ec-9136-d43d7ef1576e", "parents": "65be48e0-de8d-11ec-b4ae-d43d7ef1576e", "rule": "return 'defuse'", "feature_idx": 1, "feature_name": "Year(older_more_difficult)", "instances": 116, "metric": 0, "return_statement": 1, "tree_id": 0},
{"current_level": 3, "leaf_id": "65c2b4d6-de8d-11ec-89c3-d43d7ef1576e", "parents": "6582f1e8-de8d-11ec-9c53-d43d7ef1576e", "rule": "if obj[3]>7:", "feature_idx": 3, "feature_name": "Meters_under_the_ground", "instances": 135, "metric": 0.7364977795505669, "return_statement": 0, "tree_id": 0},
{"current_level": 4, "leaf_id": "65c2b4d7-de8d-11ec-8575-d43d7ef1576e", "parents": "65c2b4d6-de8d-11ec-89c3-d43d7ef1576e", "rule": "return 'detonate'", "feature_idx": 3, "feature_name": "Meters_under_the_ground", "instances": 135, "metric": 0, "return_statement": 1, "tree_id": 0},
{"current_level": 2, "leaf_id": "65c72151-de8d-11ec-adc4-d43d7ef1576e", "parents": "6572790a-de8d-11ec-ac91-d43d7ef1576e", "rule": "if obj[2]>0:", "feature_idx": 2, "feature_name": "Protection_from_defuse", "instances": 161, "metric": 0.9203523274205176, "return_statement": 0, "tree_id": 0},
{"current_level": 3, "leaf_id": "65c72152-de8d-11ec-8a44-d43d7ef1576e", "parents": "65c72151-de8d-11ec-adc4-d43d7ef1576e", "rule": "return 'detonate'", "feature_idx": 2, "feature_name": "Protection_from_defuse", "instances": 161, "metric": 0, "return_statement": 1, "tree_id": 0},
{"current_level": 1, "leaf_id": "65cb8dc2-de8d-11ec-b823-d43d7ef1576e", "parents": "root", "rule": "if obj[4]>80.67436609605278:", "feature_idx": 4, "feature_name": "Random_detonation_chance", "instances": 200, "metric": 0.9964625048848765, "return_statement": 0, "tree_id": 0},
{"current_level": 2, "leaf_id": "65cb8dc3-de8d-11ec-a99c-d43d7ef1576e", "parents": "65cb8dc2-de8d-11ec-b823-d43d7ef1576e", "rule": "return 'detonate'", "feature_idx": 4, "feature_name": "Random_detonation_chance", "instances": 200, "metric": 0, "return_statement": 1, "tree_id": 0}
]