TL;DR

  • Código: só depois de entregar o trabalho que eu percebi que o README tava padrão.
  • Aplicação Rodando: Se ela demorar para abrir é porque o heroku derruba depois de 15min de inatividade.

Introdução

Eu sou bem orientado a projetos e é nesses projetos que eu realmente aprendo, com um contexto mais real porém com um escopo mais administrável. Eu com certeza não conseguiria aprender sobre redes neurais criando um segmentador/reconhecedor de imagem pique YOLO mas sim algo simples para modelar um conjunto de dados e rodar um treinamento que possa a princípio rodar em um tempo aceitável em CPU. Eu cheguei a fazer isso porém não gostei muito do resultado e deixei arquivado até achar uma abordagem melhor.

Nesse trabalho de Java a intenção foi bem parecida. O normal dos outros alunos é fazer um sistema de gestão de alguma coisa usando AWT e no final do trabalho ficar por isso mesmo sem um uso mais real. Provavelmente tinha outras implementações de Jogo da Velha Online, provavelmente baseadas em web (agora tem mais uma). Assim como sistemas de gestão hehe.

A arquitetura

Para dar tempo, até por que eu não fazia ideia de quanto tempo ia precisar, eu tentei deixar o escopo mais simples possível, porém funcional. Se tivesse mais tempo para investir nesse projeto provavelmente usaria websockets para atualizar o board, o problema é como fazer isso no Java e coordenar todo o processo então fiz usando uma abordagem mais simples, mas que com o que eu aprendi pode ser adaptado para websocket.

Eu tive problemas relacionados com a serialização de classes para JSON, elas simplesmente retornavam um objeto vazio, depois descobri que isso era limitação da JVM que eu estava usando (GraalVM 11 CE) e para deixar mais simples a abortagem mudei para OpenJDK 11. O banco é o bom e velho PostgreSQL. A ideia de fazer com o postgres é que a gente poderia hospedar no Heroku e ter persistência de graça. Hospedagem no Heroku tava nos planos desde o começo.

Para codar a aplicação e o frontend foi usado o Intellij. Academicos tem licença estudantil na faixa. É uma IDE com um flow muito gostoso de codar. Tudo funciona liso na maior parte do tempo. Refatoração é uma questão de arrastar o arquivo ou dar um Shift Shift Rename Enter $novo_nome Enter e o resto ela se encarrega. As sugestões de código que eu usava bastante como atalho tipo ao invés de declarar o tipo da variável eu só digito o nome, igual, o valor, volto pro começo da linha, Ctrl + ., ai tem a opção de escolher o tipo, geralmente a primeira é a ideal. O tempo de boot nem é tão longo, o segredo é usar SSD, por mais vagabundo que o SSD seja, se ele não corrompe os dados vai ser melhor que usar um HD de 5200 RPM (padrão de notebook).

image-20210522115331461

A parte de frontend foi bem direto ao ponto. Um esqueleto básico e CSS simples para a interface mais umas manhas usando DOM (getElementById FTW) para manipular e mostrar os dados. O backend manda o mesmo HTML sempre e a regra de negócio do frontend é feita totalmente pelo JS que carrega.

Para lidar com autenticação foi usado um plugin no Quarkus que basicamente usa uma das entidades JPA como dona da verdade, por isso que é necessário ter uma property marcada como @Roles na entidade de usuário. A autenticação é totalmente feita por Basic Auth, ou seja você tem que passar usuário e senha para as rotas autenticadas ou vai tomar um 401 Unauthorized.

No front o usuário e a senha ficam salvos no local storage do navegador e se o usuário deslogar ele vai simplesmente remover os valores do local storage e recarregar a página.

Hospedagem e execução

Como dito, desde a época de mundo das ideias foi-se pensado em hospedar esta aplicação no Heroku.

Por que? Por que é de graça, simples, resolve o problema, não é uma aplicação de latência crítica e fornece um banco Postgres, que é limitado mas resolve o problema.

Localmente o Quarkus quando se inicia em modo dev e tem docker instalado já sobe e configura o Postgres então é uma coisa a menos de se preocupar. A configuração em específico do banco eu vou colocar no README, mas já adiantando, é baseada nesse artigo.

image-20210522160348231

O jogo em sí

Assim como em qualquer jogo online, o jogo da velha online tem um sistema de pareamento de partidas. Bem trivial na verdade. Um usuario quando entra na tela de board chama assincronamente (usando fetch) uma rota autenticada para criar a sala, nisso ele salva o ID da sala num elemento de window e começa a buscar o novo estado do frontend dele a cada 1s. Quando a partida termina o jogador é avisado se ganhou, perdeu ou empatou por que a partida mudou estado e assincronamente é guardada a partida no histórico do banco de dados podendo ser visualizada posteriormente.

Se um usuário fica na partida o sistema está programado para esperar automaticamente por 10s, se uma partida não for encontrada ele atualiza a página automaticamente. Uma side effect dessa abordagem é que esse usuário pode acabar jogando com ele mesmo na segunda tentativa, se não houver jogadas em nenhum dos lados a partida é encerrada, como sempre, mas não é salva no histórico como partida abandonada. Se quiser brincar deixei o link do repo e da aplicação rodando na seção de TL;DR (a primeira seção).