Skip to content

Instantly share code, notes, and snippets.

@1328
Created April 11, 2016 17:08
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 1328/82f1fc1ecb3489ad944b4c1013fe9ab6 to your computer and use it in GitHub Desktop.
Save 1328/82f1fc1ecb3489ad944b4c1013fe9ab6 to your computer and use it in GitHub Desktop.
cars
import numpy as np
from itertools import product
from random import shuffle,random
def blank_road(**args):
lanes, cells = args['lanes'], args['cells']
return np.zeros((lanes, cells))
def all_spots(**args):
'''
this is a bit tricky, but useful: yields out all possible spots on road
surface
'''
return product(range(args['lanes']), range(args['cells']))
def populate(**args):
'''
populates a blank road with cars number of cars
'''
road = blank_road(**args)
positions = list(all_spots(**args))
shuffle(positions)
positions = positions[:args['start_cars']]
for position in positions:
road[position] = 1
return road
def next_positions(current, **args):
'''
return all future possible positions from position current
'''
# first possible check is always one car length ahead
possibles = [ (current[0], current[1]+1)] # move one forward
# next check if can overtake in lane -1
if current[0]-1 >= 0:
possibles.append( (current[0]-1, current[1]+1))
# next check if can overtake in lane +1
if current[0]+1 < args['lanes']:
possibles.append( (current[0]+1, current[1]+1))
return possibles
def path(road, current, **args):
'''
return the next valid position from current
given the road state of road
'''
for possible in next_positions(current, **args):
if road[possible] == 0:
return possible
# no possible positions, so retun current spot
return current
def check_stall(**args):
return random() < args['stall_chance']
def cycle(road, **args):
'''
does one cycle walking road forward into a new state
return a new road array
'''
result = blank_road(**args)
for current in all_spots(**args):
if current[1]+1 == args['cells']:
# at final cell, skip b/c we assume that you have a clear shot at
# next
continue
if road[(current)] == 0:
# no car at current, so move on
continue
if check_stall(**args):
print('car at {} stalled'.format(current))
new_position = current
else:
# try and move forward
new_position = path(road, current, **args)
if new_position == current:
print('car at {} blocked'.format(current))
result[new_position] = 1
return result
def print_road(road, **args):
'''
print the current road state to screen
'''
# here i break out lanes and cells from args to make the comprehension a bit
# easier to follow
lanes = args['lanes']
cells = args['cells']
for lane in range(lanes):
output = ''.join('O' if road[(lane, cell)] else '.' for cell in range(cells))
print(output)
def test():
defaults = {
'lanes':3,
'cells':20,
'start_cars': 15,
'stall_chance': .4, # chance car will not move in a cycle
}
road = populate(**defaults)
for i in range(10):
print_road(road, **defaults)
road = cycle(road, **defaults)
print()
if __name__ == '__main__':
test()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment