Files
Ajedrez_Purgatorio/Assets/Tests/EditMode/Purgatory/PurgatoryDuelRulesTests.cs
T
jimmyabv f7d56066c0 feat: Purgatory Final duel vs La Muerte + SFX wiring + runtime options menu
- Duel flow: mating piece vs boss while board collapses (PurgatoryDuelManager/Rules/UI/MuerteQuotes)
- GameState.PurgatoryDuel + CampaignManager rescue/restart hooks + SquareClick routing
- Dice-based rescue of most valuable dead identity; final defeat restarts Chapter 1
- 6 SFX clips wired in Ch1/2/3 via AudioClipAssigner
- OptionsMenuController runtime audio/graphics panel, wired to MainMenu
- Tests migrated to Assets/Tests/EditMode subfolders + PurgatoryDuelRulesTests (200 total)
- Editor tools: DiagAssign, SpeakerDatabaseSetup, PurgatoryCanvasMaintenance
2026-08-24 19:39:52 -03:00

167 lines
6.3 KiB
C#

using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
/// <summary>
/// Tests del Duelo del Purgatorio: curva de colapso, persecución del Jefe
/// y selección de casillas devoradas (purgatorio-final.md, criterio 7).
/// </summary>
public class PurgatoryDuelRulesTests
{
// ══════════════════════════════════════════════════════
// CURVA DE COLAPSO
// ══════════════════════════════════════════════════════
[Test]
public void TilesForTurn_GracePeriod_ReturnsZero()
{
Assert.AreEqual(0, PurgatoryDuelRules.TilesForTurn(1));
Assert.AreEqual(0, PurgatoryDuelRules.TilesForTurn(2));
}
[Test]
public void TilesForTurn_EarlyGame_ReturnsOne()
{
Assert.AreEqual(1, PurgatoryDuelRules.TilesForTurn(3));
Assert.AreEqual(1, PurgatoryDuelRules.TilesForTurn(7));
}
[Test]
public void TilesForTurn_Endgame_ReturnsTwo()
{
Assert.AreEqual(2, PurgatoryDuelRules.TilesForTurn(8));
Assert.AreEqual(2, PurgatoryDuelRules.TilesForTurn(20));
}
// ══════════════════════════════════════════════════════
// SELECCIÓN DE CASILLAS DEVORADAS
// ══════════════════════════════════════════════════════
[Test]
public void PickTilesToDevour_ExcludesBlockedSquares()
{
var excluded = new HashSet<Vector2Int> { new Vector2Int(4, 4), new Vector2Int(0, 0) };
var rng = new System.Random(12345);
List<Vector2Int> victims = PurgatoryDuelRules.PickTilesToDevour(6, excluded, rng);
Assert.AreEqual(6, victims.Count);
foreach (Vector2Int tile in victims)
{
Assert.IsFalse(excluded.Contains(tile), $"Casilla excluida devorada: {tile}");
Assert.IsTrue(PurgatoryDuelRules.IsInBounds(tile));
}
}
[Test]
public void PickTilesToDevour_NoDuplicates()
{
var rng = new System.Random(99);
List<Vector2Int> victims = PurgatoryDuelRules.PickTilesToDevour(10, new HashSet<Vector2Int>(), rng);
Assert.AreEqual(new HashSet<Vector2Int>(victims).Count, victims.Count);
}
[Test]
public void PickTilesToDevour_MoreThanAvailable_ReturnsAvailableOnly()
{
var excluded = new HashSet<Vector2Int>();
for (int x = 0; x < 8; x++)
for (int y = 0; y < 8; y++)
if (!(x == 0 && y == 0))
excluded.Add(new Vector2Int(x, y));
var rng = new System.Random(7);
List<Vector2Int> victims = PurgatoryDuelRules.PickTilesToDevour(5, excluded, rng);
Assert.AreEqual(1, victims.Count);
Assert.AreEqual(new Vector2Int(0, 0), victims[0]);
}
// ══════════════════════════════════════════════════════
// PERSECUCIÓN DEL JEFE
// ══════════════════════════════════════════════════════
[Test]
public void NextChaseStep_DiagonalTarget_StepsDiagonally()
{
var from = new Vector2Int(2, 2);
var target = new Vector2Int(5, 5);
Vector2Int step = PurgatoryDuelRules.NextChaseStep(from, target, new HashSet<Vector2Int>());
Assert.AreEqual(new Vector2Int(3, 3), step);
Assert.AreEqual(1, PurgatoryDuelRules.Chebyshev(step, from));
}
[Test]
public void NextChaseStep_BlockedDiagonal_FallsBackToAxis()
{
var from = new Vector2Int(2, 2);
var target = new Vector2Int(5, 5);
var blocked = new HashSet<Vector2Int> { new Vector2Int(3, 3) };
Vector2Int step = PurgatoryDuelRules.NextChaseStep(from, target, blocked);
Assert.AreNotEqual(new Vector2Int(3, 3), step, "No debe entrar en la casilla bloqueada.");
Assert.AreNotEqual(from, step, "Con eje libre debe rodear el hueco, no quedarse quieto.");
Assert.LessOrEqual(PurgatoryDuelRules.Chebyshev(step, target), PurgatoryDuelRules.Chebyshev(from, target),
"El paso axial de rodeo no debe alejar al Jefe del objetivo.");
}
[Test]
public void NextChaseStep_Adjacent_ReachesPlayer()
{
var from = new Vector2Int(3, 3);
var player = new Vector2Int(4, 3);
Vector2Int step = PurgatoryDuelRules.NextChaseStep(from, player, new HashSet<Vector2Int>());
Assert.AreEqual(player, step);
}
[Test]
public void NextChaseStep_AllPathsBlocked_StaysInPlace()
{
var from = new Vector2Int(0, 0);
var target = new Vector2Int(4, 4);
var blocked = new HashSet<Vector2Int>
{
new Vector2Int(1, 0),
new Vector2Int(0, 1),
new Vector2Int(1, 1)
};
Vector2Int step = PurgatoryDuelRules.NextChaseStep(from, target, blocked);
Assert.AreEqual(from, step);
}
[Test]
public void NextChaseStep_AlwaysReducesOrMaintainsChebyshev()
{
var rng = new System.Random(2026);
for (int i = 0; i < 200; i++)
{
var from = new Vector2Int(rng.Next(8), rng.Next(8));
var target = new Vector2Int(rng.Next(8), rng.Next(8));
var blocked = new HashSet<Vector2Int>();
int blockCount = rng.Next(4);
for (int b = 0; b < blockCount; b++)
blocked.Add(new Vector2Int(rng.Next(8), rng.Next(8)));
Vector2Int step = PurgatoryDuelRules.NextChaseStep(from, target, blocked);
Assert.LessOrEqual(
PurgatoryDuelRules.Chebyshev(step, target),
PurgatoryDuelRules.Chebyshev(from, target),
$"from={from} target={target} blocked=[{string.Join(";", blocked)}]");
Assert.LessOrEqual(PurgatoryDuelRules.Chebyshev(step, from), 1, "El Jefe mueve como rey (máx 1 casilla por paso).");
if (!blocked.Contains(step) || step == from)
Assert.IsTrue(true);
}
}
}