DrinkGame รจ un gioco alcolico web-based modulare scritto in Python con Flask, pensato per animare le serate con gli amici. Grazie al sistema a plugin, puoi facilmente creare e aggiungere nuovi minigiochi personalizzati.

- ๐ฎ Sistema a Plugin: aggiungi facilmente nuovi minigiochi
- ๐ Multiplayer Real-time: comunicazione in tempo reale con WebSocket
- ๐ฒ Selezione Casuale Pesata: i giochi vengono scelti in base al peso configurato
- ๐ฅ Sistema di Lobby: crea e unisciti a stanze di gioco private
- ๐ฏ Selezione Intelligente dei Giocatori: algoritmo che bilancia la partecipazione
- ๐ณ Docker Ready: deploy rapido con Docker Compose
- ๐ฑ Responsive Design: giocabile su mobile e desktop
| git clone https://github.com/ThePlayer372-FR/DrinkGame.git
cd DrinkGame
docker compose up
|
Il gioco sarร disponibile su: http://localhost:5000
| git clone https://github.com/ThePlayer372-FR/DrinkGame.git
cd DrinkGame
pip install -r req.txt
cd src
python app.py
|
- Crea una Lobby: visita la homepage e crea una nuova stanza
- Condividi il Codice: condividi il codice della lobby con i tuoi amici
- Unisciti alla Lobby: inserisci il codice e il tuo nome
- L'Host Avvia: il primo giocatore che entra diventa host e puรฒ avviare il gioco
- Gioca: segui le istruzioni dei minigiochi che appaiono casualmente
- Continua: l'host puรฒ passare al gioco successivo con il pulsante "Avanti"
Ogni minigioco รจ un plugin indipendente collocato in src/games/plugins/NomeGioco/.
| src/
games/
plugins/
NomeGioco/
__init__.py # File vuoto
game.py # Logica del gioco
templates/
index.html # Template HTML del gioco
[assets opzionali] # JSON, immagini, etc.
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 | """Nome Gioco plugin."""
import os
from typing import Dict, Any
from manager import games_manager
from games.GamesManager import Game
from lobby.lobby import Lobby
class NomeGiocoGame(Game):
"""Descrizione del tuo gioco."""
name = "NomeGioco" # Nome univoco del gioco
weight = 1.0 # Peso per la selezione (0.0 - 1.0+)
playerCount = 1 # Numero di giocatori da selezionare
def play(self, lobby: Lobby) -> Dict[str, Any]:
"""Esegui la logica del gioco.
Args:
lobby: L'istanza della lobby
Returns:
Dictionary con 'template' e 'options'
"""
# Carica il template HTML
template_path = os.path.join(
os.path.dirname(__file__),
"templates",
"index.html"
)
with open(template_path, "r", encoding="utf-8") as f:
template = f.read()
# Puoi usare lobby.get_seed() per randomness consistente
# Puoi usare lobby.get_tmp_value() per salvare stato tra round
return {
"template": template,
"options": {
# Variabili personalizzate da passare al template
"custom_var": "valore"
}
}
# Registra il gioco
games_manager.register_game(NomeGiocoGame())
|
- Naming Convention: usa PascalCase per le classi (es.
TruthLiesGame)
- File Paths: usa sempre
os.path.join() per compatibilitร cross-platform
- Encoding: specifica sempre
encoding="utf-8" quando leggi file
- Type Hints: aggiungi type hints per migliore documentazione
- Docstrings: documenta la classe e il metodo
play()
- Error Handling: gestisci le eccezioni (specialmente per API esterne)
- Peso Ragionevole: usa pesi tra 0.1 (raro) e 1.0 (comune)
Ogni template HTML deve includere:
1
2
3
4
5
6
7
8
9
10
11
12 | <!DOCTYPE html>
<html>
<head>
{% include "headGame.html" %}
<title>Nome Gioco</title>
</head>
<body>
<!-- Il tuo contenuto qui -->
{% include "baseGame.html" %}
</body>
</html>
|
- Meta tag (charset, viewport)
- jQuery 3.6+
- Socket.IO Client
- TailwindCSS (styling)
- Connessione WebSocket automatica
- Join automatico alla lobby room
- Listener per eventi
reload
- Pulsante "Avanti" per l'host (con
id="next")
- Logica di navigazione tra giochi
I template Jinja2 ricevono automaticamente queste variabili:
| Variabile |
Tipo |
Descrizione |
players |
list[str] |
Lista dei giocatori selezionati per questo gioco |
lobbyCode |
str |
Codice identificativo della lobby |
SOCKET_URL |
str |
URL del server WebSocket |
isHost |
bool |
True se il giocatore corrente รจ l'host |
isSelected |
bool |
True se il giocatore รจ tra quelli selezionati |
**options |
dict |
Opzioni personalizzate dal metodo play() |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 | <!DOCTYPE html>
<html>
<head>
{% include "headGame.html" %}
<title>Il Mio Gioco</title>
</head>
<body class="bg-gray-900 text-white min-h-screen flex items-center justify-center">
<div class="container mx-auto p-4 text-center">
<h1 class="text-4xl font-bold mb-8">๐ฎ Il Mio Gioco</h1>
{% if isSelected %}
<div class="bg-yellow-600 p-6 rounded-lg mb-4">
<p class="text-2xl">Sei stato selezionato!</p>
<p class="mt-4">{{ custom_var }}</p>
</div>
{% else %}
<div class="bg-gray-700 p-6 rounded-lg mb-4">
<p class="text-xl">Guarda gli altri giocatori!</p>
</div>
{% endif %}
<div class="mt-8">
<p class="text-lg">Giocatori: {{ players|join(', ') }}</p>
</div>
</div>
{% include "baseGame.html" %}
</body>
</html>
|
Puoi configurare l'applicazione tramite variabili d'ambiente:
| Variabile |
Default |
Descrizione |
DEBUG |
1 (True) |
Abilita/disabilita modalitร debug |
INACTIVE_LOBBY_TIME |
3600 (1 ora) |
Timeout per lobby inattive (secondi) |
CODE_LEN |
5 |
Lunghezza codice lobby |
WEB_SOCKET_URL |
http://192.168.91.200:5000/ |
URL del server WebSocket |
Esempio con Docker Compose:
| environment:
- DEBUG=0
- CODE_LEN=6
- WEB_SOCKET_URL=http://localhost:5000/
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | src/
โโโ app.py # Applicazione Flask principale
โโโ api.py # Endpoint API REST
โโโ socket_handlers.py # Handler WebSocket
โโโ manager.py # Istanze singleton dei manager
โโโ config.py # Configurazione applicazione
โโโ utils.py # Funzioni utility
โโโ extensions.py # Estensioni Flask (SocketIO)
โโโ games/
โ โโโ GamesManager.py # Manager e base class per giochi
โ โโโ plugins/ # Directory dei plugin giochi
โโโ lobby/
โ โโโ lobby.py # Classe Lobby
โ โโโ lobbymanager.py # Manager delle lobby
โโโ templates/ # Template HTML base
|
- Singleton Pattern:
GamesManager e LobbyManager
- Plugin Architecture: caricamento dinamico dei giochi
- Abstract Base Class:
Game come interfaccia per i plugin
- WebSocket Real-time: comunicazione bidirezionale con Socket.IO
- Cards ๐ - Pesca una carta con un'azione da compiere
- Challenge โ๏ธ - Sfida tra due giocatori
- Count ๐ข - Gioco di conteggio collaborativo
- I Know ๐ง - Domande e risposte
- Impostor ๐ต๏ธ - Trova l'impostore con parole diverse
- Truth or Lies ๐คฅ - Indovina veritร o bugie
Le contribuzioni sono benvenute! Puoi contribuire con:
- ๐ฎ Nuovi minigiochi: crea plugin per nuovi giochi divertenti
- ๐ Bug fix: segnala o risolvi bug
- โจ Miglioramenti UI/UX: rendi l'esperienza piรน piacevole
- ๐ Documentazione: migliora guide e commenti
- โก Ottimizzazioni: performance e qualitร del codice
- Fai fork del repository
- Crea un branch per la tua feature (
git checkout -b feature/AmazingFeature)
- Segui le convenzioni PEP 8 per Python
- Aggiungi type hints e docstrings
- Testa le tue modifiche
- Commit con messaggi descrittivi (
git commit -m 'Add: nuovo gioco XYZ')
- Push al branch (
git push origin feature/AmazingFeature)
- Apri una Pull Request
- [ ] Segue la struttura plugin standard
- [ ] Include docstrings e type hints
- [ ] Template HTML responsive e accessibile
- [ ] Testato con diversi numeri di giocatori
- [ ] Tematicamente appropriato e divertente
- [ ] Path dei file cross-platform (
os.path.join())
| # Verifica le dipendenze
pip install -r req.txt
# Verifica la porta
lsof -i :5000
|
- Verifica che
WEB_SOCKET_URL sia configurato correttamente
- Controlla che non ci siano firewall che bloccano la porta
- Verifica che la struttura della cartella sia corretta
- Controlla i log per errori di importazione
- Assicurati che il metodo
play() restituisca il formato corretto