Пример #1
0
 def ReadCityFromDb(cls, city_id, manager):
     new_city = cls(city_id)
     new_city.original_read_dict = manager.ReadTable(
         MEGUCA_ROW,
         MEGUCA_PRIMARY_KEYS, {"CityID": new_city.city_id},
         table=MEGUCA_TABLE_NAME,
         read_flag="may_be_modified")
     used_ids = list()
     for primary_keys, row_tuple in new_city.original_read_dict.items():
         row = row_tuple[0]
         new_meguca = Meguca.FromMegucaRow(row,
                                           new_city.MegucaCleanupFunctor)
         new_city.friends_tracker.Set(new_meguca, new_meguca.friends)
         new_city.family_tracker.Set(new_meguca, new_meguca.family)
         used_ids.append(new_meguca.id)
         new_city.all_names.add(new_meguca.GetFullName())
         if new_meguca.is_dead:
             new_city.dead_megucas[new_meguca.id] = new_meguca
         elif new_meguca.is_witch:
             new_city.witches[new_meguca.id] = new_meguca
         elif new_meguca.is_contracted:
             new_city.contracted_megucas[new_meguca.id] = new_meguca
         else:
             new_city.potential_megucas[new_meguca.id] = new_meguca
     used_ids.sort()
     # Override allocator with new ID set.
     Meguca.ALLOCATOR = UniqueIDAllocator.RestoreFromSaved(
         used_ids[1], list(set(range(0, used_ids[1] + 1)) - set(used_ids)))
     all_potential_gucas = {
         **new_city.contracted_megucas,
         **new_city.potential_megucas,
         **new_city.witches,
         **new_city.dead_megucas
     }
     # We can only do this once all megucas are in place.
     for meguca in all_potential_gucas.values():
         meguca.ReconstructFriendsAndFamily(all_potential_gucas)
     return new_city
# Check db explicitly without using object.
c = manager.connection.cursor()
rows = c.execute("SELECT * FROM {}".format(EXCEPTION_TABLE_NAME))

# print columns
print([x[0] for x in c.description])

# print rows
for row in rows:
    print(row)

# Test writing and reading a meguca from the DB. This ignores reconstructing friends, etc.

manager.CreateTableIfDoesNotExist(MEGUCA_TABLE_FIELDS, table=MEGUCA_TABLE_NAME)

new_meguca = Meguca.MakeNew()

print("Full Random Meguca:")
print(new_meguca)

print('Writing Meguca to DB...')

meguca_row = new_meguca.ToMegucaRow(fake_city_id)

# One row dict.
write_dict = {
    frozenset(getattr(meguca_row, x) for x in MEGUCA_PRIMARY_KEYS):
    (meguca_row, True)
}

manager.WriteTable(write_dict, [x[0] for x in MEGUCA_TABLE_FIELDS],
Пример #3
0
    def NewSensorMeguca(self,
                        targets: Dict[str, int] = None,
                        sensors: Dict[str, int] = None,
                        friends: List[Any] = None) -> Meguca:
        if friends is None:
            friends = []
        else:
            # rare edge case check to avoid infinite loops
            all_surnames = set(x.surname for x in friends)
            if len(all_surnames
                   ) >= len(LAST_NAME_POOL) + len(EITHER_NAME_POOL):
                warnings.warn("Exhausted surname pool! Dropping a friend.")
                friends.remove(random.choice(friends))
        # Make a new meguca, and also figure out who their friends/family are, if any. friends, if provided, will be used as a list of guaranteed friends.
        # Returns whoever this meguca is.
        new_meguca = Meguca.MakeNew(targets,
                                    sensors,
                                    cleanup=self.MegucaCleanupFunctor)
        new_meguca.friends = self.friends_tracker.Get(new_meguca)
        new_meguca.family = self.family_tracker.Get(new_meguca)
        while True:
            # avoid same surname
            proceed = True
            while True:
                proceed = True
                for friend in friends:
                    if friend.surname == new_meguca.surname:
                        new_meguca.RandomizeName()
                        proceed = False
                        break
                if proceed:
                    break
            if not proceed:
                continue
            while True:
                proceed = True
                if new_meguca.GetFullName() in self.all_names:
                    new_meguca.RandomizeName()
                    proceed = False
                else:
                    break
            if proceed:
                break
        self.all_names.add(new_meguca.GetFullName())
        # A simple approach. Each meguca has as many contractable friends as their friendships stat.
        # It is assumed that all of these must lie in the pool of potential_megucas + contracted_megucas + witches + dead_megucas = MEGUCA_POPULATION + dead_megucas (we include dead megucas to prevent numerical issues)
        # The probability of a given friend of theirs already being in the pool controlled by frienships stat and this population count.
        # However, we must first determine family, as that supersedes friends.
        already_used = set([x.id for x in friends])
        # TODO: It would be fun flavorwise for girls who have dead/witched friends to be able to bring them back in their wish,
        # or to have altered stats, but we can save that for later (especially since the stats would have to somehow work with
        # the sensors.)
        # We will need this merged dict no matter what anyway.
        all_potential_gucas = {
            **self.contracted_megucas,
            **self.potential_megucas,
            **self.witches,
            **self.dead_megucas
        }
        friendship_weights = {
            id: meguca.stats["friendships"]
            for id, meguca in all_potential_gucas.items()
            if meguca not in friends
        }
        for id, meguca in all_potential_gucas.items():
            if meguca.surname == new_meguca.surname:
                self.family_tracker.Connect(meguca, new_meguca)
                del friendship_weights[id]
                already_used.add(id)
        # add guaranteed friends
        self.friends_tracker.AddMultiple(new_meguca, friends)
        for _ in range(new_meguca.stats["friendships"] - len(friends)):
            prob_already_exists_friend = (
                sum(weight for id, weight in friendship_weights.items()) /
                (3 * (MEGUCA_POPULATION + len(self.dead_megucas))))
            # if friend doesn't already exist, we ignore it unless they get pulled later by the NewMegucaFromFriend event.
            if random.random() < prob_already_exists_friend:
                while True:
                    id = WeightedDictRandom(friendship_weights)[0]
                    if id in already_used:
                        continue
                    meguca = all_potential_gucas[id]
                    self.friends_tracker.Connect(new_meguca, meguca)
                    # NOTE: This procedure will often give megucas more friends than their friendships stat strictly dictates.
                    # This is FINE, and a deliberate feature, not a bug. It could be corrected here with an if statement if we really
                    # wanted.
                    del friendship_weights[id]
                    already_used.add(id)
                    break

        self.potential_megucas[new_meguca.id] = new_meguca
        return new_meguca
Пример #4
0
# Test Script to test some stuff
from copy import copy

from Objs.Utils.GlobalDefines import *

from Objs.Meguca.Meguca import Meguca

new_meguca = Meguca.MakeNew()

print("Full Random Meguca:")
print(new_meguca)

print("Available Stats: (Note: this ignores sensor visibility for now)")
for stat in MEGUCA_STATS:
    print(stat)

targets = {}
sensors = {}
while True:
    oldtargets = copy(targets)
    oldsensors = copy(sensors)
    try:
        str_sensor = input("Set Sensor? (Type name)")
        assert (str_sensor in MEGUCA_STATS)
        sensor_level = int(input("Set Sensor Level (0-indexed)?"))
        sensors[str_sensor] = sensor_level
        target = int(input("Set Target? (-1 if nothing)"))
        if target != -1:
            targets[str_sensor] = target
        new_meguca = Meguca.MakeNew(targets, sensors)
        print(new_meguca)