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],
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
# 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)