This commit is contained in:
2022-12-15 23:29:02 +01:00
parent 95220bec08
commit 4f57b57a00
24 changed files with 1695 additions and 81 deletions

View File

@@ -18,13 +18,20 @@ namespace EscapeRoomEngine.Engine.Runtime.Measurements
private static Dictionary<int, PuzzleMeasurement> _runningMeasurements;
private static Session _currentSession;
public static float AverageTime(IEnumerable<PuzzleModuleDescription> puzzles) =>
puzzles.Sum(puzzle => PuzzleStorage.Instance.Load(puzzle).AverageTimeToSolve);
public static float AverageTime(PuzzleModuleDescription puzzle) =>
PuzzleStorage.Instance.Load(puzzle).AverageTimeToSolve;
public static float AverageTime(IEnumerable<PuzzleModuleDescription> puzzles) => puzzles.Sum(AverageTime);
public static float AverageTime(Room room) =>
room.puzzles.Sum(puzzle => AverageTime((PuzzleModuleDescription)puzzle.description));
public static float EstimateTime(PuzzleModuleDescription puzzle) =>
PuzzleStorage.Instance.Load(puzzle).EstimateTimeToSolve(SessionPercentile());
public static float EstimateTime(IEnumerable<PuzzleModuleDescription> puzzles) => puzzles.Sum(EstimateTime);
public static float EstimateTime(Room room) =>
room.puzzles.Sum(puzzle => EstimateTime((PuzzleModuleDescription)puzzle.description));
public static float SessionPercentile() => _currentSession?.MeanPercentile ?? 0.5f;
public static void StartMeasuring(PuzzleModuleDescription puzzle)
{
_runningMeasurements[puzzle.Id] = new PuzzleMeasurement

View File

@@ -17,7 +17,8 @@ namespace EscapeRoomEngine.Engine.Runtime.Measurements
public float TotalTimeSpentOnPuzzle => Measurements.Sum(measurement => measurement.Time);
public float AverageTimeToSolve => Measurements.Count > 0 ? TotalTimeSpentOnPuzzle / Measurements.Count : 0f;
public NormalDistribution Distribution => new(TimesAsSamples());
[UsedImplicitly]
public Puzzle() {}
public Puzzle(PuzzleModuleDescription puzzle)
@@ -25,6 +26,23 @@ namespace EscapeRoomEngine.Engine.Runtime.Measurements
ID = puzzle.Id;
}
/// <summary>
/// Estimate how long a player in the given percentile will take to solve this puzzle.
/// </summary>
public float EstimateTimeToSolve(float percentile) => Distribution.InverseCumulative(percentile);
private float[] TimesAsSamples()
{
var samples = new float[Measurements.Count];
for (var i = 0; i < Measurements.Count; i++)
{
samples[i] = Measurements[i].Time;
}
return samples;
}
public override string ToString()
{
return $"{Engine.Theme.GetPuzzle(ID)}: avg. {AverageTimeToSolve.ToTimeSpan():m':'ss} ({string.Join(", ", Measurements)})";

View File

@@ -8,6 +8,8 @@ namespace EscapeRoomEngine.Engine.Runtime.Measurements
{
public class PuzzleStorage : MonoBehaviour
{
private const int SchemaVersion = 1;
public static PuzzleStorage Instance { get; private set; }
[SerializeField]
@@ -17,7 +19,20 @@ namespace EscapeRoomEngine.Engine.Runtime.Measurements
private void OnEnable()
{
_realm = Realm.GetInstance(databasePath);
var config = new RealmConfiguration
{
SchemaVersion = SchemaVersion,
MigrationCallback = (migration, oldSchemaVersion) =>
{
if (oldSchemaVersion < 1)
{
// migration from version 0 to 1
}
Logger.Log($"Migrated database to version {SchemaVersion}", LogType.Measuring);
}
};
_realm = Realm.GetInstance(config.ConfigWithPath(databasePath));
}
private void Awake()
@@ -41,10 +56,7 @@ namespace EscapeRoomEngine.Engine.Runtime.Measurements
{
session.Time = time;
_realm.Write(() =>
{
_realm.Add(session);
});
_realm.Write(() => _realm.Add(session));
}
#endregion
@@ -84,6 +96,9 @@ namespace EscapeRoomEngine.Engine.Runtime.Measurements
// add solved puzzle to session
session.PuzzlesSolved.Add(found);
// add time percentile to session
session.Percentiles.Add(found.Distribution.Cumulative(measurement.Time));
});
}

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using EscapeRoomEngine.Engine.Runtime.Utilities;
using JetBrains.Annotations;
using MongoDB.Bson;
@@ -13,8 +14,11 @@ namespace EscapeRoomEngine.Engine.Runtime.Measurements
[PrimaryKey]
public ObjectId ID { get; set; }
public float Time { get; set; }
public IList<float> Percentiles { get; }
public IList<Puzzle> PuzzlesSolved { get; }
public float MeanPercentile => Percentiles.Count == 0 ? .5f : Probability.Mean(Percentiles.ToArray());
[UsedImplicitly]
public Session()
{