diff --git a/assets/sounds/notmine.wav b/assets/sounds/notmine.wav new file mode 100644 index 0000000..f0a06bb Binary files /dev/null and b/assets/sounds/notmine.wav differ diff --git a/assets/sprites/mines/1.png b/assets/sprites/mines/1.png new file mode 100644 index 0000000..ff3c622 Binary files /dev/null and b/assets/sprites/mines/1.png differ diff --git a/assets/sprites/notmines/1.png b/assets/sprites/notmines/1.png new file mode 100644 index 0000000..87f6e2b Binary files /dev/null and b/assets/sprites/notmines/1.png differ diff --git a/assets/sprites/slowgrass.png b/assets/sprites/slowgrass.png new file mode 100644 index 0000000..342b91e Binary files /dev/null and b/assets/sprites/slowgrass.png differ diff --git a/classes/ai.py b/classes/ai.py index 07e2b98..5815030 100644 --- a/classes/ai.py +++ b/classes/ai.py @@ -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) diff --git a/classes/bfs.py b/classes/bfs.py index c1338a4..e1d5833 100644 --- a/classes/bfs.py +++ b/classes/bfs.py @@ -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) diff --git a/classes/minesweeper.py b/classes/minesweeper.py index cae0a8b..f42fa50 100644 --- a/classes/minesweeper.py +++ b/classes/minesweeper.py @@ -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): - difficulty = randrange(0, 4) + 1 - weight = randrange(10, 31) / 10 - timer = randrange(100, 200) - mine = Mine(j, i, self.tile_size, difficulty, weight, timer) - self.mines.append(mine) + #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, 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 - decision = tree.return_predict(model) - print("Decision : ", decision, "\n") + #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(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 - self.current_map.mines.remove(mine) - pygame.mixer.Channel(3).set_volume(0.7) - pygame.mixer.Channel(3).play(pygame.mixer.Sound("assets/sounds/pickup.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 diff --git a/main.py b/main.py index fcbd179..9323f92 100644 --- a/main.py +++ b/main.py @@ -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) diff --git a/outputs/rules/rules.json b/outputs/rules/rules.json index ebc93cd..f45276d 100644 --- a/outputs/rules/rules.json +++ b/outputs/rules/rules.json @@ -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} ] \ No newline at end of file