Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: fix connected components test #112

Merged
merged 2 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ RenderSettings:
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.21176471, g: 0.23394229, b: 0.25882354, a: 1}
m_AmbientSkyColor: {r: 1, g: 1, b: 1, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
Expand Down Expand Up @@ -838,6 +838,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
maxAmmoCount: 0
_currentAmmoCount: 0
--- !u!114 &1220979210
MonoBehaviour:
m_ObjectHideFlags: 0
Expand All @@ -851,7 +852,6 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
emptyInventoryImage: {fileID: 2800000, guid: 8d003bcfe1c8c044893bf31bdf72fba7, type: 3}
inventoryObject: {fileID: 1220979207}
_inventorySize: 4
--- !u!114 &1220979211
MonoBehaviour:
Expand Down
155 changes: 77 additions & 78 deletions aplib.net-demo/Assets/Testing/AplibTests/ConnectedComponentsTests.cs
Original file line number Diff line number Diff line change
@@ -1,35 +1,86 @@
using Aplib.Core;
using Aplib.Core.Agents;
using Aplib.Core.Belief.Beliefs;
using Aplib.Core.Belief.BeliefSets;
using Aplib.Core.Desire.DesireSets;
using Aplib.Core.Desire.Goals;
using Aplib.Core.Desire.GoalStructures;
using Aplib.Core.Intent.Actions;
using Aplib.Core.Intent.Tactics;
using Aplib.Integrations.Unity;
using Aplib.Integrations.Unity.Actions;
using LevelGeneration;
using NUnit.Framework;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.TestTools;
using static Aplib.Core.Combinators;
using Action = Aplib.Core.Intent.Actions.Action<Testing.AplibTests.ConnectedComponentsBeliefSet>;
using BdiAgent = Aplib.Core.Agents.BdiAgent<Testing.AplibTests.ConnectedComponentsBeliefSet>;
using DesireSet = Aplib.Core.Desire.DesireSets.DesireSet<Testing.AplibTests.ConnectedComponentsBeliefSet>;
using Goal = Aplib.Core.Desire.Goals.Goal<Testing.AplibTests.ConnectedComponentsBeliefSet>;
using PrimitiveTactic = Aplib.Core.Intent.Tactics.PrimitiveTactic<Testing.AplibTests.ConnectedComponentsBeliefSet>;
using Tactic = Aplib.Core.Intent.Tactics.Tactic<Testing.AplibTests.ConnectedComponentsBeliefSet>;
using TransformPathfinderAction = Aplib.Integrations.Unity.Actions.TransformPathfinderAction<Testing.AplibTests.ConnectedComponentsBeliefSet>;

namespace Testing.AplibTests
{
public class ConnectedComponentsBeliefSet : BeliefSet
public class ConnectedComponentsBeliefSet : IBeliefSet
{
public Belief<GameObject, Rigidbody> PlayerRigidbody = new(
GameObject.Find("Player"),
x => x.GetComponent<Rigidbody>());
public Rigidbody PlayerRigidbody { get; } = GameObject.Find("Player").GetComponent<Rigidbody>();

public Belief<Queue<Vector3>, Vector3> GetCurrentTarget;

public Queue<Vector3> TargetPositionsInConnectedComponents { get; } = new(GetTargetPositionsInConnectedComponents());

public Queue<Vector3> TeleporterPositions { get; } = new(GetTeleporterLandingPoints());

public ConnectedComponentsBeliefSet()
{
GetCurrentTarget = new(
reference: TargetPositionsInConnectedComponents,
getObservationFromReference: positions => positions.Peek(),
shouldUpdate: () =>
{
if (TargetPositionsInConnectedComponents.Count == 0) return false;
SilasPeters marked this conversation as resolved.
Show resolved Hide resolved

Vector3 currentTarget = TargetPositionsInConnectedComponents.Peek();

if (Vector3.Distance(PlayerRigidbody.position, currentTarget) > 0.4f)
return false;

Debug.Log($"Reached target at {currentTarget}");
TargetPositionsInConnectedComponents.Dequeue();
Debug.Log($"Remaining targets: {TargetPositionsInConnectedComponents.Count}");

return TargetPositionsInConnectedComponents.Count > 0;
}
);
}

public void UpdateBeliefs()
{
GetCurrentTarget.UpdateBelief();
}

private static IEnumerable<Vector3> GetTargetPositionsInConnectedComponents()
{
GameObject gridGameObject = GameObject.Find("LevelGeneration");
LevelGenerationPipeline levelGenerationPipeline = gridGameObject.GetComponent<LevelGenerationPipeline>();
SpawningExtensions spawningExtensions = gridGameObject.GetComponent<SpawningExtensions>();

Vector3 centreOfCellHeightOffset = Vector3.up * 1.5f;

return levelGenerationPipeline.Grid
.DetermineConnectedComponents()
.Select(cells => spawningExtensions.CenterOfCell(cells.First()) + centreOfCellHeightOffset);
}

private static IEnumerable<Vector3> GetTeleporterLandingPoints()
=> GameObject.Find("Teleporters")
.GetComponentsInChildren<Teleporter.Teleporter>()
.Select(x => x.LandingPoint);
}

public class ConnectedComponentsTests
{
private const string _sceneName = "ConnectedComponentsTestScene";
private readonly Vector3 _centreOfCellHeightOffset = Vector3.up * 1.7f;

[SetUp]
public void SetUp()
Expand All @@ -47,85 +98,33 @@ public void SetUp()
[UnityTest]
public IEnumerator CanVisitEveryConnectedComponent()
{
// Arrange
ConnectedComponentsBeliefSet rootBeliefSet = new();
GameObject gridGameObject = GameObject.Find("LevelGeneration");
LevelGenerationPipeline levelGenerationPipeline = gridGameObject.GetComponent<LevelGenerationPipeline>();
SpawningExtensions spawningExtensions = gridGameObject.GetComponent<SpawningExtensions>();

// Arrange ==> Level information
Vector3[] cellsToVisit = levelGenerationPipeline.Grid.DetermineConnectedComponents()
.Select(cells => spawningExtensions.CenterOfCell(cells.First()) + _centreOfCellHeightOffset).ToArray();

Vector3[] teleporterPositions = GameObject.Find("Teleporters")
.GetComponentsInChildren<Teleporter.Teleporter>()
.Select(x => x.LandingPoint).ToArray();

int currentCellToVisitIndex = 0;
// Arrange
ConnectedComponentsBeliefSet connectedComponentBeliefSet = new();

Vector3 currentCellPosition()
{
return cellsToVisit[currentCellToVisitIndex];
}
// Remove doors and keys from the level.
GameObject doorsAndKeys = GameObject.Find("Doors and keys");
Object.Destroy(doorsAndKeys);

// Arrange ==> GoalStructure: Visit cell of the current connected component
TransformPathfinderAction<ConnectedComponentsBeliefSet> approachCurrentCellAction = new(
Tactic moveToNextComponent = new TransformPathfinderAction(
beliefSet => beliefSet.PlayerRigidbody,
currentCellPosition(),
1.4f);

Action<ConnectedComponentsBeliefSet> waitForTeleportAction = new(_ => { Debug.Log("Waiting for teleport..."); });
beliefSet => beliefSet.GetCurrentTarget,
1.5f);

PrimitiveTactic<ConnectedComponentsBeliefSet> approachCurrentCellTactic = new(approachCurrentCellAction);
PrimitiveTactic<ConnectedComponentsBeliefSet> waitForTeleportTactic = new(waitForTeleportAction,
beliefSet => teleporterPositions.Any(teleporterPosition =>
(teleporterPosition - ((Rigidbody)beliefSet.PlayerRigidbody).position).magnitude < 0.4f));
FirstOfTactic<ConnectedComponentsBeliefSet> waitForTeleportOrApproachCurrentCellTactic = new(
waitForTeleportTactic,
approachCurrentCellTactic);

Goal<ConnectedComponentsBeliefSet> approachCurrentCellGoal = new(waitForTeleportOrApproachCurrentCellTactic,
beliefSet => (currentCellPosition() - ((Rigidbody)beliefSet.PlayerRigidbody).position).magnitude <
1.5f);

PrimitiveGoalStructure<ConnectedComponentsBeliefSet> approachCurrentCellGoalStructure =
new(approachCurrentCellGoal);

RepeatGoalStructure<ConnectedComponentsBeliefSet> visitCurrentCellGoalStructure =
new(approachCurrentCellGoalStructure);

// Arrange ==> GoalStructure: Target the next cell until every cell has been targeted
Action<ConnectedComponentsBeliefSet> targetNextCellAction = new(_ =>
{
Debug.Log($"Reached cell at {currentCellPosition()}");
currentCellToVisitIndex++;
});

PrimitiveTactic<ConnectedComponentsBeliefSet> targetNextCellTactic = new(targetNextCellAction);
Goal<ConnectedComponentsBeliefSet> visitedEveryCellGoal = new(targetNextCellTactic,
_ => currentCellToVisitIndex >= cellsToVisit.Length);

PrimitiveGoalStructure<ConnectedComponentsBeliefSet> visitedEveryCellGoalStructure =
new(visitedEveryCellGoal);

// Arrange ==> GoalStructure: Visit every connected component
SequentialGoalStructure<ConnectedComponentsBeliefSet> visitCurrentCellAndVisitEveryCellGoalStructure =
new(visitCurrentCellGoalStructure, visitedEveryCellGoalStructure);

RepeatGoalStructure<ConnectedComponentsBeliefSet> visitEveryConnectedComponentGoalStructure =
new(visitCurrentCellAndVisitEveryCellGoalStructure);

// Arrange ==> DesireSet
DesireSet<ConnectedComponentsBeliefSet> desireSet = new(visitEveryConnectedComponentGoalStructure);
DesireSet visitAllComponents = new Goal(moveToNextComponent, HasVisitedEveryConnectedComponent);

// Act
BdiAgent<ConnectedComponentsBeliefSet> agent = new(rootBeliefSet, desireSet);
BdiAgent agent = new(connectedComponentBeliefSet, visitAllComponents);
AplibRunner testRunner = new(agent);

yield return testRunner.Test();

// Assert
Assert.AreEqual(CompletionStatus.Success, agent.Status);

// Local functions
static bool HasVisitedEveryConnectedComponent(ConnectedComponentsBeliefSet beliefSet)
=> beliefSet.TargetPositionsInConnectedComponents.Count == 0;
}
}
}