Last active
February 15, 2018 15:46
-
-
Save rubcuadra/4b7801665e8b67b9e5af527aa18fcafc to your computer and use it in GitHub Desktop.
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 randint,sample,random | |
from time import sleep | |
import os, platform | |
MAX_VELOCITY = 9 | |
MAX_CARS_PER_ROAD=10 #Can change this, always < ROAD_SIZE | |
P_RANDOM_STOP = 0.15 #Probab Car reduces velocity randomly | |
MAX_ROA = 1.0 #Rate of Appearance | |
EMPTY_CHAR = '.' | |
WAIT_BETWEEN_SIMULATIONS = 1 #Seconds | |
def cleanConsole(): | |
try: | |
if platform.system() == "Windows": | |
os.system('cls') | |
else: | |
os.system('clear') | |
except: | |
pass | |
class Car: | |
def __init__(self, velocity, xPosition,yPosition, coordinator): | |
self.velocity = velocity | |
self.updatePos(yPosition,xPosition) | |
self.coordinator = coordinator | |
def changeSpeed(self): | |
ncr = self.nextCarInRange() #Check next car position whitin our range(velocity) | |
if ncr == 0: #We can accelerate, no cars | |
if self.velocity < MAX_VELOCITY: | |
self.velocity+=1 | |
else: #Slow down and finish | |
self.velocity = ncr - 1 | |
#Probability of slowing down 1 Only if car is moving | |
if self.velocity>0 and random()<P_RANDOM_STOP: | |
self.velocity -= 1 | |
# print "RED: [%s,%s]"%(self.y,self.x) | |
def updatePos(self,y,x): | |
self.y = y | |
self.x = x | |
def move(self): | |
if self.velocity == 0: return #No need to move | |
self.coordinator.setInPlace(self,self.y,self.x+self.velocity) | |
#Si regresa 0 entonces si nos podemos mover, | |
#Si regresa cualquier otro numero entonces no, es la posicion del prox coche | |
def nextCarInRange(self): | |
for i in range(self.velocity+1): | |
if not self.coordinator.isAvailable(self.y,self.x+i+1): #Solo avanzan en X | |
return i+1 #Nos regresa la distancia hacia el proximo Coche | |
return 0 | |
def __str__(self): | |
return str(self.velocity) | |
class Playground: | |
def __init__(self, ROAD_DISTANCE, NUM_ROADS, NEW_CARS_APPEARANCE_PROBABILITY=0): | |
self.ROAD_DISTANCE = ROAD_DISTANCE | |
self.NUM_ROADS = NUM_ROADS | |
self.NEW_CARS_APPEARANCE_PROBABILITY = NEW_CARS_APPEARANCE_PROBABILITY | |
self.velocities = 0 #Summed velocities | |
self.totalCars = 0 | |
self.initPlayground() | |
self.printPlayground() | |
def initPlayground(self): | |
emptyRoad = [EMPTY_CHAR]*self.ROAD_DISTANCE | |
emptyAvenue = [ emptyRoad[:] for _ in range(self.NUM_ROADS) ] | |
for i in range(self.NUM_ROADS): | |
#CALCULATE INITIAL CARS POSITIONS | |
cars_pos = sample( range(0,self.ROAD_DISTANCE), randint(1,MAX_CARS_PER_ROAD) ) | |
#ADD EACH VELOCITY to THE CORRESPONDING CELL | |
for val in cars_pos: | |
emptyAvenue[i][val] = Car( randint(0,MAX_VELOCITY) , val,i, self) | |
self.totalCars += 1 | |
self.avenue = emptyAvenue | |
def isAvailable(self,y,x): | |
if y >= self.NUM_ROADS or x >= self.ROAD_DISTANCE: | |
return True | |
return self.avenue[y][x] == EMPTY_CHAR | |
def setInPlace(self,car,y,x): #ys mayores haran que truene o car.y/car.x wrong coordinates | |
if x >= self.ROAD_DISTANCE: #The car left the road | |
self.avenue[car.y][car.x] = EMPTY_CHAR | |
self.totalCars -= 1 | |
return #Maybe add another car | |
if self.avenue[y][x] != EMPTY_CHAR: #DEBUG ERRORS | |
print "ERR: [%s,%s] %s -> [%s,%s]"%(car.y,car.x,car.velocity,y,x) | |
self.avenue[y][x] = car #Move to new position | |
self.avenue[car.y][car.x] = EMPTY_CHAR #Delete old position | |
car.updatePos(y,x) #Update, succesfull movement | |
def carsActions(self): | |
self.velocities = 0.0 #Hack, usaremos para average speed | |
#Primero que todos cambien velocidad | |
for road in self.avenue: | |
for car in road: | |
if car != EMPTY_CHAR: | |
car.changeSpeed() | |
self.velocities += float(car.velocity) #Temporal | |
#Despues que todos se muevan | |
for road in self.avenue: | |
for car in reversed(road): #Mover de derecha a izq | |
if car != EMPTY_CHAR: | |
car.move() | |
def dispatchCars(self): | |
for i,road in enumerate(self.avenue): | |
#If we can add & % tells us to add | |
if road[0]==EMPTY_CHAR and random()<self.NEW_CARS_APPEARANCE_PROBABILITY: | |
road[0] = Car( randint(0,MAX_VELOCITY) ,0,i, self) | |
self.totalCars += 1 | |
def showMenu(self): | |
c = "r" | |
while c != "q": | |
self.printPlayground() | |
c = raw_input("Press the key for any action:\n\tq\tExit\n\tw\t-ROA\n\te\t+ROA\n\tr\tResume\nYour Choice: ") | |
if c == "w": | |
self.decreaseTraffic() | |
elif c == "e": | |
self.increaseTraffic() | |
elif c == "r" or c == "q": | |
break | |
else: | |
print "Wrong Input" | |
if c == "r": | |
self.startSimulation() | |
else: | |
print "Bye!" | |
def startSimulation(self): | |
try: | |
while True: | |
self.carsActions() #Accelerate/Move | |
self.dispatchCars() #Appear New Cars | |
self.printPlayground() | |
sleep(WAIT_BETWEEN_SIMULATIONS) | |
except KeyboardInterrupt: | |
self.showMenu() | |
def printPlayground(self): | |
cleanConsole() | |
for road in self.avenue: | |
for cell in road: | |
print cell, | |
self.printStats() | |
def printStats(self): | |
print "Number of Roads: %s, Road Size: %s"%(self.NUM_ROADS,self.ROAD_DISTANCE) | |
print "Cars rate of appearance: %s"%self.NEW_CARS_APPEARANCE_PROBABILITY | |
print "Probability car reduces speed randomly: %s"%P_RANDOM_STOP | |
print "Number of Cars %s"%self.totalCars | |
print "Average Velocity %s"%(0 if self.totalCars<=0 else self.velocities/float(self.totalCars)) | |
print "\nPress 'Ctrl + C' for more\n" | |
def increaseTraffic(self): | |
self.NEW_CARS_APPEARANCE_PROBABILITY+=0.05 | |
if self.NEW_CARS_APPEARANCE_PROBABILITY>MAX_ROA: self.NEW_CARS_APPEARANCE_PROBABILITY = MAX_ROA | |
def decreaseTraffic(self): | |
self.NEW_CARS_APPEARANCE_PROBABILITY-=0.05 | |
if self.NEW_CARS_APPEARANCE_PROBABILITY<0.05: self.NEW_CARS_APPEARANCE_PROBABILITY = 0 | |
if __name__=="__main__": | |
pg = Playground(100,30) | |
pg.showMenu() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment