Spaces:
Running
Running
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') |