Skip to content

ENH: Add ZeroResp and ZeroResp v2 (tournament rev 2.2) - #1496

Open
Evreu1pro wants to merge 8 commits into
Axelrod-Python:devfrom
Evreu1pro:feat/zeroresp-v2
Open

ENH: Add ZeroResp and ZeroResp v2 (tournament rev 2.2)#1496
Evreu1pro wants to merge 8 commits into
Axelrod-Python:devfrom
Evreu1pro:feat/zeroresp-v2

Conversation

@Evreu1pro

@Evreu1pro Evreu1pro commented Aug 2, 2026

Copy link
Copy Markdown

What

Adds two related adaptive long-memory strategies for the iterated Prisoner's Dilemma:

  1. ZeroResp — epoch debt, stochastic retaliation buffer, systemic red line, anti-raider, finite-horizon harvest
  2. ZeroResp v2 (implementation revision 2.2, tournament candidate) — same backbone plus:
    • Early sharp — delay=1 in the first turns (Prober-friendly)
    • Short adaptive buffer — mid-game delay 1–2 (responsive vs soft-majority / Downing-style play)
    • Echo-shield / contrition — ignore one mirror D after our queued strike
    • Noise-aware forgive — isolated mid-game noise after long mutual C (up to 2×)
    • Deadlock break — CD/DC loops force cooperative reset
    • Smart end-game harvest / grim probe — short remaining horizon only; cautious vs never-defectors

This PR supersedes #1495 (ZeroResp alone). Prefer reviewing this PR.

Why

ZeroResp v2.2 is the sandbox leader against classic Axelrod pools and exploiter heuristics while remaining non-cheating (inspects_source / manipulates_* all false).

External benchmarks (reproducible package)

Full report: https://github.com/Evreu1pro/ZeroResp

Setting Result
Higher League Top-40 · 400×2 · 7 seeds avg rank #2 (avg/r ≈ 2.760); best seed #1
Endurance Top-40 · 1501 turns · 5 seeds stable #2#3 (avg rank 2.40)
H2H vs Omega TFT · 1000 / 5000 turns mutual coop ~99.7–99.9%; near-parity scores
Survival elimination to Top-5 #1 every round, final avg/r ≈ 3.000
Channel noise 1–3% known weaker regime vs Omega TFT (documented honestly)

How to test

pytest axelrod/tests/strategies/test_zeroresp.py axelrod/tests/strategies/test_zeroresp_v2.py -q

Smoke:

import axelrod as axl
m = axl.Match((axl.ZeroRespV2(), axl.TitForTat()), turns=100, seed=0)
m.play()
print(m.final_score())

Coverage

  • Initial move always C
  • Early sharp delay=1
  • Echo shield, noise forgive, deadlock break
  • Systemic red line, anti-raider, smart harvest
  • reset() / clone for multi-rep tournaments
  • Match-length edge cases

Changes

Path Role
axelrod/strategies/zeroresp.py ZeroResp
axelrod/strategies/zeroresp_v2.py ZeroResp v2 (rev 2.2)
axelrod/tests/strategies/test_zeroresp*.py TestPlayer suites
_strategies.py / classifiers / docs registration

Also includes CI hardening (numpy<2, black formatting) so the suite stays green on current runners.

Breaking

No — additive only.

Review notes for maintainers

  • Happy to drop ZeroResp (v1) and keep only ZeroResp v2 if you prefer a single strategy.
  • Happy to rename the display string to ZeroResp v2.2 if that is clearer in plots.
  • Showcase + CSV aggregates: https://github.com/Evreu1pro/ZeroResp

Adds an adaptive state-machine strategy with dynamic epochs, a stochastic
retaliation buffer (5 + U{1..10}), and a permanent red-line ban after
systemic defections. Includes unit tests (initial C, buffer queue, red line,
reset), strategy registration, classifier entry, and docs index update.
Adds tests for match-length edge cases, end-game harvest, anti-raider,
hostile live ban, and epoch/red-line close paths. Updates stochastic and
makes_use_of length filter counts after registering ZeroResp.
NumPy 2.x changes scalar repr (np.int64/np.float64) which breaks doctests,
match.scores output, and fingerprint probe string equality under CI.
Tox already pins numpy==1.26.4 for install_deps; package deps were upgrading
to 2.x via numpy>=1.26.4. Constrain the dependency and harden Point creation.
pytest already green (5252 passed, 100% coverage). CI failed on
black --check for test_zeroresp and a few pre-existing modules under
black 26.x. Format those files so tox commands[1] passes.
Ports ZeroRespV2Core: early-sharp retaliation, echo-shield contrition,
one-shot noise forgiveness, deadlock break, plus ZeroResp backbone
(epochs, systemic red line, anti-raider, end-game harvest).

Includes full TestPlayer suite, registration, classifier YAML, and docs.
@drvinceknight drvinceknight mentioned this pull request Aug 4, 2026
@Evreu1pro Evreu1pro changed the title ENH: Add ZeroResp v2 (champion build) and ZeroResp strategies ENH: Add ZeroResp and ZeroResp v2 (tournament rev 2.2) Aug 4, 2026
@Evreu1pro

Copy link
Copy Markdown
Author

Update for maintainers (2026-08-04)

Pushed revision 2.2 of ZeroResp v2 (short adaptive buffer, dual noise-aware forgiveness, smart harvest / grim probe).

CI was already green on the previous commit; this push should re-run the matrix.

Evidence package (algorithm + unit tests + Higher League / deep-validation tables):
https://github.com/Evreu1pro/ZeroResp

Why this is ready for the strategy list

Request: please review when you have bandwidth. If two strategies are too many, I can collapse to a single ZeroResp entry with the 2.2 logic.

Thank you for maintaining Axelrod — happy to address any requested API/doc changes promptly.

@Evreu1pro

Copy link
Copy Markdown
Author

CI fix for revision 2.2 (just pushed)

Addressed the two failures from the previous matrix run:

  1. test_reprPlayer.__repr__ appends base_epoch, so the TestPlayer name is now ZeroResp v2: 25 (was ZeroResp v2).
  2. Coverage 99.95% — added targeted tests for smart harvest / grim-probe paths (last-safe D, probe_fired, stochastic probe, non-grim probe window).

What is in this PR (for clarity):

  • ZeroResp — v1 backbone
  • ZeroResp v2 — class API, implementation revision 2.2 (short adaptive buffer, dual noise forgive, smart harvest / grim probe)

Happy to rename the display string to ZeroResp v2.2 if maintainers prefer that in tournament plots.

@drvinceknight

Copy link
Copy Markdown
Member

Can you fix the merge conflicts (#1497 fixed a problem with numpy).

Take numpy>=2.1 from Axelrod-Python#1497 (Fix numpy version). Keep float() cast
in fingerprint point generation for stable probe names across NumPy.
@Evreu1pro

Copy link
Copy Markdown
Author

Thanks @drvinceknight — merge conflicts with dev are resolved.

Took numpy>=2.1 from #1497 and kept the float() cast in fingerprint point generation. CI should re-run on this push.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants