Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
MaxRohowsky committed May 11, 2021
0 parents commit 85cf4c0
Show file tree
Hide file tree
Showing 4 changed files with 261 additions and 0 deletions.
Binary file added Assets/oldcar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Assets/track3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
79 changes: 79 additions & 0 deletions config.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
[NEAT]
fitness_criterion = max
fitness_threshold = 10000
pop_size = 50
reset_on_extinction = False

[DefaultGenome]
# node activation options
activation_default = tanh
activation_mutate_rate = 0.0
activation_options = tanh

# node aggregation options
aggregation_default = sum
aggregation_mutate_rate = 0.0
aggregation_options = sum

# node bias options
bias_init_mean = 0.0
bias_init_stdev = 1.0
bias_max_value = 30.0
bias_min_value = -30.0
bias_mutate_power = 0.5
bias_mutate_rate = 0.7
bias_replace_rate = 0.1

# genome compatibility options
compatibility_disjoint_coefficient = 1.0
compatibility_weight_coefficient = 0.5

# connection add/remove rates
conn_add_prob = 0.5
conn_delete_prob = 0.5

# connection enable options
enabled_default = True
enabled_mutate_rate = 0.01

feed_forward = True
initial_connection = full

# node add/remove rates
node_add_prob = 0.2
node_delete_prob = 0.2

# network parameters
num_hidden = 0
num_inputs = 5
num_outputs = 2

# node response options
response_init_mean = 1.0
response_init_stdev = 0.0
response_max_value = 30.0
response_min_value = -30.0
response_mutate_power = 0.0
response_mutate_rate = 0.0
response_replace_rate = 0.0

# connection weight options
weight_init_mean = 0.0
weight_init_stdev = 1.0
weight_max_value = 30
weight_min_value = -30
weight_mutate_power = 0.5
weight_mutate_rate = 0.8
weight_replace_rate = 0.1

[DefaultSpeciesSet]
compatibility_threshold = 3.0

[DefaultStagnation]
species_fitness_func = max
max_stagnation = 20
species_elitism = 2

[DefaultReproduction]
elitism = 2
survival_threshold = 0.2
182 changes: 182 additions & 0 deletions main30.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import pygame
import os
import random
import math
import sys
import neat

pygame.init()
# Global Constants
SCREEN_WIDTH = 1244
SCREEN_HEIGHT = 1016

SCREEN = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
TRACK = pygame.image.load(os.path.join("Assets", "track3.png"))


class Car(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.original_image = pygame.image.load(os.path.join("Assets", "oldcar.png"))
self.image = self.original_image
self.rect = self.image.get_rect(center=(490, 820))
self.center = self.rect.center
self.vel_vector = pygame.math.Vector2(0.8, 0)
self.angle = 0
self.rotation_vel = 5
self.direction = 0
self.alive = True
self.radars = []

def update(self, screen):
self.radars.clear()
self.rotate(screen)
self.drive()
for radar_angle in (-60, -30, 0, 30, 60):
self.radar(SCREEN, radar_angle)
self.data()
self.collision(screen)


#print(self.radar(SCREEN, 0)[0])

def drive(self):
self.rect.center += self.vel_vector*6

def collision(self, screen):
len = 40
collision_point_right = [int(self.rect.center[0] + math.cos(math.radians(360+18-self.angle))*len),
int(self.rect.center[1] + math.sin(math.radians(360+18-self.angle))*len)]
collision_point_left = [int(self.rect.center[0] + math.cos(math.radians(360-18-self.angle))*len),
int(self.rect.center[1] + math.sin(math.radians(360-18-self.angle))*len)]

# print(screen.get_at(collision_point_right))
if screen.get_at(collision_point_right) == pygame.Color(2, 105, 31, 255) \
or screen.get_at(collision_point_left) == pygame.Color(2, 105, 31, 255):
self.alive = False
print("collision")

# Draw Collision Points - (draw this after getting the color(!) using get_at)
pygame.draw.circle(screen, (0, 255, 255, 0), collision_point_right, 4)
pygame.draw.circle(screen, (0, 255, 255, 0), collision_point_left, 4)

def rotate(self, screen):
if self.direction == 1:
self.angle -= self.rotation_vel
self.vel_vector.rotate_ip(self.rotation_vel)
if self.direction == -1:
self.angle += self.rotation_vel
self.vel_vector.rotate_ip(-self.rotation_vel)

self.image = pygame.transform.rotozoom(self.original_image, self.angle, 0.1)
self.rect = self.image.get_rect(center=self.rect.center)
# pygame.draw.rect(screen, (255, 255, 255, 255), self.rect)

def radar(self, screen, radar_angle):
length = 0
x = int(self.rect.center[0] + math.cos(math.radians(360-self.angle+radar_angle)) * length)
y = int(self.rect.center[1] + math.sin(math.radians(360-self.angle+radar_angle)) * length)

while not screen.get_at((x, y)) == pygame.Color(2, 105, 31, 255) and length < 200:
length += 1
x = int(self.rect.center[0] + math.cos(math.radians(360-self.angle+radar_angle)) * length)
y = int(self.rect.center[1] + math.sin(math.radians(360-self.angle+radar_angle)) * length)

# Draw Radar
pygame.draw.line(screen, (255, 255, 255, 255), self.rect.center, (x, y), 1)
pygame.draw.circle(screen, (0, 255, 0, 0), (x, y), 3)

dist = int(math.sqrt(math.pow(self.rect.center[0] - x, 2)
+ math.pow(self.rect.center[1] - y, 2)))

self.radars.append([radar_angle, dist])

def data(self):
radars = self.radars
input = [0, 0, 0, 0, 0]
for i, radar in enumerate(radars):
input[i] = int(radar[1])
return input


def remove(index):
cars.pop(index)
ge.pop(index)
nets.pop(index)

def eval_genomes(genomes, config):
global cars, ge, nets
clock = pygame.time.Clock()

cars = []
ge = []
nets = []

for genome_id, genome in genomes:
cars.append(pygame.sprite.GroupSingle(Car()))
ge.append(genome)
net = neat.nn.FeedForwardNetwork.create(genome, config)
nets.append(net)
genome.fitness = 0

run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()

SCREEN.blit(TRACK, (0, 0))

for car in cars:
car.update(SCREEN)
car.draw(SCREEN)

if len(cars) == 0:
break

for i, car in enumerate(cars):
ge[i].fitness += 1
if not car.sprite.alive:
remove(i)

for i, car in enumerate(cars):
print(car.sprite.data())
output = nets[i].activate(car.sprite.data())
#print(output)
if output[0] > 0.7:
car.sprite.direction = -1
if output[1] > 0.7:
car.sprite.direction = 1
if output[0] <= 0.7 and output[1] <= 0.7:
car.sprite.direction = 0

clock.tick(30)
pygame.display.update()


# Setup the NEAT Neural Network
def run(config_path):
global pop
config = neat.config.Config(
neat.DefaultGenome,
neat.DefaultReproduction,
neat.DefaultSpeciesSet,
neat.DefaultStagnation,
config_path
)

pop = neat.Population(config)

pop.add_reporter(neat.StdOutReporter(True))
stats = neat.StatisticsReporter()
pop.add_reporter(stats)

pop.run(eval_genomes, 50)


if __name__ == '__main__':
local_dir = os.path.dirname(__file__)
config_path = os.path.join(local_dir, 'config.txt')
run(config_path)

0 comments on commit 85cf4c0

Please sign in to comment.