Spaces:
Running
Running
File size: 5,950 Bytes
3a19185 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
import networkx as nx
class WorldGraph(nx.DiGraph):
def __init__(self, path_to_originial_map):
super().__init__()
self.load_graph_from_file(path_to_originial_map)
def load_graph_from_file(self, filename):
with open(filename, 'r') as f:
for line in f:
line = line.strip()
if not line or line.startswith('#'):
continue
parts = line.split()
if parts[2] in ['own', 'friendliness']:
# Add directed edge with type and value
self.add_edge(parts[0], parts[1], relationship=parts[2], value=int(parts[3]))
else:
# Node attributes: country, money, warming, army
try:
self.add_node(parts[0], money=int(parts[1]), warming=float(parts[2]), army=int(parts[3]), leader=parts[4])
except IndexError:
self.add_node(parts[0], money=int(parts[1]), warming=float(parts[2]), army=int(parts[3]))
def update_world(self, country, delta_USA, delta_country, delta_friendliness, game_number):
"""updates world graph and returns USA GDP"""
self.nodes['United-States']['money'] += delta_USA
self.nodes[country]['money'] += delta_country
self['United-States'][country]['value'] += delta_friendliness
#clip between -4 and 4
self['United-States'][country]['value'] = max(-4, min(self['United-States'][country]['value'] , 4))
self.save_graph_as_edgelist(f'games/game_{game_number}/world_graph.edgelist')
print(self['United-States'][country])
print(self.nodes['United-States'])
return self.nodes['United-States']['money']
def get_countries_at_war(self):
"""
Returns a list of tuples representing pairs of countries that are at war
(friendliness == -2).
:param graph: A NetworkX DiGraph with 'relationship' and 'value' edge attributes.
:return: List of tuples (country1, country2)
"""
war_pairs = []
for u, v, data in graph.edges(data=True):
if data.get('relationship') == 'friendly' and data.get('value') == -2:
war_pairs.append((u, v))
return war_pairs
def get_control_of(self, owner, owned):
"""
Transfers ownership of `owned` country to `owner` country.
Steps:
1. Update relationships to reflect ownership (owner -> owned = +1, owned -> owner = -1).
2. Remove all other relationships for the `owned` country.
3. Transfer attributes (Money, Warming, Army) to the `owner` and set them to 0 for the `owned` country.
:param graph: A NetworkX DiGraph
:param owner: The country that will take ownership
:param owned: The country being owned
"""
# Step 1: Set ownership relationships
self.add_edge(owner, owned, relationship='own', value=1)
self.add_edge(owned, owner, relationship='own', value=-1)
# Step 2: Remove all other edges related to `owned`
for neighbor in list(self.successors(owned)) + list(self.predecessors(owned)):
if neighbor != owner: # Don't remove the ownership link
self.remove_edge(owned, neighbor)
self.remove_edge(neighbor, owned)
# Step 3: Transfer attributes
owner_data = self.nodes[owner]
owned_data = self.nodes[owned]
owner_data['Money'] += owned_data['Money']
owner_data['Warming'] += owned_data['Warming']
owner_data['Army'] += owned_data['Army']
# Set owned country attributes to 0
self.nodes[owned]['Money'] = 0
self.nodes[owned]['Warming'] = 0.0
self.nodes[owned]['Army'] = 0
def save_graph_as_edgelist(self, filename):
"""
Saves the graph to an edgelist file with relationships and node attributes.
:param filename: The name of the file to save the edgelist.
"""
with open(filename, 'w') as f:
# Write edges with relationship type and value
f.write("# Own and friendly relationships\n")
for u, v, data in self.edges(data=True):
relationship = data['relationship']
value = data['value']
f.write(f"{u} {v} {relationship} {value}\n")
f.write("\n# Node attributes (country Money Warming Army)\n")
for node, data in self.nodes(data=True):
try:
f.write(f"{node} {data['money']} {data['warming']} {data['army']}\n")
except KeyError:
f.write(f"{node} {data['money']} {data['warming']} {data['army']} {data['leader']}\n")
def push_data_to_front(self):
"""returns a dict that looks like
{"United-States": {"money" : xxx},
"country1": {"money": xxx, "friendliness": -1},
"country2": {"money": yyy, "friendliness": 2},
...
}"""
d = {}
for c in self.nodes():
if c == 'United-States':
d[c] = {'money': self.nodes[c]['money']}
else:
d[c] = {
'money': self.nodes[c]['money'],
'friendliness': self['United-States'][c]['value']
}
return d
""" Object manipulation
>>> graph['China']['Taiwan']
{'relationship': 'own', 'value': 1}
>>> graph['China']['Russia']
{'relationship': 'friendliness', 'value': 1}
>>> graph.nodes['France']
{'money': 70, 'warming': 0.7, 'army': 50, 'leader': 'Macron'}
"""
if __name__ == '__main__':
G = WorldGraph('original_setup/contexts/world_map.edgelist')
print(G.nodes['United-States'])
G.nodes['United-States']['money'] += 5
print(G.nodes['United-States'])
print(G.push_data_to_front())
G.save_graph_as_edgelist('test.edgelist') |