Created
May 31, 2020 19:33
-
-
Save dwightguth/e79e21309efd53b3281404f4cfe12220 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from z3 import * | |
| npcs = [] | |
| biomes = [] | |
| class npc(object): | |
| def __init__(self, name): | |
| self.name = name | |
| self.sells = True | |
| self._loves = [] | |
| self._likes = [] | |
| self._dislikes = [] | |
| self._hates = [] | |
| self.near = {} | |
| npcs.append(self) | |
| def loves(self, *loves): | |
| self._loves = loves | |
| def likes(self, *likes): | |
| self._likes = likes | |
| def dislikes(self, *dislikes): | |
| self._dislikes = dislikes | |
| def hates(self, *hates): | |
| self._hates = hates | |
| guide = npc("Guide") | |
| merchant = npc("Merchant") | |
| zoologist = npc("Zoologist") | |
| golfer = npc("Golfer") | |
| nurse = npc("Nurse") | |
| tavernkeep = npc("Tavernkeep") | |
| party_girl = npc("Party girl") | |
| wizard = npc("Wizard") | |
| demolitionist = npc("Demolitionist") | |
| goblin_tinkerer = npc("Goblin tinkerer") | |
| clothier = npc("Clothier") | |
| dye_trader = npc("Dye trader") | |
| arms_dealer = npc("Arms dealer") | |
| steampunker = npc("Steampunker") | |
| dryad = npc("Dryad") | |
| painter = npc("Painter") | |
| witch_doctor = npc("Witch doctor") | |
| stylist = npc("Stylist") | |
| angler = npc("Angler") | |
| pirate = npc("Pirate") | |
| mechanic = npc("Mechanic") | |
| tax_collector = npc("Tax collector") | |
| cyborg = npc("Cyborg") | |
| #santa = npc("Santa claus") | |
| truffle = npc("Truffle") | |
| class biome(object): | |
| def __init__(self, name): | |
| self.name = name | |
| biomes.append(self) | |
| forest = biome("Forest") | |
| hallow = biome("Hallow") | |
| underground = biome("Underground") | |
| desert = biome("Desert") | |
| jungle = biome("Jungle") | |
| ocean = biome("Ocean") | |
| snow = biome("Snow") | |
| mushroom = biome("Mushroom") | |
| guide.likes(forest, clothier, zoologist) | |
| guide.dislikes(ocean, steampunker) | |
| guide.hates(painter) | |
| guide.sells = False | |
| merchant.likes(forest, golfer, nurse) | |
| merchant.dislikes(desert, tax_collector) | |
| merchant.hates(angler) | |
| zoologist.loves(witch_doctor) | |
| zoologist.likes(forest, golfer) | |
| zoologist.dislikes(desert, angler) | |
| zoologist.hates(arms_dealer) | |
| golfer.loves(angler) | |
| golfer.likes(forest, painter, zoologist) | |
| golfer.dislikes(underground, pirate) | |
| golfer.hates(merchant) | |
| nurse.loves(arms_dealer) | |
| nurse.likes(hallow, wizard) | |
| nurse.dislikes(snow, dryad, party_girl) | |
| nurse.hates(zoologist) | |
| tavernkeep.loves(demolitionist) | |
| tavernkeep.likes(hallow, goblin_tinkerer) | |
| tavernkeep.dislikes(snow, guide) | |
| tavernkeep.hates(dye_trader) | |
| party_girl.loves(wizard, zoologist) | |
| party_girl.likes(hallow, stylist) | |
| party_girl.dislikes(underground, merchant) | |
| party_girl.hates(tax_collector) | |
| wizard.loves(golfer) | |
| wizard.likes(hallow, merchant) | |
| wizard.dislikes(ocean, witch_doctor) | |
| wizard.hates(cyborg) | |
| demolitionist.loves(tavernkeep) | |
| demolitionist.likes(underground, mechanic) | |
| demolitionist.dislikes(ocean, arms_dealer, goblin_tinkerer) | |
| goblin_tinkerer.loves(mechanic) | |
| goblin_tinkerer.likes(underground, dye_trader) | |
| goblin_tinkerer.dislikes(jungle, clothier) | |
| goblin_tinkerer.hates(stylist) | |
| clothier.loves(truffle) | |
| clothier.likes(underground, tax_collector) | |
| clothier.dislikes(hallow, nurse) | |
| clothier.hates(mechanic) | |
| dye_trader.likes(desert, arms_dealer, painter) | |
| dye_trader.dislikes(forest, steampunker) | |
| dye_trader.hates(pirate) | |
| arms_dealer.loves(nurse) | |
| arms_dealer.likes(desert, steampunker) | |
| arms_dealer.dislikes(snow, golfer) | |
| arms_dealer.hates(demolitionist) | |
| steampunker.loves(cyborg) | |
| steampunker.likes(desert, painter) | |
| steampunker.dislikes(jungle, dryad, wizard, party_girl) | |
| dryad.likes(jungle, witch_doctor, truffle) | |
| dryad.dislikes(desert, angler) | |
| dryad.hates(golfer) | |
| painter.loves(dryad) | |
| painter.likes(jungle, party_girl) | |
| painter.dislikes(forest, truffle, cyborg) | |
| witch_doctor.likes(jungle, dryad, guide) | |
| witch_doctor.dislikes(hallow, nurse) | |
| witch_doctor.hates(truffle) | |
| stylist.loves(dye_trader) | |
| stylist.likes(ocean, pirate) | |
| stylist.dislikes(snow, tavernkeep) | |
| stylist.hates(goblin_tinkerer) | |
| angler.likes(ocean, demolitionist, party_girl, tax_collector) | |
| angler.hates(tavernkeep) | |
| angler.sells = False | |
| pirate.loves(angler) | |
| pirate.likes(ocean, tavernkeep) | |
| pirate.dislikes(underground, stylist) | |
| pirate.hates(guide) | |
| mechanic.loves(goblin_tinkerer) | |
| mechanic.likes(snow, cyborg) | |
| mechanic.dislikes(underground, arms_dealer) | |
| mechanic.hates(clothier) | |
| tax_collector.loves(merchant) | |
| tax_collector.likes(snow, party_girl) | |
| tax_collector.dislikes(hallow, demolitionist, mechanic) | |
| #tax_collector.hates(santa) | |
| tax_collector.sells = False | |
| cyborg.likes(snow, steampunker, pirate, stylist) | |
| cyborg.dislikes(jungle, zoologist) | |
| cyborg.hates(wizard) | |
| #santa.loves(snow) | |
| #santa.hates(desert, tax_collector) | |
| truffle.loves(guide) | |
| truffle.likes(dryad) | |
| truffle.dislikes(clothier) | |
| truffle.hates(witch_doctor) | |
| NPC = Datatype("NPC") | |
| for n in npcs: | |
| NPC.declare(n.name) | |
| NPC = NPC.create() | |
| for n in npcs: | |
| n.ctr = getattr(NPC, n.name) | |
| Biome = Datatype("Biome") | |
| for b in biomes: | |
| Biome.declare(b.name) | |
| Biome = Biome.create() | |
| for b in biomes: | |
| b.ctr = getattr(Biome, b.name) | |
| for n in npcs: | |
| n.biome = Const(n.name + "_biome", Biome) | |
| n.near = {} | |
| for i in range(len(npcs)): | |
| for j in range(i+1, len(npcs)): | |
| near = Bool("near_" + npcs[i].name + "_" + npcs[j].name) | |
| npcs[i].near[npcs[j].name] = near | |
| npcs[j].near[npcs[i].name] = near | |
| r = RealVal | |
| def modifier(l, n, mod, result): | |
| if isinstance(l, biome): | |
| return result + If(l.ctr == n.biome, mod, 0) | |
| elif isinstance(l, npc): | |
| return result + If(n.near[l.name], mod, 0) | |
| else: | |
| raise | |
| def happiness(npc): | |
| result = 90 | |
| for l in npc._loves: | |
| result = modifier(l, npc, -10, result) | |
| for l in npc._likes: | |
| result = modifier(l, npc, -5, result) | |
| for l in npc._dislikes: | |
| result = modifier(l, npc, 5, result) | |
| for l in npc._hates: | |
| result = modifier(l, npc, 10, result) | |
| return If(result < 78, 0, | |
| If(result < 83, 1, | |
| If(result < 88, 2, | |
| If(result < 93, 3, | |
| If(result < 98, 4, | |
| If(result < 103, 5, | |
| If(result < 108, 6, | |
| If(result < 113, 7, | |
| If(result < 118, 8, | |
| If(result < 123, 9, | |
| If(result < 128, 10, | |
| If(result < 133, 11, | |
| If(result < 138, 12, | |
| If(result < 143, 13, | |
| If(result < 148, 14, | |
| 15))))))))))))))) | |
| total = 0 | |
| for n in npcs: | |
| if n.sells: | |
| n.happiness = happiness(n) | |
| total += n.happiness | |
| o = Optimize() | |
| o.add(truffle.biome == mushroom.ctr) | |
| o.add(goblin_tinkerer.happiness == 0) | |
| for n in npcs: | |
| nnear = 0 | |
| for n2 in npcs: | |
| if n.name != n2.name: | |
| o.add(Implies(n.near[n2.name], n.biome == n2.biome)) | |
| nnear += If(n.near[n2.name], 1, 0) | |
| o.add(nnear < 2) | |
| o.minimize(total) | |
| print(o.check()) | |
| m = o.model() | |
| print(m.eval(total)) | |
| for n in npcs: | |
| print n.name, ":", m[n.biome], "=", str(m.eval(happiness(n)).as_long() * 5 + 75) + "%", | |
| near=False | |
| for n2 in npcs: | |
| if n.name != n2.name: | |
| if m[n.near[n2.name]]: | |
| near=True | |
| if near: | |
| print "near", | |
| for n2 in npcs: | |
| if n.name != n2.name: | |
| if m[n.near[n2.name]]: | |
| print(n2.name), | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment