Metadata-Version: 2.4
Name: treta
Version: 0.1.0
Summary: IA adversaria online para videojuegos: aprende del jugador, contraataca, finta e improvisa siendo casi imposible de predecir. Cero dependencias.
Project-URL: Homepage, https://github.com/esraderey/treta
Project-URL: Issues, https://github.com/esraderey/treta/issues
Author: esraderey
License: MIT
License-File: LICENSE
Keywords: game-ai,ia-adversaria,novelty-search,online-learning,opponent-modeling,regret-matching,videojuegos,zero-dependencies
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Games/Entertainment
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Typing :: Typed
Requires-Python: >=3.10
Provides-Extra: test
Requires-Dist: hypothesis>=6; extra == 'test'
Requires-Dist: pytest>=8; extra == 'test'
Description-Content-Type: text/markdown

# treta

**IA adversaria online para videojuegos: aprende del jugador, contraataca, finta e improvisa — manteniéndose casi imposible de predecir.**

[![PyPI](https://img.shields.io/pypi/v/treta)](https://pypi.org/project/treta/)
![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue)
![Dependencias: 0](https://img.shields.io/badge/dependencias-0-brightgreen)
![Licencia MIT](https://img.shields.io/badge/licencia-MIT-green)

Python puro, **cero dependencias**, determinista por semilla, ~O(|A|²) por turno (apta para 60 Hz).

*Registro de experimento: **EXP-008** (línea esraderey de microlibrerías zero-dep).*

```bash
pip install treta
```

## La idea en una frase

Los enemigos de videojuego fallan por dos extremos: los guionizados se vuelven **legibles** (el jugador los "resuelve") y los aleatorios se vuelven **incompetentes**. `treta` resuelve el dilema tratando la impredecibilidad como una **cantidad medida y optimizada**: el agente entrena un **autoadversario** —un predictor de su propia conducta, de la misma clase que usaría un jugador hábil— y castiga en su función de valor las acciones que ese observador anticiparía. Explota al rival *exactamente hasta donde puede sin volverse legible*.

## Uso

```python
from treta import Agente

ACCIONES = ["piedra", "papel", "tijera"]
VENCE = {"piedra": "tijera", "papel": "piedra", "tijera": "papel"}

# pago(a_ia, a_jugador) -> float (opcional; si falta, se estima de las recompensas)
def pago(a, j):
    return 0.0 if a == j else (1.0 if VENCE[a] == j else -1.0)

ia = Agente(ACCIONES, pago=pago, semilla=42)

# bucle del juego (movimientos simultáneos o por turnos):
accion = ia.decidir()               # acción del enemigo este turno
ia.observar(accion_del_jugador)     # cierra el turno; aprende online
                                    # (o ia.observar(j, recompensa=r) sin matriz de pagos)

ia.predictibilidad()   # [0,1] cuán legible es la IA para un observador competente
ia.certeza_jugador()   # [0,1] cuán bien modela al jugador
ia.improvisando()      # True durante un gambito
ia.fintando()          # True durante una finta (sembrando o cobrando un cebo)
ia.instantanea()       # telemetría para HUD/depuración
```

`decidir(extra=...)` acepta cualquier rasgo observable hasheable (fase del nivel, distancia discretizada, arma equipada) y condiciona los modelos de contexto con él.

## Seis mecanismos, un agente

| Mecanismo | Qué aporta | Base |
|---|---|---|
| **Modelo del jugador**: mezcla bayesiana de expertos n-grama (órdenes 0..k, olvido perezoso) + red neuronal pura (`RedMicro`, MLP online de entrada dispersa) | Predice la siguiente acción del jugador; los n-gramas memorizan patrones exactos, la red generaliza | PPM/CTW (Cleary & Witten 1984; Willems 1995), mezcla bayesiana con participación fija |
| **Autoadversario** *(la innovación de EXP-008)* | El mismo aparato apuntado a la propia IA. Su acierto define `predictibilidad`, que entra como **castigo** en el valor esperado: `EV'(a) = EV(a) − λ·presión·p_yo(a)`. La IA evita literalmente lo que un observador esperaría de ella, en proporción a cuánto la están leyendo | Emparentado con *Safe Opponent Exploitation* (Ganzfried & Sandholm 2012), resuelto aquí como regularizador online barato |
| **Fintas de segunda intención** | El autoadversario como sistema de puntería: ante un rival ilegible que lee y contraataca, siembra un cebo, verifica por *acuerdo* que el rival responde a la imagen propia (su jugada prevista es la mejor respuesta a `p_yo`) y cobra la contra-contra mientras el acuerdo dure. Sangría de siembra acotada, salida al segundo cobro perdido, respiros anti-patrón y enfriamiento exponencial ante sondeos fallidos | Enseñanza estratégica (Camerer, Ho & Chong 2002); la "segunda intención" de la esgrima |
| **Regret Matching+** | Piso teórico-de-juegos: contra un adversario que contraataca, empuja la política mixta hacia maximin | Hart & Mas-Colell 2000; Tammelin 2014 (RM+/CFR+) |
| **Improvisación por novedad** | Archivo acotado de *gambitos* (motivos de 2–4 acciones) con descriptor conductual; ante estancamiento o legibilidad alta ejecuta el motivo más novedoso (búsqueda de novedad + calidad, QD-lite) | Lehman & Stanley 2011; Mouret & Clune 2015 |
| **Detección de deriva** | Page-Hinkley sobre la log-pérdida del modelo del jugador: si el jugador cambia de estilo, olvido acelerado y readaptación | Page 1954 |

La **presión** modula el castigo: contra un rival estático (que no explota los patrones de la IA) el impuesto de impredecibilidad es mínimo y la explotación es agresiva; contra un rival que lee y contraataca, el castigo, la temperatura y la mezcla con RM+ suben solos.

## Banco adversario (reproducible: `python ejemplos/duelo.py`)

Piedra-papel-tijera de suma cero (azar = pago 0, predicción por azar = 33.3 %), 4000 rondas, semilla 7. El *observador externo* es una mezcla de n-gramas (órdenes 0–3) que intenta predecir a la IA — el mismo modelo que usaría un jugador metódico.

| Rival | Pago medio IA (últ. mitad) | Acierto del observador sobre la IA |
|---|---|---|
| Repetidor (acción fija) | **+0.868** | 88.7 % |
| Ciclador (periodo 4) | **+0.712** | 78.4 % |
| Imitador (copia a la IA) | **+0.774** | 79.2 % |
| Aleatorio uniforme | +0.036 | 35.0 % |
| **Contra-predictor** (predice a la IA con sus mismos modelos y contraataca) | **+0.217** | **25.5 %** *(muy bajo el azar)* |
| Cambiante (deriva en t=1200; últ. 400) | **+0.765** | 78.0 % |

Lectura: explota con fuerza todo patrón (pago cercano a +1 donde lo hay) y queda neutral ante el azar puro. El acierto alto del observador contra rivales estáticos **no es un fallo**: nadie castiga ahí la legibilidad, así que la `presión` es ~0 y el agente elige explotación máxima. Contra el único rival que sí lee y contraataca, la IA **gana con claridad** y su acción cae *muy por debajo del azar* para el observador: el castigo por auto-predictibilidad la aleja de lo esperado y las fintas cobran, además, la imagen que el rival se forma de ella (robusto en semillas 7/11/23: pago +0.217..+0.239, acierto 23.8..25.5 %). Contra el Cambiante, Page-Hinkley detecta la deriva (1 alarma) y el pago se recupera a +0.765 en 400 rondas.

## Garantías y límites (honestos)

- **Garantiza**: determinismo por semilla; política válida en todo paso; coste por turno O(k + |A|²) sin asignaciones grandes; con matriz de pagos exacta, RM+ acumula arrepentimientos exactos que empujan la mezcla hacia maximin — la garantía formal de arrepentimiento sublineal aplica a RM+ jugado en solitario, no a la política mixta final (además, los turnos de gambito no actualizan el regret): el respaldo de la no-explotabilidad es el banco empírico.
- **No hace**: espacios de acción continuos, percepción (píxeles), planificación a varios turnos ni aprendizaje entre partidas persistido (serializa tú `instantanea` + estado si lo necesitas). El "castigo por auto-predictibilidad" es un regularizador empírico, no un equilibrio exacto: el banco de arriba es su evidencia.
- Alfabetos de 2 a 32 acciones. Para juegos con estado rico, discretiza lo observable y pásalo por `extra`.
- Las fintas asumen rival adversario (aprox. suma cero: su mejor respuesta minimiza tu pago). En juegos sin ese antagonismo la compuerta de margen las deja inertes.

## Desarrollo

```bash
pip install -e ".[test]"
pytest            # unidades + propiedades (Hypothesis) + banco adversario
```

## Licencia

MIT © esraderey
