Vai al contenuto

Progetto:BridgeShape API

Da BridgePedia.

Questa pagina documenta l'API dell'estensione BridgeShape per sviluppatori di tool esterni che generano smazzate di test a partire dai vincoli di distribuzione definiti nelle pagine di convenzione.

BridgeShape — API per Generatori di Smazzate

Documentazione tecnica per chi sviluppa un generatore di smazzate di test che legge i vincoli di distribuzione (shape constraints) dalle convenzioni di BridgePedia.

Panoramica

Ogni pagina wiki di convenzione su BridgePedia può definire nel template


Nome Progetto:BridgeShape API
Tipologia
Scopo
Trigger (quando si usa)
Risposte / sviluppi
Note

un campo shape_constraints che descrive, in un formato DSL compatto, i vincoli di distribuzione delle mani dei 4 giocatori al tavolo.

L'estensione BridgeShape espone un'API REST/JSON per leggere questi vincoli in modo strutturato.

API Endpoint

<syntaxhighlight lang="bash"> GET /api.php?action=bridgeshape&shapeaction=ACTION&format=json </syntaxhighlight>

Azioni disponibili

Azione Descrizione Parametri
get Vincoli per una singola convenzione pageid oppure title
list Elenco convenzioni con vincoli definiti
listall Elenco tutte le convenzioni (con/senza vincoli)
validate Valida una stringa DSL senza bisogno di una pagina wiki dsl

Esempi di chiamata

<syntaxhighlight lang="bash">

  1. Per titolo pagina

curl "https://bridgepedia.it/api.php?action=bridgeshape&shapeaction=get&title=Splinter&format=json"

  1. Per page ID

curl "https://bridgepedia.it/api.php?action=bridgeshape&shapeaction=get&pageid=42&format=json"

  1. Elenco pagine con vincoli

curl "https://bridgepedia.it/api.php?action=bridgeshape&shapeaction=list&format=json"

  1. Validare una stringa DSL

curl "https://bridgepedia.it/api.php?action=bridgeshape&shapeaction=validate&dsl=opener+H:5%2B+hcp:12-21&format=json" </syntaxhighlight>

Formato risposta JSON

shapeaction=get

<syntaxhighlight lang="json"> {

 "shapeconstraints": {
   "pageId": 42,
   "raw": "1H-4C: opener H:5+ hcp:12-21; responder H:4+ C:0-1 Chcp:0 hcp:10-15 // ...",
   "scenarios": [
     {
       "label": "1H-4C",
       "positions": {
         "opener": {
           "suits": {
             "H": { "min": 5, "max": null }
           },
           "hcp": { "min": 12, "max": 21 }
         },
         "responder": {
           "suits": {
             "H": { "min": 4, "max": null },
             "C": { "min": 0, "max": 1 }
           },
           "suit_hcp": {
             "C": { "min": 0, "max": 0 }
           },
           "hcp": { "min": 10, "max": 15 }
         }
       },
       "fit": []
     }
   ]
 }

} </syntaxhighlight>

shapeaction=list

<syntaxhighlight lang="json"> {

 "pages": [
   {
     "pageId": 42,
     "title": "Splinter",
     "scenarioCount": 6,
     "labels": ["1H-4C", "1H-4D", "1H-4S", "1S-4C", "1S-4D", "1S-4H"]
   },
   {
     "pageId": 15,
     "title": "Stayman",
     "scenarioCount": 2,
     "labels": ["fit a cuori", "fit a picche"]
   }
 ]

} </syntaxhighlight>

Formato DSL

Il DSL (Domain Specific Language) è la stringa scritta nel campo shape_constraints del template wiki.

Struttura

<syntaxhighlight lang="bash"> etichetta: vincoli posizione; vincoli posizione // etichetta: vincoli // ... </syntaxhighlight>

  • // separa gli scenari (il generatore ne sceglie uno random o li presenta all'utente)
  • ; separa le posizioni dentro uno scenario
  • Ogni scenario ha un'etichetta opzionale seguita da :
  • Ogni posizione inizia col nome del ruolo, seguito da vincoli separati da spazi

Posizioni

Nome Ruolo
opener Chi apre o fa la prima licita convenzionale
responder Il compagno dell'opener
opp1 Avversario a sinistra dell'opener
opp2 Avversario a destra dell'opener (compagno di opp1)

Vincoli

Lunghezza seme (specifico)

<syntaxhighlight lang="bash"> S:5+ — almeno 5 picche H:0-1 — 0 o 1 cuori D:3 — esattamente 3 quadri C:2-5 — da 2 a 5 fiori </syntaxhighlight>

Semi: S = Spades/Picche, H = Hearts/Cuori, D = Diamonds/Quadri, C = Clubs/Fiori

Lunghezza seme (wildcard)

<syntaxhighlight lang="bash"> x:0-1 — un seme qualsiasi (tra quelli non specificati) con 0-1 carte x:6+ — un seme non specificato con almeno 6 carte </syntaxhighlight>

Il generatore sceglie casualmente quale seme assegnare a x tra quelli non già vincolati esplicitamente (S/H/D/C).

HCP totali

<syntaxhighlight lang="bash"> hcp:15-17 — da 15 a 17 punti onore hcp:12+ — almeno 12 punti hcp:0-7 — da 0 a 7 punti </syntaxhighlight>

HCP nel seme (specifico)

<syntaxhighlight lang="bash"> Shcp:3+ — almeno 3 HCP a picche Chcp:0 — 0 HCP a fiori (nessun onore) Hhcp:0-2 — da 0 a 2 HCP a cuori </syntaxhighlight>

HCP nel seme (wildcard)

<syntaxhighlight lang="bash"> xhcp:0 — 0 HCP nel seme wildcard (x) xhcp:0-1 — 0-1 HCP nel seme x </syntaxhighlight>

Shape class

<syntaxhighlight lang="bash"> shape:balanced — distribuzione bilanciata (4333, 4432, 5332) shape:one_suiter — monocolore shape:two_suiter — bicolore shape:three_suiter — tricolore shape:any — qualsiasi (default) </syntaxhighlight>

Fit (vincolo cross-posizione)

<syntaxhighlight lang="bash"> fit:H8+ — almeno 8 cuori totali tra i compagni fit:S9+ — almeno 9 picche totali tra i compagni fit:M8+ — almeno 8 carte in un seme maggiore (H o S) fit:m8+ — almeno 8 carte in un seme minore (D o C) fit:8+ — almeno 8 carte in un seme qualsiasi </syntaxhighlight>

Il fit si applica tra compagni:

  • Se appare su opener o responder, o a livello di scenario → coppia dichiarante
  • Se appare su opp1 o opp2 → coppia difensiva

Formato range

Sintassi Significato
5+ Almeno 5 (min=5, max=null)
0-1 Da 0 a 1 (min=0, max=1)
3 Esattamente 3 (min=3, max=3)
12-21 Da 12 a 21 (min=12, max=21)

Nella risposta JSON, max: null significa "nessun limite superiore".

Semi non menzionati

I semi non vincolati e non coperti da x: sono distribuiti casualmente dal generatore, rispettando il vincolo che il totale delle carte per mano sia 13.

Struttura JSON di uno scenario

<syntaxhighlight lang="javascript"> interface Scenario {

 label: string;           // Etichetta (es. "1H-4C"), vuota se non specificata
 positions: {
   [posName: string]: Position;  // "opener", "responder", "opp1", "opp2"
 };
 fit: FitConstraint[];    // Vincoli di fit (array, può essere vuoto)

}

interface Position {

 suits?: {                // Vincoli lunghezza seme (solo semi esplicitati)
   [suit: string]: Range; // "S", "H", "D", "C"
 };
 hcp?: Range;             // HCP totali
 suit_hcp?: {             // HCP per seme specifico
   [suit: string]: Range;
 };
 x?: Range;               // Lunghezza seme wildcard
 x_hcp?: Range;           // HCP seme wildcard
 shape?: string;          // Shape class: "balanced", "one_suiter", etc.

}

interface Range {

 min: number;
 max: number | null;      // null = nessun limite superiore

}

interface FitConstraint {

 suit: string | null;      // "S","H","D","C" o null
 suit_class: string | null; // "major", "minor" o null
 min: number;              // Numero minimo di carte (es. 8)
 pair: string;             // "declarer" o "defense"

} </syntaxhighlight>

Logica per il generatore

Algoritmo base

Per ogni scenario:

  1. Scegli lo scenario: random tra quelli disponibili, oppure lascia scegliere all'utente
  2. Risolvi wildcard:
    • Se una posizione ha x:, scegli un seme casuale tra quelli non esplicitamente vincolati
    • xhcp: si applica allo stesso seme scelto per x:
  3. Risolvi fit:
    • Se fit.suit è specificato, entrambi i compagni devono avere un totale >= fit.min in quel seme
    • Se fit.suit_class è "major", scegli tra H e S; se "minor", tra D e C
    • Se entrambi sono null, scegli un seme qualsiasi
    • fit.pair indica quale coppia: "declarer" (opener+responder) o "defense" (opp1+opp2)
  4. Genera le mani:
    • Per ogni posizione, genera una mano che rispetti tutti i vincoli
    • I semi senza vincoli vengono riempiti casualmente
    • Il totale delle carte per mano deve essere esattamente 13
    • Il totale delle carte per seme (tutte e 4 le mani) deve essere esattamente 13
  5. Posizioni non menzionate: se uno scenario non menziona opp1/opp2, distribuisci le carte rimanenti casualmente tra gli avversari

Priorità dei vincoli

  1. Vincoli di fit (cross-posizione) — determinano la distribuzione di base
  2. Vincoli di seme specifico (S:, H:, D:, C:) — limitano i singoli semi
  3. Vincoli wildcard (x:) — dopo aver fissato i semi specifici
  4. Vincoli HCP (hcp:, Shcp:, xhcp:) — filtro finale
  5. Shape class (shape:) — validazione della forma complessiva

Gestione di max: null

Quando max è null, non c'è limite superiore esplicito. I limiti fisici del bridge si applicano comunque:

  • Massimo 13 carte per seme (tutte e 4 le mani)
  • Massimo 13 carte per mano
  • Massimo 10 HCP per seme (A+K+Q+J = 4+3+2+1)
  • Massimo 37 HCP per mano (raro ma teoricamente possibile con tutti gli onori)

Esempi completi

Splinter (tutti gli scenari specifici)

DSL nel template wiki:

<syntaxhighlight lang="bash"> 1H-4C: opener H:5+ hcp:12-21; responder H:4+ C:0-1 Chcp:0 hcp:10-15 // 1H-4D: opener H:5+ hcp:12-21; responder H:4+ D:0-1 Dhcp:0 hcp:10-15 // 1H-4S: opener H:5+ hcp:12-21; responder H:4+ S:0-1 Shcp:0 hcp:10-15 // 1S-4C: opener S:5+ hcp:12-21; responder S:4+ C:0-1 Chcp:0 hcp:10-15 // 1S-4D: opener S:5+ hcp:12-21; responder S:4+ D:0-1 Dhcp:0 hcp:10-15 // 1S-4H: opener S:5+ hcp:12-21; responder S:4+ H:0-1 Hhcp:0 hcp:10-15 </syntaxhighlight>

Splinter (compatto con fit e wildcard)

<syntaxhighlight lang="bash"> dopo 1H: fit:H8+ opener H:5+ hcp:12-21; responder x:0-1 xhcp:0 hcp:10-15 // dopo 1S: fit:S8+ opener S:5+ hcp:12-21; responder x:0-1 xhcp:0 hcp:10-15 </syntaxhighlight>

Stayman

<syntaxhighlight lang="bash"> fit a cuori: fit:H8+ opener hcp:15-17 S:2-4 H:2-4 D:2-5 C:2-5; responder H:4+ hcp:8+ // fit a picche: fit:S8+ opener hcp:15-17 S:2-4 H:2-4 D:2-5 C:2-5; responder S:4+ hcp:8+ </syntaxhighlight>

Contro informativo

<syntaxhighlight lang="bash"> base: opener hcp:12-21 x:5+; opp1 hcp:12+ S:3+ H:3+ D:3+ C:3+; responder hcp:0-8 // con intervento: opener hcp:12-21 x:5+; opp1 hcp:12+ S:3+ H:3+ D:3+ C:3+; opp2 hcp:8+ x:5+ </syntaxhighlight>

Preempt 3-a-livello

<syntaxhighlight lang="bash"> opener H:7+ x:0-1 hcp:5-10 </syntaxhighlight>

Overcall con fit avversari

<syntaxhighlight lang="bash"> overcall semplice: opener hcp:12-21 x:5+; opp1 hcp:10+ x:5+; opp2 fit:8+ // con barrage: opener hcp:12-21 x:5+; opp1 hcp:6-10 x:6+; opp2 fit:9+ </syntaxhighlight>

Note implementative

  • L'API è read-only, non richiede token CSRF
  • L'accesso anonimo è abilitato di default (BridgeShapeAllowAnonymous: true) perché i dati sono pubblici e i tool esterni ne hanno bisogno
  • Il campo raw nella risposta get contiene la stringa DSL originale, utile per debug
  • L'azione validate permette di testare stringhe DSL senza creare pagine wiki
  • I calcoli HCP usano la scala standard: A=4, K=3, Q=2, J=1