X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fworld%2Fsim.cpp;h=350d2440f0a8739a877bcbf86c6b7072bcca8477;hb=1f8fe0fd81053821f26787e9809cd1a13f747819;hp=edf7bfe4f02f88954c2fd140161e07bff785d7fa;hpb=392826deaf802ac0960ed3924a3f98b9d18d381b;p=blobs.git diff --git a/src/world/sim.cpp b/src/world/sim.cpp index edf7bfe..350d244 100644 --- a/src/world/sim.cpp +++ b/src/world/sim.cpp @@ -1,16 +1,74 @@ +#include "Record.hpp" #include "Simulation.hpp" #include "Body.hpp" #include "Planet.hpp" #include "Sun.hpp" #include "../creature/Creature.hpp" +#include "../ui/string.hpp" #include +#include namespace blobs { namespace world { +int Record::Update(creature::Creature &c, double value, double time) noexcept { + int found = -1; + for (int i = 0; i < MAX; ++i) { + if (value > rank[i].value) { + found = i; + break; + } + } + if (found < 0) { + return -1; + } + int previous = -1; + for (int i = 0; i < MAX; ++i) { + if (rank[i].holder == &c) { + previous = i; + break; + } + } + if (previous < 0) { + // move all below down by one + std::copy_backward(rank + found, rank + MAX - 1, rank + MAX); + } else if (found > previous) { + // better than last, but not an improvement + // this ensures only one slot occupied per creature + return found; + } else if (found < previous) { + // move all in between down by one + std::copy_backward(rank + found, rank + previous, rank + previous + 1); + } + // insert new + rank[found].holder = &c; + rank[found].value = value; + rank[found].time = time; + return found; +} + +std::string Record::ValueString(int i) const { + if (i < 0 || i >= MAX || !rank[i].holder) { + return "—"; + } + switch (type) { + default: + case VALUE: + return ui::DecimalString(rank[i].value, 2); + case LENGTH: + return ui::LengthString(rank[i].value); + case MASS: + return ui::MassString(rank[i].value); + case PERCENTAGE: + return ui::PercentageString(rank[i].value); + case TIME: + return ui::TimeString(rank[i].value); + } +} + Simulation::Simulation(Body &r, app::Assets &assets) : root(r) , assets(assets) @@ -82,41 +140,66 @@ void Simulation::SetDead(creature::Creature *c) { } void Simulation::CheckRecords(creature::Creature &c) noexcept { - if (c.Age() > records[0].value) { - records[0].value = c.Age(); - records[0].time = Time(); - records[0].holder = &c; - } - if (c.Mass() > records[1].value) { - records[1].value = c.Mass(); - records[1].time = Time(); - records[1].holder = &c; - } - if (c.Size() > records[2].value) { - records[2].value = c.Size(); - records[2].time = Time(); - records[2].holder = &c; - } - if (c.Strength() > records[3].value) { - records[3].value = c.Strength(); - records[3].time = Time(); - records[3].holder = &c; - } - if (c.Stamina() > records[4].value) { - records[4].value = c.Stamina(); - records[4].time = Time(); - records[4].holder = &c; - } - if (c.Dexerty() > records[5].value) { - records[5].value = c.Dexerty(); - records[5].time = Time(); - records[5].holder = &c; - } - if (c.Intelligence() > records[6].value) { - records[6].value = c.Intelligence(); - records[6].time = Time(); - records[6].holder = &c; + { // age + creature::Creature *prev = records[0].rank[0].holder; + int rank = records[0].Update(c, c.Age(), time); + if (rank == 0 && prev && prev != &c) { + LogRecord(records[0]); + } } + { // mass + creature::Creature *prev = records[1].rank[0].holder; + int rank = records[1].Update(c, c.Mass(), time); + if (rank == 0 && prev && prev != &c) { + LogRecord(records[1]); + } + } + { // size + creature::Creature *prev = records[2].rank[0].holder; + int rank = records[2].Update(c, c.Size(), time); + if (rank == 0 && prev && prev != &c) { + LogRecord(records[2]); + } + } + { // strength + creature::Creature *prev = records[3].rank[0].holder; + int rank = records[3].Update(c, c.Strength(), time); + if (rank == 0 && prev && prev != &c) { + LogRecord(records[3]); + } + } + { // stamina + creature::Creature *prev = records[4].rank[0].holder; + int rank = records[4].Update(c, c.Stamina(), time); + if (rank == 0 && prev && prev != &c) { + LogRecord(records[4]); + } + } + { // dexerty + creature::Creature *prev = records[5].rank[0].holder; + int rank = records[5].Update(c, c.Dexerty(), time); + if (rank == 0 && prev && prev != &c) { + LogRecord(records[5]); + } + } + { // intelligence + creature::Creature *prev = records[6].rank[0].holder; + int rank = records[6].Update(c, c.Intelligence(), time); + if (rank == 0 && prev && prev != &c) { + LogRecord(records[6]); + } + } +} + +void Simulation::LogRecord(const Record &r) { + Log() << "at age " << ui::TimeString(r.rank[0].holder->Age()) << " " + << r.rank[0].holder->Name() << " broke the " << r.name << " record of " + << r.ValueString(1) << " by " << r.rank[1].holder->Name() + << " (established " << ui::TimeString(r.rank[1].time) << ")" << std::endl; +} + +std::ostream &Simulation::Log() { + return std::cout << '[' << ui::TimeString(Time()) << "] "; } }