Scale lesson skill gain by the teacher's subject skill.
Hiring a 78-math applicant already cost more than a 41; the class now actually learns faster when that teacher is in the room. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -13,8 +13,8 @@ public class LessonLearningTests
|
||||
[Fact]
|
||||
public void HungryLearnsLessThanFull()
|
||||
{
|
||||
var full = LessonLearning.Gain(50, Math, share: 1, lessonSkillPerHour: 0.05f, hours: 0.75f, hunger: 1f, traitOffset: 0);
|
||||
var hungry = LessonLearning.Gain(50, Math, share: 1, lessonSkillPerHour: 0.05f, hours: 0.75f, hunger: 0.1f, traitOffset: 0);
|
||||
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);
|
||||
@@ -24,9 +24,60 @@ public class LessonLearningTests
|
||||
[Fact]
|
||||
public void DiligentOffset_RaisesTheGain()
|
||||
{
|
||||
var plain = LessonLearning.Gain(50, Math, 1, 0.05f, 1f, 1f, 0);
|
||||
var diligent = LessonLearning.Gain(50, Math, 1, 0.05f, 1f, 1f, 8);
|
||||
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 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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,6 +129,67 @@ public class LessonTeacherPresentTests
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WeakTeacher_GainsLessThanStrong()
|
||||
{
|
||||
var (school, homeroom, pupilId, teacherId) = StaffedMath();
|
||||
using (school)
|
||||
{
|
||||
AdvanceTo(school, LessonStart);
|
||||
SetPlace(school, pupilId, homeroom);
|
||||
SetPlace(school, teacherId, homeroom);
|
||||
SetSkill(school, teacherId, "Mathematics", 20);
|
||||
var beforeWeak = SkillOf(school, pupilId, "Mathematics");
|
||||
LessonLearningSystem.Apply(school, 45);
|
||||
var weakGain = SkillOf(school, pupilId, "Mathematics") - beforeWeak;
|
||||
|
||||
SetSkill(school, pupilId, "Mathematics", beforeWeak);
|
||||
SetSkill(school, teacherId, "Mathematics", 80);
|
||||
var beforeStrong = SkillOf(school, pupilId, "Mathematics");
|
||||
LessonLearningSystem.Apply(school, 45);
|
||||
var strongGain = SkillOf(school, pupilId, "Mathematics") - beforeStrong;
|
||||
|
||||
Assert.True(weakGain > 0);
|
||||
Assert.True(strongGain > weakGain);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MissingTeacherSkillKey_StillGains()
|
||||
{
|
||||
var (school, homeroom, pupilId, teacherId) = StaffedMath();
|
||||
using (school)
|
||||
{
|
||||
AdvanceTo(school, LessonStart);
|
||||
SetPlace(school, pupilId, homeroom);
|
||||
SetPlace(school, teacherId, homeroom);
|
||||
ClearSkill(school, teacherId, "Mathematics");
|
||||
var before = SkillOf(school, pupilId, "Mathematics");
|
||||
|
||||
LessonLearningSystem.Apply(school, 45);
|
||||
|
||||
Assert.True(SkillOf(school, pupilId, "Mathematics") > before);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TeacherSkill_DoesNotRescueAbsence()
|
||||
{
|
||||
var (school, homeroom, pupilId, teacherId) = StaffedMath();
|
||||
using (school)
|
||||
{
|
||||
AdvanceTo(school, LessonStart);
|
||||
SetPlace(school, pupilId, homeroom);
|
||||
SetPlace(school, teacherId, "restroom-1");
|
||||
SetSkill(school, teacherId, "Mathematics", 100);
|
||||
var before = SkillOf(school, pupilId, "Mathematics");
|
||||
|
||||
LessonLearningSystem.Apply(school, 45);
|
||||
|
||||
Assert.Equal(before, SkillOf(school, pupilId, "Mathematics"));
|
||||
}
|
||||
}
|
||||
|
||||
private static (School School, string Homeroom, string PupilId, string TeacherId) StaffedMath(
|
||||
string? teacherId = null)
|
||||
{
|
||||
@@ -206,6 +267,34 @@ public class LessonTeacherPresentTests
|
||||
return value;
|
||||
}
|
||||
|
||||
private static void SetSkill(School school, string personId, string skill, float value)
|
||||
{
|
||||
var query = new QueryDescription().WithAll<PersonIdentity, PersonSkills>();
|
||||
school.World.Query(
|
||||
in query,
|
||||
(ref PersonIdentity identity, ref PersonSkills skills) =>
|
||||
{
|
||||
if (identity.Id.Equals(personId, StringComparison.Ordinal))
|
||||
{
|
||||
skills.Values[skill] = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void ClearSkill(School school, string personId, string skill)
|
||||
{
|
||||
var query = new QueryDescription().WithAll<PersonIdentity, PersonSkills>();
|
||||
school.World.Query(
|
||||
in query,
|
||||
(ref PersonIdentity identity, ref PersonSkills skills) =>
|
||||
{
|
||||
if (identity.Id.Equals(personId, StringComparison.Ordinal))
|
||||
{
|
||||
skills.Values.Remove(skill);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static (DefCatalog Catalog, MapLayout Map) Vanilla()
|
||||
{
|
||||
var root = Path.Combine(AppContext.BaseDirectory, "vanilla");
|
||||
|
||||
Reference in New Issue
Block a user