Skip to content

Instantly share code, notes, and snippets.

@klenze

klenze/khan.py Secret

Created October 16, 2021 23:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save klenze/50fe0349379569914a8d58080d6e3cc0 to your computer and use it in GitHub Desktop.
Save klenze/50fe0349379569914a8d58080d6e3cc0 to your computer and use it in GitHub Desktop.
Opportunity graph.png source
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
rewards=["Five Vital Intelligence",
"Salt Steppe Atlas",
"Bottle of Airag",
"Parabola-Linen Scrap",
":Obtain the codebook, and sell it",
":Warn the Eagle",
":Distract the Navy's investigators",
"Oneiromantic Revelation",
"Oneiric Pearl",
":Leak this information to the Tortoise",
":Warn the Revolutionaries",
"125x Khaganian Coins",
"Searing Enigma",
"Five Bazaar Permit",
":Leak their identities to the Khagan",
":Deliver the Mummified Priest to the Khagan",
"Much-Needed Gap"
]
edges={1:{2: "Five Vital Intelligence", 3:"Five Vital Intelligence" },
2:{4: "Salt Steppe Atlas", 8:"Bottle of Airag" },
3:{9:"Parabola-Linen Scrap", 5:":Obtain the codebook, and sell it"},
4:{11:":Warn the Eagle", 3:":Distract the Navy's investigators"},
5:{4:"Oneiromantic Revelation", 7:"Oneiric Pearl"},
6:{2:":Leak this information to the Tortoise", 5:":Warn the Revolutionaries"},
7:{9:"125x Khaganian Coins", 10:"Searing Enigma"},
8:{7:"Five Bazaar Permit", 6:"Searing Enigma"},
9:{6:"Bottle of Airag", 10:":Leak their identities to the Khagan"},
10:{11:"125x Khaganian Coins", 1:"125x Khaganian Coins",},
11:{8:":Deliver the Mummified Priest to the Khagan", 1: "Much-Needed Gap"}}
def mkrewards():
res={}
id=np.identity(len(rewards))
for i, rwd in enumerate(rewards):
res[rwd]=id[i]
return res
rwd2vec=mkrewards()
def vec2str(vec):
res=""
for i in range(len(rewards)):
if vec[i]>0:
res+="%d x %s\n"%(vec[i], rewards[i])
return res
DG = nx.DiGraph()
for begin, l in edges.items():
DG.add_edges_from(map(lambda end: (begin, end), l.keys()))
# looks like nx insists on double-valued weights, so we add a custom column instead.
for end, rwd in l.items():
DG.edges[begin, end]["reward"]=rwd2vec[rwd]
def cycle_rewards(cycle):
res=np.zeros(len(rewards))
for i in range(len(cycle)):
res+=DG.edges[cycle[i], cycle[(i+1)%len(cycle)]]["reward"]
return res
cycles=sorted(list(nx.algorithms.cycles.simple_cycles(DG)), key=len)
khanite_only_rewards=rwd2vec["Much-Needed Gap"]+rwd2vec["Oneiric Pearl"]+rwd2vec["125x Khaganian Coins"]
khanite_rewards=khanite_only_rewards+rwd2vec["Salt Steppe Atlas"]+rwd2vec["Bottle of Airag"]
for c in cycles:
r =cycle_rewards(c)
# if len(c)<10:
# continue
# if r@khanite_rewards +1.5 < sum(r):
# continue
print(c)
print(vec2str(r))
c=[1, 2, 8, 6, 5, 4, 3, 9, 10, 11] # one of the cycles of length 10
layout=nx.drawing.layout.shell_layout(DG, [c, list(filter(lambda a: not a in c, list(DG)))])
def color_edge(e):
rwd=DG.edges[e]["reward"]
if rwd @ khanite_only_rewards > 0.5:
return "red"
if rwd @ khanite_rewards > 0.5:
return "green"
if rwd @ rwd2vec[":Leak this information to the Tortoise"] > 0.5:
return "magenta"
if rwd @ (rwd2vec[":Warn the Eagle"]+rwd2vec[":Warn the Revolutionaries"]+rwd2vec[":Leak their identities to the Khagan"])> 0.5:
return "blue"
return "black"
edge_colors=list(map(color_edge, DG.edges))
labels1={1:"Agent", 2: "Zailor", 3:"Codebook", 4: "Blueprints", 5: "Mirror", 6: "Device",
7: "Trove", 8: "Secret", 9:"Telegraph", 10:"Master\ncovets", 11: "Master\nlots"}
labels=dict(map(lambda a: (a, "%d\n%s"%(a, labels1[a])), DG))
nx.draw(DG, with_labels=True, font_weight='bold', pos=layout,
arrows=True, arrowsize=40, edge_color=edge_colors,
node_color='white', edgecolors="black", node_size=5000,
labels=labels)
plt.show()
print(nx.algorithms.euler.is_eulerian(DG))
print(list(map(lambda a:a[0], nx.algorithms.euler.eulerian_circuit(DG))))
#nx.drawing.nx_pylab.draw_kamada_kawai(DG, with_labels=True, font_weight='bold' )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment