Locker and home do not count. A pack without the field keeps vanilla 0.5. Co-authored-by: Cursor <cursoragent@cursor.com>
149 lines
5.0 KiB
C#
149 lines
5.0 KiB
C#
using HSchool.Content;
|
|
using HSchool.People;
|
|
|
|
namespace HSchool.Ai.Tests;
|
|
|
|
public class LessonLearningTests
|
|
{
|
|
private static readonly SkillDef Math = new()
|
|
{
|
|
DefName = "Mathematics",
|
|
Range = new IntRange { Min = 0, Max = 100 },
|
|
};
|
|
|
|
[Fact]
|
|
public void HungryLearnsLessThanFull()
|
|
{
|
|
var full = LessonLearning.Gain(50, Math, share: 1, lessonSkillPerHour: 0.05f, hours: 0.75f, hunger: 1f, traitOffset: 0, teacherSkill: 100);
|
|
var hungry = LessonLearning.Gain(50, Math, share: 1, lessonSkillPerHour: 0.05f, hours: 0.75f, hunger: 0.1f, traitOffset: 0, teacherSkill: 100);
|
|
|
|
Assert.True(full > 50);
|
|
Assert.True(hungry > 50);
|
|
Assert.True(full - 50 > hungry - 50);
|
|
}
|
|
|
|
[Fact]
|
|
public void DiligentOffset_RaisesTheGain()
|
|
{
|
|
var plain = LessonLearning.Gain(50, Math, 1, 0.05f, 1f, 1f, 0, 100);
|
|
var diligent = LessonLearning.Gain(50, Math, 1, 0.05f, 1f, 1f, 8, 100);
|
|
|
|
Assert.True(diligent > plain);
|
|
}
|
|
|
|
[Fact]
|
|
public void TeacherSkill20_GainsLessThan80()
|
|
{
|
|
var weak = LessonLearning.Gain(50, Math, 1, 0.05f, 1f, 1f, 0, 20);
|
|
var strong = LessonLearning.Gain(50, Math, 1, 0.05f, 1f, 1f, 0, 80);
|
|
|
|
Assert.True(weak > 50);
|
|
Assert.True(strong - 50 > weak - 50);
|
|
}
|
|
|
|
[Fact]
|
|
public void TeacherFactor_MatchesNeedCurve()
|
|
{
|
|
Assert.Equal(LessonLearning.NeedFactor(0f), LessonLearning.TeacherFactor(0f));
|
|
Assert.Equal(LessonLearning.NeedFactor(1f), LessonLearning.TeacherFactor(100f));
|
|
Assert.Equal(LessonLearning.NeedFactor(0.2f), LessonLearning.TeacherFactor(20f));
|
|
}
|
|
|
|
[Fact]
|
|
public void MultiSkillSubject_AveragesListedSkills_NotDictionaryOrder()
|
|
{
|
|
var (catalog, _) = Fixtures.Vanilla();
|
|
var subject = catalog.Subjects["PrimarySchool"];
|
|
var skills = new Dictionary<string, float>(StringComparer.Ordinal)
|
|
{
|
|
["Biology"] = 100,
|
|
["Literature"] = 100,
|
|
["RussianLanguage"] = 100,
|
|
["Mathematics"] = 0,
|
|
};
|
|
|
|
var average = LessonLearning.AverageTeacherSkill(subject, skills, catalog);
|
|
|
|
Assert.Equal(75f, average);
|
|
Assert.NotEqual(skills.Values.First(), average);
|
|
}
|
|
|
|
[Fact]
|
|
public void ColdLearnsLessThanWarm()
|
|
{
|
|
var warm = LessonLearning.Gain(50, Math, 1, 0.05f, 1f, 1f, 0, 100, warmth: 1f);
|
|
var cold = LessonLearning.Gain(50, Math, 1, 0.05f, 1f, 1f, 0, 100, warmth: 0.1f);
|
|
|
|
Assert.True(cold > 50);
|
|
Assert.True(warm - 50 > cold - 50);
|
|
}
|
|
|
|
[Fact]
|
|
public void HungerStillCutsWhenWarm()
|
|
{
|
|
var full = LessonLearning.Gain(50, Math, 1, 0.05f, 1f, hunger: 1f, traitOffset: 0, teacherSkill: 100, warmth: 1f);
|
|
var hungry = LessonLearning.Gain(50, Math, 1, 0.05f, 1f, hunger: 0.1f, traitOffset: 0, teacherSkill: 100, warmth: 1f);
|
|
|
|
Assert.True(full - 50 > hungry - 50);
|
|
Assert.Equal(
|
|
LessonLearning.Gain(50, Math, 1, 0.05f, 1f, 0.1f, 0, 100),
|
|
hungry);
|
|
}
|
|
|
|
[Fact]
|
|
public void MissingWarmthArgument_DefaultsToFull()
|
|
{
|
|
var implied = LessonLearning.Gain(50, Math, 1, 0.05f, 1f, 0.1f, 0, 100);
|
|
var explicitWarm = LessonLearning.Gain(50, Math, 1, 0.05f, 1f, 0.1f, 0, 100, warmth: 1f);
|
|
|
|
Assert.Equal(explicitWarm, implied);
|
|
}
|
|
|
|
[Fact]
|
|
public void MissingTextbook_HalvesGain()
|
|
{
|
|
var withBook = LessonLearning.Gain(50, Math, 1, 0.05f, 1f, 1f, 0, 100, warmth: 1f, textbookFactor: 1f);
|
|
var without = LessonLearning.Gain(50, Math, 1, 0.05f, 1f, 1f, 0, 100, warmth: 1f, textbookFactor: 0.5f);
|
|
|
|
Assert.Equal((withBook - 50) * 0.5f, without - 50, precision: 5);
|
|
}
|
|
|
|
[Fact]
|
|
public void TextbookInBag_OnlyThatSubjectCounts()
|
|
{
|
|
var items = new[]
|
|
{
|
|
new InventoryItem("Textbook", null, 1f, ItemLocations.Bag, "Literature"),
|
|
new InventoryItem("Textbook", null, 1f, ItemLocations.Locker, "Mathematics"),
|
|
};
|
|
|
|
Assert.False(LessonLearning.HasTextbookInBag(items, "Mathematics"));
|
|
Assert.True(LessonLearning.HasTextbookInBag(items, "Literature"));
|
|
}
|
|
|
|
[Fact]
|
|
public void TextbookAtHome_DoesNotCount()
|
|
{
|
|
var items = new[]
|
|
{
|
|
new InventoryItem("Textbook", null, 1f, ItemLocations.Home, "Mathematics"),
|
|
};
|
|
|
|
Assert.False(LessonLearning.HasTextbookInBag(items, "Mathematics"));
|
|
}
|
|
|
|
[Fact]
|
|
public void MissingTeacherSkill_UsesRangeMin_AndStillGains()
|
|
{
|
|
var (catalog, _) = Fixtures.Vanilla();
|
|
var subject = catalog.Subjects["Mathematics"];
|
|
var min = catalog.Skills["Mathematics"].Range.Min;
|
|
var average = LessonLearning.AverageTeacherSkill(subject, new Dictionary<string, float>(), catalog);
|
|
var gained = LessonLearning.Gain(50, Math, 1, 0.05f, 1f, 1f, 0, average);
|
|
|
|
Assert.Equal(min, average);
|
|
Assert.True(gained > 50);
|
|
Assert.True(gained < LessonLearning.Gain(50, Math, 1, 0.05f, 1f, 1f, 0, 100));
|
|
}
|
|
}
|