Skip to content

Instantly share code, notes, and snippets.

@1328
Created October 20, 2014 23:39
Show Gist options
  • Select an option

  • Save 1328/5fdaed8f9135587ea2d0 to your computer and use it in GitHub Desktop.

Select an option

Save 1328/5fdaed8f9135587ea2d0 to your computer and use it in GitHub Desktop.
aliens - comments
import sys
import random
#Helper dictionary to reverse directions
# line is too long, break it up
reverse_directions = { "north" : "south",
"east":"west",
"west":"east",
"south":"north" }
#City helper variables
cities = []
#Alien helper variables
aliens = []
class City(object):
def __init__(self, name, **kwargs):
self.alien = None
self.name = name
self.adj = dict(kwargs)
# if you are going to use an object, consider creating another objectect
# initiator from line in the file
@classmethod
def from_line(cls, line):
# break up the line here and create new city
# gives a bit cleaner look and show off some skills
# overkill maybe...
class Alien:
def __init__(self, n):
self.n = n
# does this really need an object if you are just storing once piece of
# data and have no methods?
#- create a function for this
# Read through file and create all the cities
with open("./world_map_medium.txt","r") as r:
for line in r:
results = line.split()
city_name = results[0]
adj_cities = {}
for adj_city in results[1:]:
dir, name = adj_city.split("=")
adj_cities[dir] = name
cities.append(City(city_name, **adj_cities))
city_quick_lookup = {x.name: x for x in cities}
# Iterate through all the cities and make sure that the adjacent cities are setup correctly (converting strings to actual references to City objects)
for c in city_quick_lookup.values():
for dir,name in c.adj.items():
#If city exists then connect it
if name in city_quick_lookup.keys():
c.adj[dir] = city_quick_lookup[name]
#Else create it (since it's not in the first row of the city names and is some sort of outlier city
else:
c.adj[dir] = City(name, **{reverse_directions[dir]:c})
#REMINDER TO MAKE THIS ARGV later!
# n = int(raw_input())
#Number of aliens that the user wishes to simulate
# put everything in main() func called when __name__ == '__main__'
number_of_aliens = int(sys.argv[1])
print "Now creating simulation with {} alien(s)!".format(number_of_aliens)
print
print "Take cover! The alien invasion has begun!"
print
aliens = {x:Alien(x) for x in range(number_of_aliens)}
for alien in aliens.values():
city = random.choice(city_quick_lookup.values())
#City doesn't already have an alien so place peacefully
# don't use getattr/ settr if you can avoid it and you can
if getattr(city, "alien") == None:
setattr(city, "alien", alien)
print city.name, "has been invaded by Alien {}!".format(alien.n)
#City already has an alien so they must fight!
else:
print
print "Alien {} and Alien {} are having a battle in the city of {}, the city and aliens have been completely destroyed!".format(alien.n, city.alien.n, city.name)
#Iterate through all the cities adjacent and remove paths into the city
for dir, a_city in city.adj.items():
if a_city.adj[reverse_directions[dir]] == city:
del a_city.adj[reverse_directions[dir]]
##Remove aliens from dict
del aliens[alien.n]
del aliens[city.alien.n]
#Remove the city from the overall
del city_quick_lookup[city.name]
print
print "The number of human cities is now {}!".format(len(city_quick_lookup))
print
print
print "The aliens are now on a rampage and are moving about the country!!"
print
# this is a lot of work. A better data structure is to have an
# alien_map = {city: aliens}
cities_with_aliens = [x for x in city_quick_lookup.values() if x.alien != None]
#Number of iterations
# note: you should mention that the directions are broken and some aliens might
# not move b/c they get stranded in an inacessable city
for n in xrange(10000):
#Iterate through each city with an alien
#broken, since you are modifying cities with aliens as you iterate
# over it
for c in cities_with_aliens:
#If the city has no adjacent cities, then leave it be and alien stays
if len(c.adj.values()) != 0:
#Pick random city from the paths leading out of the city
new_city = random.choice(c.adj.values())
#If new city has no alien, move there and move onto the next alien
if new_city.alien == None:
new_city.alien = c.alien
c.alien = None
#Alien moves to new city and out of the old one
# don't modify a list as you iterate over it
cities_with_aliens.append(new_city)
cities_with_aliens.remove(c)
#City has an alien and we need to fight!
else:
print
print "Alien {} from {} and Alien {} have encountered one another in the city of {}, a fight ensues!".format(c.alien.n, c.name, new_city.alien.n,new_city.name)
print "The Aliens {} and {} and the city of {} are obliterated".format(c.alien.n, new_city.alien.n, c.name)
#Remove the now dead aliens from the alien dict
del aliens[c.alien.n]
del aliens[new_city.alien.n]
##Delete adjacent paths into the city that is are destroyed
for dir, nearby_city in new_city.adj.items():
if nearby_city.adj[reverse_directions[dir]] == new_city:
del nearby_city.adj[reverse_directions[dir]]
##Delete reference to aliens in cities
c.alien = None
new_city.alien = None
#Delete the city that was moved into
del city_quick_lookup[new_city.name]
#Remove both cities from list of cities with aliens
cities_with_aliens.remove(new_city)
cities_with_aliens.remove(c)
if len(city_quick_lookup) > 0:
print
print "The rampage is over!"
print "The number of human cities remaining is {}!".format(len(city_quick_lookup))
print "The number of aliens remaining is {}!".format(len(aliens))
print
print "The remaining cities:"
for c in city_quick_lookup.values():
o = "\t" + c.name
for dir, city in c.adj.items():
o+= " "+str(dir)+"="+str(city.name)
print o
else:
print "All cities were destroyed in the invasion!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment