Perché il burraco, e perché da zero
Il burraco è tra i giochi di carte più cercati online in Italia, ma l'offerta gratuita di qualità è scarsa: molti siti richiedono un account solo per iniziare, altri puntano dritti al multiplayer a pagamento, altri ancora sono pieni di banner che rendono la partita illeggibile su mobile. Volevo l'opposto — apri la pagina, il computer mischia le carte, giochi. Come per gli altri giochi di roversia.it, tutto scritto in JavaScript vanilla: nessuna libreria di carte, nessun engine, solo DOM, CSS e la logica di gioco.
La parte interessante non è l'interfaccia — carte, animazioni, layout sono lavoro meccanico — ma le regole stesse. Il burraco ha una combinazione di vincoli che sembrano semplici finché non li devi tradurre in codice che deve funzionare sempre, anche nei casi limite: quante scale si possono formare con due jolly agli estremi, quando si può aprire il pozzetto, cosa succede se nessuno chiude e il mazzo finisce.
Why burraco, and why from scratch
Burraco is among the most searched card games online in Italy, yet good free options are scarce: many sites require an account just to start, others push straight toward paid multiplayer, others are so full of banners the match becomes unreadable on mobile. I wanted the opposite — open the page, the computer shuffles, you play. Like the other games on roversia.it, it's all vanilla JavaScript: no card library, no engine, just DOM, CSS, and game logic.
The interesting part isn't the interface — cards, animations, layout are mechanical work — but the rules themselves. Burraco has a set of constraints that look simple until you have to turn them into code that must always work, including the edge cases: how many runs can form with two wildcards at the ends, when the pot can be opened, what happens if nobody closes and the deck runs out.
Validare tris e scale, jolly compresi
Le due combinazioni valide sono il tris (3 o più carte dello stesso valore) e la scala (3 o più carte in sequenza dello stesso seme). I 2 e le pinelle sono jolly e sostituiscono qualsiasi carta in entrambe. Per il tris la regola è diretta: separo carte reali e jolly, verifico che le reali abbiano tutte lo stesso valore, e impongo che i jolly non superino il numero di carte reali — altrimenti il tris diventerebbe "quasi tutto jolly", cosa che le regole classiche non ammettono.
La scala è più delicata. Prendo le carte reali dello stesso seme, calcolo lo span tra il valore minimo e massimo, e i "buchi" interni che restano da riempire sono la differenza tra lo span e il numero di carte reali. Se i jolly disponibili non bastano a coprire quei buchi, la scala non è valida. Se invece avanzano jolly dopo aver riempito i buchi interni, quelli possono estendere la scala oltre gli estremi — ma solo se c'è "spazio" verso l'asso o verso il re, perché il mazzo non gira in tondo.
Il caso che mi ha fatto perdere più tempo: una scala che parte da un 9 e arriva a un re, con un jolly avanzato. Quel jolly può solo estendersi verso il basso (9→8) perché sopra il re non c'è spazio. Se non gestisci esplicitamente l'asimmetria tra "spazio sotto" e "spazio sopra" lo span, il validatore accetta scale impossibili.
Il burraco vero e proprio — quello che dà il nome al gioco — è una scala di almeno 7 carte: pulito se fatto di sole carte reali, sporco se contiene uno o più jolly. È anche la condizione necessaria per chiudere la mano: senza almeno un burraco calato, calare tutte le carte non basta a vincere la partita.
Validating sets and runs, wildcards included
The two valid melds are sets (3+ cards of the same rank) and runs (3+ cards in sequence, same suit). 2s and jokers are wild and can replace any card in either. For a set the rule is straightforward: separate real cards from wilds, check that all real cards share the same rank, and require wilds not to outnumber real cards — otherwise the set would become "mostly wild," which classic rules don't allow.
The run is trickier. I take the real cards of the same suit, compute the span between the lowest and highest rank, and the internal "gaps" left to fill are the difference between the span and the number of real cards. If the available wilds can't cover those gaps, the run is invalid. If wilds are left over after filling internal gaps, they can extend the run past either end — but only if there's "room" toward the ace or the king, since the deck doesn't wrap around.
The case that cost me the most time: a run starting at 9 and ending at king, with one leftover wild. That wild can only extend downward (9→8) because there's no room above the king. If you don't explicitly handle the asymmetry between "room below" and "room above" the span, the validator accepts impossible runs.
The actual "burraco" — the meld that gives the game its name — is a run of at least 7 cards: clean if made of real cards only, dirty if it contains one or more wilds. It's also the condition required to close a hand: without at least one burraco on the table, melding your entire hand isn't enough to win.
Il pozzetto: una regola che dipende dalla storia, non dal presente
Il pozzetto è un mazzetto di 11 carte che si può prendere intero al posto di pescarne una sola dal mazzo. Per aprirlo, però, un giocatore deve aver calato almeno un tris o una scala pulita, cioè senza jolly. È la regola che mi ha costretto a ripensare lo stato di gioco: non basta guardare cosa c'è sul tavolo in questo momento, perché una volta aperto il pozzetto resta aperto anche se in seguito vengono calate solo combinazioni sporche. Serve tracciare un flag persistente per ciascun giocatore — "ha già aperto" — aggiornato una sola volta, al primo meld pulito, e mai più ricalcolato da zero.
Chi prende il pozzetto aggiunge tutte le 11 carte alla propria mano in un colpo solo: un vantaggio enorme in termini di combinazioni possibili, ma anche undici carte in più da smaltire prima di poter chiudere. Bilanciare quando conviene prenderlo è una delle decisioni più importanti anche per l'avversario umano, ed è per questo che diventa un buon indicatore per calibrare quanto "aggressiva" far giocare l'intelligenza artificiale.
The pot: a rule that depends on history, not the present
The pot is a stack of 11 cards that can be taken whole instead of drawing a single card from the deck. To open it, though, a player must have melded at least one set or one clean run — no wilds. This is the rule that forced me to rethink the game state: you can't just look at what's on the table right now, because once the pot is open it stays open even if only dirty melds follow. You need a persistent flag per player — "has already opened" — set once, on the first clean meld, and never recalculated from scratch.
Whoever takes the pot adds all 11 cards to their hand in one move: a huge advantage in terms of possible combinations, but also eleven extra cards to get rid of before closing. Deciding when it's worth taking is one of the most important calls even for a human opponent, which makes it a good lever for tuning how "aggressive" the AI plays.
Un'IA a tre livelli, senza reti neurali
Niente machine learning: l'avversario è governato da euristiche diverse per ogni difficoltà, applicate in tre momenti del turno — decisione se pescare dal pozzetto, ricerca delle calate possibili, scelta della carta da scartare.
Facile
Prende il pozzetto solo nel 12% dei casi in cui potrebbe, cerca esclusivamente tris di valore già in mano (nessuna ricerca di scale), tenta una sola calata a turno e poi si ferma, e scarta una carta a caso — anche un jolly, se capita, il che è oggettivamente una mossa debole ma realistica per un livello introduttivo.
Media
Sale al 30% di probabilità di prendere il pozzetto e passa a un ciclo greedy: cerca tris, poi scale, poi prova ad aggiungere carte alle calate già presenti sul tavolo, e ripete il ciclo finché trova qualcosa da calare o supera un tetto di iterazioni di sicurezza. Nello scarto, sceglie la carta di valore più alto tra quelle non-jolly, per liberarsi del rischio di restare con carte pesanti in mano a fine mano.
Difficile
Prende il pozzetto nel 65% dei casi utili, esegue lo stesso ciclo greedy della media ma in più riutilizza i jolly avanzati per allungare le proprie scale verso il burraco (7 carte), e soprattutto sceglie lo scarto guardando il tavolo: calcola quali semi e quali valori l'avversario umano sta effettivamente usando nelle sue calate, ed evita di scartare carte che gli servirebbero, preferendo jolly solo come ultima risorsa.
Il risultato è un avversario che, a parità di codice sorgente, si comporta in modo percepibilmente diverso solo cambiando poche soglie numeriche e aggiungendo un paio di euristiche mirate — senza la complessità di un vero motore di ricerca.
A three-tier AI, no neural networks
No machine learning: the opponent runs on different heuristics per difficulty, applied at three points in the turn — whether to take the pot, searching for possible melds, and choosing which card to discard.
Easy
Takes the pot only 12% of the times it could, looks exclusively for sets already sitting in hand (no run search at all), attempts a single meld per turn and then stops, and discards a random card — even a wild if it comes up, which is objectively a weak move but realistic for a beginner tier.
Medium
Takes the pot 30% of the time and switches to a greedy loop: looks for sets, then runs, then tries adding cards to melds already on the table, repeating until it finds something to play or hits a safety iteration cap. For the discard, it picks the highest-value non-wild card, to shed the risk of being stuck with heavy cards at the end of the hand.
Hard
Takes the pot 65% of the useful times, runs the same greedy loop as medium but also reuses leftover wilds to extend its own runs toward a burraco (7 cards), and crucially chooses its discard by reading the table: it computes which suits and ranks the human opponent is actually using in their melds, and avoids discarding cards they'd need, keeping wilds as a last resort.
The result is an opponent that, on the same codebase, behaves noticeably differently just by changing a handful of numeric thresholds and adding a couple of targeted heuristics — without the complexity of a real search engine.
Chiusura mano, punteggio e cosa resta salvato
La mano finisce quando un giocatore cala l'ultima carta senza più scarti, avendo già realizzato almeno un burraco — oppure in stallo, se il mazzo si esaurisce senza che nessuno chiuda. Il punteggio somma i valori delle carte calate da ciascun giocatore e sottrae quelle rimaste in mano, con bonus dedicati per burraco pulito e sporco. Lo storico partite e il punteggio totale restano salvati in localStorage: nessun account, ma anche nessuna sincronizzazione tra dispositivi diversi — una scelta coerente con l'obiettivo di "apri e giochi", da rivedere solo se in futuro servisse un multiplayer reale con backend.
Lo stesso approccio di PWA installabile e zero dipendenze l'ho già usato per Neon Breakout: cambia la natura del problema — lì fisica e collisioni in tempo reale su canvas, qui validazione di regole discrete e IA a euristiche — ma la filosofia di fondo resta la stessa: un file HTML autosufficiente, installabile come app, senza build step.
Closing a hand, scoring, and what gets saved
A hand ends when a player melds their last card with no discard left, having already made at least one burraco — or in a stalemate if the deck runs out before anyone closes. Scoring sums the value of each player's melded cards and subtracts whatever's left in hand, with dedicated bonuses for clean and dirty burracos. Match history and total score are saved in localStorage: no account, but also no syncing across devices — a choice consistent with the "open and play" goal, worth revisiting only if real multiplayer with a backend becomes necessary.
I'd already used the same installable, zero-dependency PWA approach for Neon Breakout: the nature of the problem changes — real-time physics and collisions on canvas there, discrete rule validation and heuristic AI here — but the underlying philosophy stays the same: a self-contained HTML file, installable as an app, with no build step.
Domande frequenti
Come si valida una scala di carte con i jolly in JavaScript?
Si separano le carte reali dai jolly, si calcola lo span tra la carta più bassa e quella più alta dello stesso seme, e si verifica che i buchi interni siano coperti dai jolly disponibili. I jolly avanzati possono poi estendere la scala oltre i due estremi, purché restino dentro il range asso-re.
Come si programma un'intelligenza artificiale per un gioco di carte come il burraco?
Senza reti neurali o ricerca esaustiva: bastano euristiche diverse per ogni livello di difficoltà, applicate su probabilità di pescare dal pozzetto, ricerca greedy delle calate possibili e scelta dello scarto in base a cosa sta usando l'avversario.
Si può giocare a burraco online gratis senza registrazione?
Sì: apri la pagina e giochi subito contro il computer, senza account. Storico partite e punteggio restano salvati in locale nel browser tramite localStorage.
Come funziona il pozzetto nel burraco e perché è la regola più delicata da programmare?
Si apre quando un giocatore cala il suo primo tris o la sua prima scala pulita, senza jolly. È delicato perché dipende dallo storico delle calate di quel giocatore, non dallo stato attuale del tavolo: serve un flag persistente aggiornato una sola volta.
Conviene scrivere un gioco di carte in JavaScript vanilla o usare un framework?
Per un gioco a carte con interfaccia HTML/CSS classica e logica di validazione, un framework aggiunge complessità senza benefici reali. Comincia a convenire solo con multiplayer in tempo reale o stato condiviso complesso.
Frequently asked questions
How do you validate a run of cards with wildcards in JavaScript?
Separate real cards from wilds, compute the span between the lowest and highest rank of the same suit, and check that internal gaps are covered by the available wilds. Leftover wilds can then extend the run past either end, as long as it stays within the ace-to-king range.
How do you code an AI opponent for a card game like burraco?
No neural networks or exhaustive search needed: different heuristics per difficulty tier, applied to pot-taking probability, a greedy search for possible melds, and discard choice based on what the opponent is using.
Can you play free online burraco without signing up?
Yes: open the page and play right away against the computer, no account needed. Match history and score are saved locally in the browser via localStorage.
How does the pot work in burraco, and why is it the trickiest rule to code?
It opens when a player melds their first set or first clean run, with no wilds. It's tricky because it depends on that player's meld history, not the current table state: you need a persistent flag set only once.
Should you write a card game in vanilla JavaScript or use a framework?
For a card game with a classic HTML/CSS interface and validation logic, a framework adds complexity with no real benefit. It only starts paying off with real-time multiplayer or complex shared state.