sequenceDiagram participant P1 as Player 1 (10 pavos) participant P2 as Player 2 (10 elotes) participant S as Server/Room participant UI as UI Components Note over P1,P2: Inicio de Demo Play S->>P1: Asignar rol P1, tokens iniciales S->>P2: Asignar rol P2, tokens iniciales Note over UI: Jugadores pueden cambiar variante en cualquier momento P1->>S: setVariant(G1-G5) S->>S: resetRound(), currentRound=1, status=PLAYING S-->>P1: broadcast variantChanged S-->>P2: broadcast variantChanged loop Cada Ronda (1-3) alt G2 - Regla contraproductiva Note over P2: Checkbox "Forzar oferta" (activo por defecto) P2->>S: p2Force(true/false) S-->>UI: forcedByP2 = true/false Note over P1: Si forzado, botón "No ofrecer" deshabilitado end alt G5 - Cheap talk Note over P1,P2: Chat no vinculante por 1 minuto end alt P1 decide ofrecer P1->>S: proposeOffer({offerPavo, offerElote, requestPavo, requestElote}) S->>S: Validar tokens disponibles S-->>UI: offerActive = true, ocultar OfferControls S-->>P2: Mostrar oferta y botones de decisión P2->>S: p2Action(accept/reject/snatch) S->>S: Prevenir múltiples acciones (if p2Action exists, return) alt accept S->>S: Intercambiar tokens ambos lados S->>S: Auto-avanzar ronda else reject S->>S: Sin cambios en tokens S->>S: Auto-avanzar ronda else snatch S->>S: P2 recibe oferta sin pagar alt G3 - Token de vergüenza S-->>UI: Mostrar botones vergüenza a P1 P1->>S: assignShame(true/false) alt true S->>P2: shameTokens += 1 end S->>S: Auto-avanzar ronda else G4 - Derechos mínimos S-->>UI: Mostrar botones denuncia a P1 P1->>S: report(true/false) alt true S->>S: Revertir robo S->>S: P1 recibe pedido sin dar oferta (sanción inversa) end S->>S: Auto-avanzar ronda else Otros S->>S: Auto-avanzar ronda end end else P1 no ofrece P1->>S: noOffer() S->>S: p1Action = "no_offer" S->>S: Auto-avanzar ronda end end Note over S: Después de ronda 3 S->>S: gameStatus = FINISHED Note over UI: Al cambiar variante, reinicia todo