diff --git a/app/games/flappy-bird-py/PythonFlappyBird.css b/app/games/flappy-bird-py/PythonFlappyBird.css index 431ea15..487b0cc 100644 --- a/app/games/flappy-bird-py/PythonFlappyBird.css +++ b/app/games/flappy-bird-py/PythonFlappyBird.css @@ -1,11 +1,14 @@ +/* === Reset e Fonte === */ body { margin: 0; font-family: "Poppins", sans-serif; background-color: #121212; color: #e0e0e0; min-height: 100vh; + overflow-x: hidden; } +/* === Layout Principal === */ .page-container { min-height: 100vh; display: flex; @@ -24,25 +27,78 @@ body { animation: fadeIn 0.5s ease-in; } +/* === Cabeçalho === */ .header { border-bottom: 1px solid #333; padding-bottom: 1rem; margin-bottom: 2rem; - text-align: center; + display: flex; + flex-direction: column; + align-items: center; + gap: 1rem; } .header h1 { font-size: 2rem; font-weight: 700; color: #00b4ff; - margin-bottom: 0.5rem; + margin: 0 0 1rem 0; + text-align: center; + overflow-wrap: anywhere; + word-break: break-word; + width: 100%; } .header p { color: #aaa; - font-size: 0.95rem; + font-size: 1.2rem; + line-height: 1.6; +} + +/* === Header flex com vídeo à esquerda e texto à direita === */ +.header-content { + display: flex; + align-items: center; + justify-content: space-between; + gap: 2rem; + flex-wrap: wrap; + width: 100%; +} + +.text-content { + flex: 1 1 60%; + display: flex; + flex-direction: column; + gap: 0.5rem; + text-align: left; +} + +.small-video { + flex: 0 0 35%; + text-align: left; +} + +.small-video video { + width: 100%; + max-width: 250px; + border-radius: 10px; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.6); + transition: transform 0.3s ease; +} + +.small-video video:hover { + transform: scale(1.05); +} + +.small-video .caption { + font-size: 0.8rem; + color: #999; + text-align: left; + margin-top: 0.4rem; + font-style: italic; } +/* === Seções === */ .section { margin-bottom: 2rem; } @@ -73,6 +129,7 @@ body { margin-top: 0.5rem; } +/* === Código === */ .section pre { background-color: #2a2a2a; border-radius: 8px; @@ -84,6 +141,7 @@ body { box-shadow: inset 0 0 5px rgba(255, 255, 255, 0.1); } +/* === Download Section === */ .download-section { text-align: center; margin-top: 2rem; @@ -103,12 +161,12 @@ body { } .download-button:hover { - background-color: #009Afc; - color: #f0f0f0f0; - + background-color: #009afc; + color: #f0f0f0; transform: translateY(-2px); } +/* === Rodapé === */ .footer { border-top: 1px solid #333; margin-top: 2rem; @@ -118,6 +176,7 @@ body { color: #888; } +/* === Listas Estilizadas === */ .section ul, .section ol { padding-left: 1.8rem; @@ -168,7 +227,77 @@ body { top: 0; } -/* Animação */ +/* === Imagens === */ +.media-box.flex-image-right { + display: grid; + grid-template-columns: 60% 30%; + align-items: center; + gap: 1.5rem; + margin: 1.5rem 0; +} + +.media-text { + text-align: left; + display: flex; + align-items: center; + min-height: 100px; + padding: 0 0.5rem; +} + +.media-img { + display: flex; + flex-direction: column; + align-items: flex-end; + min-width: 120px; +} + +.media-img img { + width: 100%; + max-width: 320px; + border-radius: 12px; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.6); + transition: transform 0.3s ease; +} + +.media-img img:hover { + transform: scale(1.02); +} + +.media-img .caption { + font-size: 0.9rem; + color: #aaa; + margin-top: 0.4rem; + font-style: italic; + text-align: right; +} + +/* === Figure-specific sizing adjustments === */ +.media-img.figure-3 img { + max-width: 420px; +} + +.media-img.figure-6 img { + max-width: 520px; +} + +.media-box { + text-align: center; + margin: 1.5rem 0; +} + +.media-box img { + width: 90%; + max-width: 700px; + border-radius: 12px; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.6); + transition: transform 0.3s ease; +} + +.media-box img:hover { + transform: scale(1.02); +} + +/* === Animação === */ @keyframes fadeIn { from { opacity: 0; @@ -179,4 +308,99 @@ body { opacity: 1; transform: translateY(0); } +} + +/* === Responsividade === */ +@media (max-width: 900px) { + .media-box.flex-image-right { + grid-template-columns: 1fr 1fr; + } + + .media-img img { + max-width: 220px; + } + + .media-img.figure-3 img { + max-width: 300px; + } + + .media-img.figure-6 img { + max-width: 360px; + } +} + +@media (max-width: 750px) { + .header-content { + flex-direction: column; + align-items: center; + text-align: center; + } + + .small-video { + text-align: center; + margin-bottom: 1rem; + flex: 1 1 100%; + } + + .text-content { + flex: 1 1 100%; + text-align: center; + } + + .media-box.flex-image-right { + display: flex; + flex-direction: column; + align-items: center; + gap: 1rem; + } + + .media-text, + .text-content { + text-align: center; + width: 100%; + min-height: auto; + padding: 0 0.5rem; + } + + .media-img { + align-items: center; + width: 100%; + } + + .media-img img { + max-width: 90vw; + } + + .media-img .caption { + text-align: center; + } + + .small-video video { + max-width: 250px; + } + + .header h1 { + font-size: clamp(1.1rem, 4.5vw, 1.6rem); + } +} + +.back-button { + position: fixed; + top: 20px; + left: 50px; + z-index: 9999; + padding: 0.5rem 0.8rem; + border-radius: 8px; + background: rgba(0, 180, 255, 0.08); + border: 1px solid rgba(0, 180, 255, 0.12); + color: #00b4ff; + font-weight: 500; + cursor: pointer; + transition: all 0.3s ease; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); +} + +.back-button:hover { + background: rgba(0, 180, 255, 0.15); + transform: translateY(-2px); } \ No newline at end of file diff --git a/app/games/flappy-bird-py/PythonFlappyBird.tsx b/app/games/flappy-bird-py/PythonFlappyBird.tsx index 089eaa1..7ff822f 100644 --- a/app/games/flappy-bird-py/PythonFlappyBird.tsx +++ b/app/games/flappy-bird-py/PythonFlappyBird.tsx @@ -1,4 +1,5 @@ import type { JSX } from "react"; +import { Link } from "react-router-dom"; import "./PythonFlappyBird.css"; export default function PythonFlappyBird(): JSX.Element { @@ -7,12 +8,32 @@ export default function PythonFlappyBird(): JSX.Element {
{/* Cabeçalho */}
-

Como funciona a IA que aprende a jogar Flappy Bird

-

- Neste projeto, demonstramos como uma inteligência artificial aprende a jogar Flappy Bird utilizando redes neurais combinadas com algoritmos evolutivos (NEAT). - Durante várias gerações, os pássaros virtuais aprendem a saltar na hora certa, evitando obstáculos, até que se tornem capazes de voar por longos períodos sem colidir. - Todo o processo envolve evolução progressiva, seleção natural simulada e adaptação baseada em desempenho. -

+
+ ← Voltar +

Como funciona a IA que aprende a jogar Flappy Bird

+
+
+
+
+

+ Neste projeto, demonstramos como uma inteligência artificial aprende a jogar Flappy Bird utilizando + redes neurais combinadas com + algoritmos evolutivos (NEAT). +

+

+ Durante várias gerações, os pássaros virtuais aprendem a saltar na hora certa, evitando obstáculos, + até que se tornem capazes de voar por longos períodos sem colidir. + Todo o processo envolve evolução progressiva, seleção natural simulada e adaptação baseada em desempenho. +

+
+ +
+ +
+ +

Vídeo — Comunicação entre o jogo e o algoritmo NEAT.

+
+
{/* 1. Estrutura geral do sistema */} @@ -81,6 +102,17 @@ export default function PythonFlappyBird(): JSX.Element {

A rede neural processa esses valores e gera uma saída, que determina se o pássaro deve pular. Com a evolução, a IA aprende padrões complexos, antecipando obstáculos e reagindo rapidamente a mudanças de altura.

+
+
+

+ A rede neural processa esses valores e gera uma saída, que determina se o pássaro deve pular. Com a evolução, a IA aprende padrões complexos, antecipando obstáculos e reagindo rapidamente a mudanças de altura. +

+
+
+ Diagrama ilustrando os três inputs usados pela rede (altura do pássaro e distâncias superior e inferior do cano). +

Figura 2 — Diagrama dos três inputs usados pela rede neural (altura do pássaro e distâncias ao cano).

+
+
{/* 3. Estrutura da Rede Neural */} @@ -105,7 +137,7 @@ export default function PythonFlappyBird(): JSX.Element {

Como a decisão é calculada:

- Cada input é multiplicado por seu peso correspondente, somado a um bias e processado por uma função de ativação (tanh). O resultado contínuo é convertido em ação: + Cada input é multiplicado por seu peso correspondente, somado a um bias e processado por uma função de ativação (tanh). Sem o bias, a saída seria sempre zero se todas as entradas forem zero (dependendo da função de ativação). O bias desloca a função para cima ou para baixo, dando mais flexibilidade à rede para aprender padrões. O resultado contínuo é convertido em ação:

                         {`input_y = 30
@@ -126,6 +158,25 @@ Se output ≤ 0.5 → NÃO PULA`}
                     

Resumindo, a rede neural transforma informações do ambiente em decisões concretas (pular ou não) e sua estrutura evolui automaticamente para melhorar a performance da IA ao longo do tempo.

+
+
+

+ O NEAT permite que a topologia da rede evolua: adicionar ou remover nós e conexões, ajustando pesos e biases para aumentar a eficiência e maximizar a pontuação. + Resumindo, a rede neural transforma informações do ambiente em decisões concretas (pular ou não) e sua estrutura evolui automaticamente para melhorar a performance da IA ao longo do tempo. +

+
+
+
+
+

+ Exemplo visual do algoritmo NEAT em ação, mostrando a evolução das conexões e nós ao longo das gerações. +

+
+
+ Exemplo de evolução de topologia de rede pelo NEAT, mostrando nós e conexões sendo alterados ao longo das gerações. +

Figura 3 — Exemplo da evolução da topologia de redes com NEAT (nós e conexões).

+
+
{/* 4. Algoritmo Evolutivo (NEAT) */} @@ -175,6 +226,17 @@ Se output ≤ 0.5 → NÃO PULA`}

No código, classes como Population, Genome e o método pop.run(main, 100) controlam o processo, executando o jogo por 100 gerações ou até atingir fitness máximo.

+
+
+

+ Ilustração do processo de seleção natural no NEAT, onde apenas os melhores indivíduos passam seus genes para a próxima geração. +

+
+
+ Ilustração do processo de seleção no NEAT mostrando indivíduos escolhidos para reprodução com base no fitness. +

Figura 4 — Processo de seleção no NEAT (indivíduos selecionados para reprodução).

+
+
{/* 5. Comparação entre RNA e Algoritmo Genético */} @@ -217,6 +279,18 @@ Se output ≤ 0.5 → NÃO PULA`}

Em resumo, a rede neural determina o comportamento do pássaro, enquanto o NEAT seleciona, mistura e evolui essas redes, permitindo aprendizado contínuo e estratégias cada vez mais eficientes.

+ +
+
+

+ Resultado final: IA dominando o jogo após várias gerações, atingindo alta pontuação e desempenho consistente. +

+
+
+ Gráfico mostrando a IA alcançando alta pontuação após várias gerações de treinamento. +

Figura 5 — Resultado final: IA dominando o jogo após várias gerações.

+
+
{/* 6. Download e execução */} @@ -256,7 +330,6 @@ venv\\Scripts\\activate # Windows`} Estrutura mínima do projeto:
                                 {`/assets
-/config
 /src
   └── /game
        └── FlappyBird.py
@@ -281,6 +354,17 @@ requirements.txt`}
                             

Esses dados permitem acompanhar a evolução da IA em tempo real.

+
+
+

+ Exemplo de logs e métricas exibidas durante a execução do treinamento, permitindo acompanhar a evolução da IA em tempo real. +

+
+
+ Captura de tela de logs e métricas exibidas durante o treinamento (média de fitness, melhor da geração). +

Figura 6 — Logs e métricas exibidas durante o treinamento (fitness, melhor da geração).

+
+
diff --git a/public/PythonFlappyBird/FlappyBirdAI.zip b/public/PythonFlappyBird/FlappyBirdAI.zip index cc4dfe4..7187d9f 100644 Binary files a/public/PythonFlappyBird/FlappyBirdAI.zip and b/public/PythonFlappyBird/FlappyBirdAI.zip differ diff --git a/public/PythonFlappyBird/flappy-bird-py-gif.mp4 b/public/PythonFlappyBird/flappy-bird-py-gif.mp4 new file mode 100644 index 0000000..c721e35 Binary files /dev/null and b/public/PythonFlappyBird/flappy-bird-py-gif.mp4 differ diff --git a/public/PythonFlappyBird/highScore.png b/public/PythonFlappyBird/highScore.png new file mode 100644 index 0000000..35ab99f Binary files /dev/null and b/public/PythonFlappyBird/highScore.png differ diff --git a/public/PythonFlappyBird/input.png b/public/PythonFlappyBird/input.png new file mode 100644 index 0000000..81c2d01 Binary files /dev/null and b/public/PythonFlappyBird/input.png differ diff --git a/public/PythonFlappyBird/logs.png b/public/PythonFlappyBird/logs.png new file mode 100644 index 0000000..ee55fa5 Binary files /dev/null and b/public/PythonFlappyBird/logs.png differ diff --git a/public/PythonFlappyBird/neat.jpg b/public/PythonFlappyBird/neat.jpg new file mode 100644 index 0000000..efa99d4 Binary files /dev/null and b/public/PythonFlappyBird/neat.jpg differ diff --git a/public/PythonFlappyBird/selection.png b/public/PythonFlappyBird/selection.png new file mode 100644 index 0000000..a058a5a Binary files /dev/null and b/public/PythonFlappyBird/selection.png differ