# SnatchGame – Diagramas Mermaid Este índice reúne los diagramas claves para implementar el juego y verificar los flujos. Puedes abrir cada `.mmd` con la extensión oficial de Mermaid o verlos embebidos abajo. ## Visión general del ciclo ```mermaid %% game-overview.mmd flowchart TD A[Emparejar jugadores al azar] --> B[Asignar roles P1/P2] B --> C[Seleccionar variante G1..G5] C --> D[Iniciar partida de 3 rondas] D --> R1[Ronda 1] --> R2[Ronda 2] --> R3[Ronda 3] R3 --> E[Registrar SOLO resultado de R3] E --> F[Actualizar leaderboard/analytics] F --> G[Reemparejar y posible cambio de roles] ``` ## Orquestación global (200 jugadores, G1->G5) ```mermaid %% tournament-orchestration.mmd flowchart TD Start[Init torneo] --> PhaseG1[Phase G1: iniciar] PhaseG1 --> MatchG1[Emparejar 200 jugadores al azar] MatchG1 --> RoomsG1[Crear rooms P1-P2 y asignar roles] RoomsG1 --> PlayG1[Jugar 3 rondas en paralelo] PlayG1 --> CommitG1[Commit solo resultado de ronda 3] CommitG1 --> WaitAllG1[Esperar que TODOS terminen] WaitAllG1 --> RematchG2[Reemparejar todos al azar] RematchG2 --> PhaseG2[Phase G2: iniciar] PhaseG2 --> MatchG2[Emparejar 200 jugadores al azar] MatchG2 --> RoomsG2[Crear rooms y roles] RoomsG2 --> PlayG2[Jugar 3 rondas en paralelo] PlayG2 --> CommitG2[Commit ronda 3] CommitG2 --> WaitAllG2[Esperar TODOS] WaitAllG2 --> RematchG3[Reemparejar] RematchG3 --> PhaseG3[Phase G3: iniciar] PhaseG3 --> MatchG3 MatchG3 --> RoomsG3 RoomsG3 --> PlayG3 PlayG3 --> CommitG3 CommitG3 --> WaitAllG3 WaitAllG3 --> RematchG4 RematchG4 --> PhaseG4[Phase G4: iniciar] PhaseG4 --> MatchG4 MatchG4 --> RoomsG4 RoomsG4 --> PlayG4 PlayG4 --> CommitG4 CommitG4 --> WaitAllG4 WaitAllG4 --> RematchG5 RematchG5 --> PhaseG5[Phase G5: iniciar] PhaseG5 --> MatchG5 MatchG5 --> RoomsG5 RoomsG5 --> PlayG5 PlayG5 --> CommitG5 CommitG5 --> End[Fin del torneo] ``` ## Máquina de estados (Room/Partida) ```mermaid %% game-state-machine.mmd stateDiagram-v2 [*] --> Lobby Lobby --> Matching : join/ready Matching --> Setup : asignar roles + variante Setup --> PreChat : si G5 (cheap talk) Setup --> Round1 : si no G5 PreChat --> Round1 : fin ventana chat (1 min) Round1 --> Round2 : resultado cerrado Round2 --> Round3 : resultado cerrado Round3 --> PostGame : resultado cerrado PostGame --> Commit : registrar solo R3 Commit --> Rematch : liberar jugadores Rematch --> [*] note right of Round1 Las decisiones pueden ser: - Secuenciales (G1,G2,G3,G4,G5) - Simultáneas (si en el futuro aplica) end note ``` ## Secuencia por ronda (cliente-servidor) ```mermaid %% game-sequence.mmd sequenceDiagram participant P1 as Player 1 participant P2 as Player 2 participant S as Server/Room participant AJ as AutoJudge G4 S->>P1: startRound(gameType, roundNo, role=P1) S->>P2: startRound(gameType, roundNo, role=P2) alt G2 (P2 decide forzar) P2->>S: decide(force or no_force) S-->>P1: forcedOffer = true/false else Otros juegos Note over P1,P2: Sin decision previa de P2 end alt no_offer P1->>S: noOffer() S-->>P1: sin cambios de tokens S-->>P2: sin cambios de tokens else oferta P1->>S: proposeOffer({offer:{pavo,elote}, request:{pavo,elote}}) S-->>P2: offerAvailable P2->>S: actionP2(accept / reject / snatch) alt accept S-->>P1: transfer ambos lados (según oferta/pedido) S-->>P2: transfer ambos lados (según oferta/pedido) else reject S-->>P1: sin cambios S-->>P2: sin cambios else snatch S-->>P2: transferir solo lo ofrecido a P2 opt G4 denuncia P1->>S: report: yes or no alt report=yes S->>AJ: aplicar sanción AJ-->>S: confiscar oferta a P2 y revertir a P1 else report=no Note over P1,P2: Se mantiene el robo end end opt G3 repudio P1->>S: shameToken: assign yes or no S-->>P2: actualizar contador vergüenza (próxima partida) end end end S-->>P1: endRound S-->>P2: endRound ``` ## Variantes de juego ### G1 – Sin derechos de propiedad (oferta variable) ```mermaid %% g1-no-property.mmd flowchart TD A1[P1: Proponer oferta? (pavos/elotes + pedido)] -->|No ofrecer| O1[Sin cambios] A1 -->|Ofrecer| B1[P2: Aceptar / Rechazar / Robar] B1 -->|Aceptar| O2[Intercambiar según oferta/pedido] B1 -->|Rechazar| O3[Sin cambios] B1 -->|Robar| O4[Transferir solo lo ofrecido a P2] ``` ### G2 – Regla contraproductiva (P2 puede forzar) – oferta variable ```mermaid %% g2-counterproductive-rule.mmd flowchart TD A2[P2: Forzar?] -->|Sí| F2[P1: Debe proponer oferta] A2 -->|No| B2[P1: Proponer oferta?] F2 --> C2[P2: Acción final] B2 -->|No ofrecer| O1[Sin cambios] B2 -->|Ofrecer| C2[P2: Aceptar / Rechazar / Robar] C2 -->|Aceptar| O2[Intercambiar según oferta/pedido] C2 -->|Rechazar| O3[Sin cambios] C2 -->|Robar| O4[Transferir solo lo ofrecido a P2] ``` ### G3 – Token de repudio (vergüenza) – oferta variable ```mermaid %% g3-shame-token.mmd flowchart TD A3[P1: Proponer oferta?] -->|No ofrecer| O1[Sin cambios] A3 -->|Ofrecer| B3[P2: Aceptar / Rechazar / Robar] B3 -->|Aceptar| O2[Intercambiar según oferta/pedido] B3 -->|Rechazar| O3[Sin cambios] B3 -->|Robar| C3[P1: Asignar ficha de vergüenza?] C3 -->|Sí| O4a[+1 vergüenza para P2] C3 -->|No| O4b[Sin vergüenza] ``` ### G4 – Derechos mínimos de propiedad (juez) – oferta variable ```mermaid %% g4-min-property-rights.mmd flowchart TD A4[P1: Proponer oferta?] -->|No ofrecer| O1[Sin cambios] A4 -->|Ofrecer| B4[P2: Aceptar / Rechazar / Robar] B4 -->|Aceptar| O2[Intercambiar según oferta/pedido] B4 -->|Rechazar| O3[Sin cambios] B4 -->|Robar| C4[P1: ¿Denunciar?] C4 -->|No| O4[Transferir solo lo ofrecido a P2] C4 -->|Sí| J4[AutoJudge revierte robo (confisca oferta a P2)] J4 --> O5[Restituir oferta a P1] ``` ### G5 – Cheap talk (conversación previa) – oferta variable ```mermaid %% g5-cheap-talk.mmd flowchart TD Pre[Chat previo 1 min - no vinculante] --> A5[P1: Proponer oferta?] A5 -->|No ofrecer| O1[Sin cambios] A5 -->|Ofrecer| B5[P2: Aceptar / Rechazar / Robar] B5 -->|Aceptar| O2[Intercambiar según oferta/pedido] B5 -->|Rechazar| O3[Sin cambios] B5 -->|Robar| O4[Transferir solo lo ofrecido a P2] ``` ## Emparejamiento en masa (fase Gx) ```mermaid %% matchmaking.mmd sequenceDiagram participant OR as Orchestrator participant MM as Matchmaker participant P as PlayerPool participant R as RoomFactory OR->>MM: start phase (Gx) for ALL MM->>P: collect all available players (200) MM->>P: shuffle randomly loop pair players MM->>R: create room with pair (P1,P2) and roles R-->>MM: roomId end MM-->>OR: rooms created for all pairs OR->>R: broadcast startRound(1) to all rooms ``` ## Modelo de datos (mínimo) ```mermaid %% data-model.mmd classDiagram class Player { +string id +string name +int pavoTokens // tokens tipo P1 +int eloteTokens // tokens tipo P2 +number shameTokens // visible en próxima partida } note for Player "Scoring: como P1 => pavo*1 + elote*2; como P2 => elote*1 + pavo*2; total = suma" class GameSession { +string id +string gameType // G1..G5 +string player1Id +string player2Id +int currentRound // 1..3 +Round[] rounds // length=3 +Date createdAt } class Round { +int index // 1,2,3 +string p1Action // offer|no_offer|forced_offer +string p2Action // accept|reject|snatch|null +boolean forcedByP2 // G2 +boolean reported // G4 +boolean shameAssigned // G3 +number outcomeP1 +number outcomeP2 +boolean isThird } class LeaderboardEntry { +string playerId +number scoreAsP1 // P1: pavo*1 + elote*2 +number scoreAsP2 // P2: elote*1 + pavo*2 +number aggregateScore // scoreAsP1 + scoreAsP2 +Date updatedAt } Player "1" -- "0..*" GameSession : participa GameSession "1" o-- "3" Round : incluye Player "1" -- "0..*" LeaderboardEntry : puntuación ``` --- Notas: - Solo el resultado de la R3 se agrega al leaderboard/analytics. - G2 introduce `forcedByP2`; G3, `shameAssigned` y contador visible en la siguiente partida; G4, `reported` y sanción del juez. - El servidor es autoritativo; clientes no mutan estado.