123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- import random
- import numpy as np
- from pathfinding.core.diagonal_movement import DiagonalMovement
- from pathfinding.core.grid import Grid
- from pathfinding.finder.a_star import AStarFinder
- from simulation.board import Board
- from simulation.logic.dumb_scouter import DumbScouter
- class SensingScouter(DumbScouter):
- def __init__(self, board, knowledge, x, y, use_diagonal=False, sight_see=-1, light_compute=True):
- DumbScouter.__init__(self, board, knowledge, x, y)
- self.use_diagonal = use_diagonal
- self.sight_see = sight_see if sight_see > 0 else 1
- self.light_compute = light_compute
- self.goal = None
- self.path = []
- def get_matrix(self, x0, y0, x1, y1):
- width = x1 - x0
- height = y1 - y0
- matrix = np.zeros((width, height))
- for y in range(height):
- for x in range(width):
- if self.board.get_blob(x0 + x, y0 + y) > 0:
- matrix[x, y] = (1 + Board.MAX_BLOB - self.board.get_blob(x0 + x, y0 + y)) * 1.5
- elif self.board.is_touched(x0 + x, y0 + y):
- matrix[x, y] = Board.MAX_BLOB * 2
- else:
- matrix[x, y] = 1
- return np.transpose(matrix)
- def choose_goal(self):
- x0, y0 = max(0, self.x - self.sight_see), max(0, self.y - self.sight_see)
- x1, y1 = min(self.board.width, self.x + self.sight_see + 1), min(self.board.height, self.y + self.sight_see + 1)
- mask = np.zeros((x1 - x0, y1 - y0), dtype=bool)
- mask[self.x - x0, self.y - y0] = True
- see = np.ma.masked_where(mask, self.board.dropped_blob[x0:x1, y0:y1])
- min_indices = np.ma.where(see == np.min(see))
- if len(min_indices[0]) == 0:
- return None
- else:
- i = np.random.randint(len(min_indices[0]))
- return min_indices[0][i] + x0, min_indices[1][i] + y0
- def best_way_to(self):
- if self.sight_see > 0:
- x0, y0 = max(0, self.x - self.sight_see), max(0, self.y - self.sight_see)
- x1, y1 = min(self.board.width, self.x + self.sight_see + 1), min(self.board.height,
- self.y + self.sight_see + 1)
- else:
- x0, y0 = 0, 0
- x1, y1 = self.board.width, self.board.height
- grid = Grid(matrix=self.get_matrix(x0, y0, x1, y1))
- start = grid.node(self.x - x0, self.y - y0)
- end = grid.node(self.goal[0] - x0, self.goal[1] - y0)
- if self.use_diagonal:
- finder = AStarFinder(diagonal_movement=DiagonalMovement.always)
- else:
- finder = AStarFinder(diagonal_movement=DiagonalMovement.never)
- self.path, runs = finder.find_path(start, end, grid)
- self.path = self.path[1:]
- for i, step in enumerate(self.path):
- self.path[i] = (step[0] + x0, step[1] + y0)
- def reached(self, goal):
- return goal is not None and self.x == goal[0] and self.y == goal[1]
- def move(self):
- # Scouter has no more goal
- if self.goal is None: #or self.board.get_blob(self.goal[0], self.goal[1]) != 0:
- self.goal = self.choose_goal()
- if self.goal[0] == self.x and self.goal[1] == self.y:
- print("Shouldn't happen")
- self.path = []
- # No goal
- if self.goal is None:
- return
- # Scouter has no more path to goal
- if len(self.path) == 0 or not self.light_compute:
- self.best_way_to()
- # No path found, search another goal next time
- if len(self.path) == 0:
- self.goal = None
- return
- new_pos = self.path[0]
- self.path = self.path[1:]
- self.x = new_pos[0]
- self.y = new_pos[1]
- # Scouter reached goal
- if self.reached(self.goal):
- self.goal = None
- self.path = []
- def reset(self):
- self.goal = None
- self.path = []
- self.x = 0
- self.y = 0
|