Last active
August 29, 2015 14:07
-
-
Save 1328/0351649dd8b7a47634fc to your computer and use it in GitHub Desktop.
mapper
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 random import randrange, sample | |
| from collections import Counter | |
| class Map(object): | |
| water_chance = 10 #Chance of ground being water | |
| water_near_water = 30 #If a water tile is to our left or top | |
| house_chance = 5 | |
| boat_chance = 25 #If we're on a water tile, with a house nearby, chance of it being a boat | |
| def __init__(self, height, width): | |
| self.height = height | |
| self.width = width | |
| self.tiles = height * width | |
| self.matrix = {} # need to init for steps | |
| self.matrix = {c:'.' for c, _ in self.steps()} | |
| self._add_water() | |
| self._add_houses() | |
| self._add_boats() | |
| def steps(self, what = None): | |
| ''' | |
| generator function that walks through the points and returns point, | |
| value | |
| if what is specified, only returns tiles with what in them | |
| ''' | |
| for y in range(self.height): | |
| for point, v in self.steps_row(y, what): | |
| yield point, v | |
| def steps_row(self, y, what = None): | |
| ''' | |
| generator that walks through a row, like steps above, but just one row | |
| ''' | |
| for x in range(self.width): | |
| tile = self.matrix.get(x,y) | |
| if what is not None and what != tile: | |
| continue | |
| yield (x,y), tile | |
| def adjacent(self, point): | |
| ''' | |
| returns set of all neighboring points to point | |
| ''' | |
| neighbors = [(0,-1),(0,1),(1,0),(-1,0)] | |
| result = set() | |
| for n in neighbors: | |
| check = self.t_add(point, n) | |
| if check in self.matrix: | |
| result.add(check) | |
| return result | |
| def adj_values(self, point): | |
| ''' | |
| return a Counter of the values in neighboring tiles | |
| ''' | |
| result = Counter([self.matrix[p] for p in self.adjacent(point)]) | |
| return result | |
| def _add_water(self): | |
| # adds random water first | |
| water_pop = int(self.tiles * self.water_chance/100) | |
| base_water_tiles = sample(self.matrix.keys(), water_pop) | |
| for point in base_water_tiles: | |
| self.matrix[point] = '~' | |
| # now add more to tiles adjacent to other water tiles | |
| for point, t in self.steps(): | |
| if ('~' in self.adj_values(point) and randrange(100) < | |
| self.water_near_water): | |
| self.matrix[point] = '~' | |
| # now dry up single tiles of water, with no water friends nearby | |
| for point,t in self.steps('~'): | |
| near = self.adj_values(point) | |
| if '~' not in near: | |
| self.matrix[point] = '.' | |
| def _add_houses(self): | |
| for point, _ in self.steps('.'): | |
| if randrange(100)<self.house_chance: | |
| self.matrix[point] = 'H' | |
| def _add_boats(self): | |
| for point, _ in self.steps('~'): | |
| if 'H' not in self.adj_values(point): | |
| continue | |
| if randrange(100)<self.boat_chance: | |
| self.matrix[point] = 'B' | |
| def __str__(self): | |
| result = '' | |
| for y in range(self.height): | |
| result += ''.join(t for _,t in self.steps_row(y)) | |
| result += '\n' | |
| return result | |
| @staticmethod | |
| def t_add(a,b): | |
| ''' | |
| adds two tuples, like points! | |
| ''' | |
| return (a[0]+b[0], a[1]+b[1]) | |
| x = Map(20,25) | |
| print(x) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment