예제 #1
0
 def __init__(self, game):
     self.environment = None
     self.game = game
     self.dim = cfg.environment()['dim']
     self.resolution = cfg.qlearing()['resolution']
     self.alpha = cfg.qlearing()['alpha']
     self.epsilon = cfg.qlearing()['epsilon']
     self.gamma = cfg.qlearing()['gamma']
     self.LEARNING = cfg.qlearing()['learning']
     self.NEW_QTABLE = cfg.qlearing()['new_qtable']
     self.number_of_directions = cfg.qlearing()['number_of_directions']
     self.qtable = self.load_qtable()
     self.frames = 0
     self.epoch = 0
     self.max_epochs = cfg.qlearing()['max_epochs']
     self.max_frames = cfg.qlearing()['max_ticks']
     # Debug
     self.grid = cfg.qlearing()['print_grid']
     self.arrows = cfg.qlearing()['print_vectors']
     self.QDEBUG_LAYER = 0
     self.AGENT_INDEX_DEBUG = 0
     if self.arrows:
         self.ARROW_FISH_SPRITE, self.ARROW_PREDATOR_SPRITE = self.arrow_sprite(
         )
     self.stat_filename = None
     if self.LEARNING:
         self.setup_stat_file()
예제 #2
0
 def kill_all_emigrants(self):
     tolerance = cfg.environment()['border_tolerance']
     emigrants = []
     self.fish_qtree.set_mask(gen_border('top', tolerance=tolerance))
     [
         emigrants.append(emigrant) for emigrant in
         [element[2] for element in self.fish_qtree.elements()]
     ]
     self.fish_qtree.set_mask(gen_border('right', tolerance=tolerance))
     [
         emigrants.append(emigrant) for emigrant in
         [element[2] for element in self.fish_qtree.elements()]
     ]
     self.fish_qtree.set_mask(gen_border('bottom', tolerance=tolerance))
     [
         emigrants.append(emigrant) for emigrant in
         [element[2] for element in self.fish_qtree.elements()]
     ]
     self.fish_qtree.set_mask(gen_border('left', tolerance=tolerance))
     [
         emigrants.append(emigrant) for emigrant in
         [element[2] for element in self.fish_qtree.elements()]
     ]
     if cfg.qlearing()['predators_learning']:
         self.predator_qtree.set_mask(gen_border('top',
                                                 tolerance=tolerance))
         [
             emigrants.append(emigrant) for emigrant in
             [element[2] for element in self.predator_qtree.elements()]
         ]
         self.predator_qtree.set_mask(
             gen_border('right', tolerance=tolerance))
         [
             emigrants.append(emigrant) for emigrant in
             [element[2] for element in self.predator_qtree.elements()]
         ]
         self.predator_qtree.set_mask(
             gen_border('bottom', tolerance=tolerance))
         [
             emigrants.append(emigrant) for emigrant in
             [element[2] for element in self.predator_qtree.elements()]
         ]
         self.predator_qtree.set_mask(
             gen_border('left', tolerance=tolerance))
         [
             emigrants.append(emigrant) for emigrant in
             [element[2] for element in self.predator_qtree.elements()]
         ]
     [emigrant.die() for emigrant in emigrants]
예제 #3
0
def gen_border(*args, **kwargs):
    w, h = cfg.environment()['dim']
    tolerance = kwargs['tolerance']
    if 'top' in args:
        return np.array([[-tolerance, -tolerance], [w + tolerance, -tolerance],
                         [w + tolerance, tolerance], [-tolerance, tolerance]])
    elif 'right' in args:
        return np.array([[w - tolerance, -tolerance],
                         [w + tolerance, -tolerance],
                         [w + tolerance, h + tolerance],
                         [w - tolerance, h + tolerance]])
    elif 'bottom' in args:
        return np.array([[-tolerance, -tolerance + h],
                         [w + tolerance, -tolerance + h],
                         [w + tolerance, tolerance + h],
                         [-tolerance, tolerance + h]])
    elif 'left':
        return np.array([[-tolerance, -tolerance], [tolerance, -tolerance],
                         [tolerance, h + tolerance],
                         [-tolerance, h + tolerance]])
    else:
        raise NotImplemented()
예제 #4
0
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")


def resize(image: np.ndarray):
    '''Resizes boid view to fit neural network input size'''
    r = cfg.dqn_vision()['view_size']
    b_size = int(round(image.shape[0] / r))
    return block_reduce(image, block_size=(b_size, b_size), func=np.mean)


def rgb_to_normalized_gray(rgb):
    '''Normalizes and maps 3 rgb channels to 1 channel grayscale'''
    return np.dot(rgb[..., :3] / 255, [0.2989, 0.5870, 0.1140])


screen_width, screen_height = cfg.environment()['dim']


def extract_boid_view(vision_area: np.ndarray,
                      position: np.ndarray) -> torch.Tensor:
    '''Computes downsampled boid view image state'''
    vision_poly = boid_vision_poly(vision_area, position)
    return downsample_image(vision_poly)


def boid_vision_poly(vision_area: np.ndarray,
                     position: np.ndarray) -> torch.Tensor:
    '''Cutting boid reaction area from game screen'''
    screen = pg.display.get_surface()

    for point in vision_area:
예제 #5
0
def random_position():
    borders = cfg.borders()
    tolerance = cfg.environment()['border_tolerance']
    return pg.Vector2(
        scale(np.random.rand(), [0, 1], [tolerance, borders[0] - tolerance]),
        scale(np.random.rand(), [0, 1], [tolerance, borders[1] - tolerance]))
예제 #6
0
def random_velocity(magnitude):
    angle = scale(np.random.rand(), [0, 1], [0, 360])
    vec = pg.Vector2()
    vec.from_polar((magnitude, angle))
    return vec


def scale(value, old, new):
    return ((value - old[0]) / (old[1] - old[0])) * (new[1] - new[0]) + new[0]


X_AXIS_VEC = pg.Vector2(1, 0)
Y_AXIS_VEC = pg.Vector2(0, 1)
DEBUG_POSITION_COLOR = pg.Color('green')
SCREEN_WIDTH, SCREEN_HEIGHT = cfg.environment()['dim']


class Agent:
    def __init__(self, sprite: pg.Surface, position: pg.Vector2,
                 velocity: pg.Vector2, reaction_radius: float):
        self.original_sprite = sprite
        self.showable_sprite = None
        self.hitbox = None
        self.position = position
        self.velocity = velocity
        self.acceleration = pg.Vector2(0, 0)
        self.alive = True
        self.closest_target = None
        self.last_observation = None
        self.current_observation = None
예제 #7
0
        return np.array([[-tolerance, -tolerance + h],
                         [w + tolerance, -tolerance + h],
                         [w + tolerance, tolerance + h],
                         [-tolerance, tolerance + h]])
    elif 'left':
        return np.array([[-tolerance, -tolerance], [tolerance, -tolerance],
                         [tolerance, h + tolerance],
                         [-tolerance, h + tolerance]])
    else:
        raise NotImplemented()


BORDERS_NAMES = ['top', 'right', 'bottom', 'left']
TURNING_BORDERS: List[Polygon] = [
    Polygon(
        gen_border(border, tolerance=cfg.environment()['turning_tolerance']))
    for border in BORDERS_NAMES
]
SCREEN_WIDTH, SCREEN_HEIGHT = cfg.environment()['dim']


class Environment:
    def __init__(self):
        self.fishes = [Fish() for _ in range(cfg.fish_amount())]
        self.all_fishes = self.fishes
        self.predators = [Predator() for _ in range(cfg.predator_amount())]
        self.all_predators = self.predators
        self.fish_qtree = None
        self.predator_qtree = None
        self.last_states = {
            'all_fishes': self.fishes,