Projeto Simples de Machine Learning Com Python
Projeto Simples de Machine Learning Com Python
"""
NEUROEVOLUÇÃO - Machine Learning com Pygame
================================================
Criaturas com redes neurais aprendem a coletar comida
usando Algoritmo Genético + Neuroevolução.
Controles:
ESPAÇO → Pausar / Retomar
1/2/3/4 → Velocidade (1x, 2x, 5x, 10x)
R → Reiniciar simulação
Q / ESC → Sair
"""
import pygame
import numpy as np
import random
import math
import sys
N_CREATURES = 40
N_FOOD = 25
GENERATION_SECS = 12 # Segundos por geração
# Rede Neural
INPUT_SIZE = 7
HIDDEN_SIZE = 10
OUTPUT_SIZE = 2
# Evolução
MUTATION_RATE = 0.12
MUTATION_STR = 0.35
ELITE_FRAC = 0.20
# Paleta de cores
C_BG = (12, 16, 28)
C_UI = (18, 23, 42)
C_BORDER = (45, 65, 110)
C_FOOD = (60, 220, 110)
C_FOOD_GLOW = (30, 110, 55)
C_CREATURE = (80, 160, 255)
C_BEST = (255, 210, 50)
C_WORST = (80, 90, 130)
C_TEXT = (190, 205, 235)
C_DIM = (90, 105, 145)
C_CHART = (70, 210, 140)
C_ACCENT = (255, 140, 60)
def flat(self):
return [Link]([[Link](), self.b1, [Link](), self.b2])
def clone(self):
nn = NeuralNet()
[Link]([Link]().copy())
return nn
def mutate(self):
w = [Link]()
mask = [Link](len(w)) < MUTATION_RATE
w += mask * [Link](len(w)) * MUTATION_STR
[Link](w)
# ─── Criatura ─────────────────────────────────────────────────────────────────
class Creature:
R = 7
MAX_SPD = 2.8
MAX_ACC = 0.28
TRAIL_LEN = 25
# Bordas — rebater
for ax in range(2):
lo = (UI_H + self.R) if ax == 1 else self.R
hi = HEIGHT - self.R if ax == 1 else WIDTH - self.R
if [Link][ax] < lo:
[Link][ax] = lo
[Link][ax] *= -0.7
elif [Link][ax] > hi:
[Link][ax] = hi
[Link][ax] *= -0.7
[Link]([Link]())
if len([Link]) > self.TRAIL_LEN:
[Link](0)
# Rastro
for i, pt in enumerate([Link]):
alpha = i / len([Link])
tc = tuple(int(cr[c] * alpha * 0.5) for c in range(3))
[Link](surf, tc, [Link](int), max(1, int(alpha * 3)))
pi = [Link](int)
# Halo do melhor
if rank == 0:
[Link](surf, (80, 60, 20), pi, self.R + 6)
# Corpo
[Link](surf, cr, pi, self.R)
[Link](surf, (200, 220, 255), pi, self.R, 1)
# Ponteiro de direção
angle = math.atan2([Link][1], [Link][0])
tip = (pi[0] + int([Link](angle) * (self.R + 5)),
pi[1] + int([Link](angle) * (self.R + 5)))
[Link](surf, (220, 235, 255), pi, tip, 2)
# ─── Simulação Principal ──────────────────────────────────────────────────────
class Simulation:
def __init__(self):
[Link]()
[Link].set_caption("
[Link] = [Link]()
🧬
[Link] = [Link].set_mode((WIDTH, HEIGHT))
Neuroevolução — Machine Learning com Pygame")
self._reset()
def _reset(self):
[Link] = 1
[Link] = 0
self.best_history = [] # melhor fitness por geração
self.avg_history = []
[Link] = 0 # frames decorridos na geração
[Link] = 1
[Link] = False
[Link] = [Creature() for _ in range(N_CREATURES)]
[Link] = self._spawn_foods()
def _spawn_foods(self):
return [[Link]([
[Link](20, WIDTH - 20),
[Link](UI_H + 15, HEIGHT - 15)
], dtype=float) for _ in range(N_FOOD)]
[Link] = new_pop
[Link] = self._spawn_foods()
[Link] = 0
[Link] += 1
# Título
title = self.font_xl.render("NEUROEVOLUÇÃO", True, (130, 185, 255))
[Link](title, (18, 10))
sub = self.font_sm.render("Redes Neurais + Algoritmo Genético", True, C_DIM)
[Link](sub, (20, 44))
sub2 = self.font_sm.render("Criaturas evoluem para coletar comida", True,
C_DIM)
[Link](sub2, (20, 62))
ctrl = self.font_sm.render("[SPC] Pausa [1-4] Vel [R] Reset [Q] Sair", True,
(70, 90, 140))
[Link](ctrl, (20, 80))
# Stats
cur_best = max(([Link] for c in [Link]), default=0)
cur_avg = sum([Link] for c in [Link]) / N_CREATURES
t_left = max(0, GENERATION_SECS - [Link] / FPS)
stats = [
("GEN", str([Link]), C_TEXT),
("MELHOR", str(cur_best), C_BEST),
("MÉDIA", f"{cur_avg:.1f}", C_CHART),
("RECORDE",str([Link]), C_ACCENT),
("TEMPO", f"{t_left:.1f}s", C_TEXT),
("VEL", f"{[Link]}x", C_TEXT),
]
sx = 340
for i, (lbl, val, col) in enumerate(stats):
bx = sx + i * 100
l = self.font_sm.render(lbl, True, C_DIM)
v = self.font_lg.render(val, True, col)
[Link](l, (bx, 12))
[Link](v, (bx, 32))
def _draw_chart(self):
if len(self.best_history) < 2:
return
cx, cy, cw, ch = WIDTH - 180, 8, 170, 80
[Link]([Link], (20, 26, 46), (cx, cy, cw, ch), border_radius=4)
[Link]([Link], C_BORDER, (cx, cy, cw, ch), 1, border_radius=4)
maxf = max(max(self.best_history), 1)
n = min(len(self.best_history), cw // 4)
bh = self.best_history[-n:]
ah = self.avg_history[-n:]
pad = 14
def to_pt(i, v):
px = cx + int(i * (cw - 4) / max(n - 1, 1)) + 2
py = cy + ch - pad - int(v / maxf * (ch - pad - 6)) - 2
return px, py
if not [Link]:
for _ in range([Link]):
self._step()
# ── Render ─────────────────────────────────────────────
[Link](C_BG)
self._draw_food()
self._draw_ui()
# Legenda
leg = [
("● Melhor criatura", C_BEST),
("● Pior criatura", C_WORST),
("● Comida", C_FOOD),
]
for i, (txt, col) in enumerate(leg):
s = self.font_sm.render(txt, True, col)
[Link](s, (WIDTH - 185, UI_H + 10 + i * 20))
if [Link]:
ov = [Link]((WIDTH, HEIGHT - UI_H), [Link])
[Link]((0, 0, 0, 120))
msg = self.font_xl.render("⏸
[Link](ov, (0, UI_H))
PAUSADO", True, (255, 250, 200))
[Link](msg, (WIDTH // 2 - 90, HEIGHT // 2 - 16))
[Link]()
Simulation().run()