68 lines
2.1 KiB
Python
68 lines
2.1 KiB
Python
from brain import Brain
|
|
from game import Game
|
|
from vector import Point, Vector
|
|
|
|
|
|
class Dot:
|
|
def __init__(self, game: Game):
|
|
super().__init__()
|
|
|
|
self.fitness: float = 0
|
|
self.is_best: bool = False
|
|
self.alive: bool = True
|
|
self.brain: Brain = Brain(1000)
|
|
self.game: Game = game
|
|
self.pos: Point = game.start
|
|
self.vel: Vector = Vector(0, 0)
|
|
self.closest_distance: float = 1e1337
|
|
|
|
self.reached_goal: bool = False
|
|
self.reached_final_goal: bool = False
|
|
|
|
@staticmethod
|
|
def randomized(game: Game) -> 'Dot':
|
|
dot: Dot = Dot(game)
|
|
dot.brain.randomize()
|
|
return dot
|
|
|
|
def die(self):
|
|
self.alive: bool = False
|
|
|
|
def move(self):
|
|
if not self.brain.available():
|
|
self.die()
|
|
return
|
|
|
|
acc: Vector = self.brain.next_direction()
|
|
self.vel += acc
|
|
self.vel.distance = min(self.vel.distance, 5)
|
|
self.pos += self.vel.to_point()
|
|
|
|
def update(self):
|
|
if not self.alive or self.reached_goal:
|
|
return
|
|
|
|
self.move()
|
|
current_target: Point = self.game.get_current_target()
|
|
if self.brain.step >= self.game.mutation_start:
|
|
self.closest_distance: float = min(self.closest_distance, (self.pos - current_target).to_vector().distance)
|
|
|
|
if not (2 <= self.pos.x < self.game.width - 2 and 2 <= self.pos.y < self.game.height - 2):
|
|
self.die()
|
|
elif (self.pos - current_target).to_vector().distance < 5:
|
|
if self.game.goal == current_target:
|
|
self.reached_final_goal: bool = True
|
|
self.reached_goal: bool = True
|
|
elif any(obstacle.check_collision(self.pos) for obstacle in self.game.obstacles):
|
|
self.die()
|
|
|
|
def clone(self) -> 'Dot':
|
|
out: Dot = Dot(self.game)
|
|
out.brain = self.brain.clone()
|
|
return out
|
|
|
|
def calculate_fitness(self):
|
|
if self.reached_goal:
|
|
self.fitness: float = 10000 + 1 / (self.brain.step ** 2)
|
|
else:
|
|
self.fitness: float = 1 / (self.closest_distance ** 2)
|