Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import random
- import math
- from dataclasses import field, dataclass
- from typing import List
- City_Fares = { # Tarifa mínima para cada cidade da simulação
- "São José dos Campos": 5,
- "Jacareí" : 4,
- "Mogi das Cruzes": 4.5,
- "Caçapava": 3.5,
- "Guararema": 3.0,
- "Santa Branca": 2.75,
- "Santa Preta": 2.5,
- "Urbanova": 3.25,
- "Jambeiro": 2.25,
- "Desaparecida": 3.75
- }
- CarList1 = ["Hyundai HB20", "Kia Cerato", "Chevrolet Onix", "Fiat Mobi", "Fiat Uno", "Nissan Leaf"]
- CarList2 = ["Land Rover Defender", "Hyundai Santa Fe", "Toyota Prius", "Jaguar XF", "Mercedes E-Class", "Lexus GS", "Mercedes GL", "Volvo XC60"]
- CarList3 = ["Toyota AE86 Trueno", "Honda NSX", "Fiat Uno Mille", "Mini Cooper", "Pagani Huayra", "Porsche 918 Spyder", "Ferrari F40"]
- Car_List = { # Carros e seus valores associados. O valor ao lado do nome do carro define quais serviços ele pode fazer
- # Cada serviço tem uma chave prima associada (UberX = 2) e se o valor associado a um carro for divisível por essa
- # chave prima, o carro pode prestar esse serviço
- "Hyundai HB20": 2,
- "Kia Cerato": 2,
- "Chevrolet Onix": 2,
- "Fiat Mobi": 2,
- "Fiat Uno": 2,
- "Nissan Leaf": 2,
- "Land Rover Defender": 6,
- "Hyundai Santa Fe": 6,
- "Toyota Prius": 6,
- "Jaguar XF": 10,
- "Mercedes E-Class": 10,
- "Lexus GS": 10,
- "Mercedes GL": 30,
- "Volvo XC60": 30,
- "Toyota AE86 Trueno": 14,
- "Honda NSX": 14,
- "Fiat Uno Mille": 14,
- "Mini Cooper": 22,
- "Pagani Huayra": 22,
- "Porsche 918 Spyder": 22,
- "Ferrari F40": 154
- }
- Uber_Types = {
- 2: "UberX",
- 3: "UberXL",
- 5: "Uber black",
- 7: "Uber vintage",
- 11: "Uber lux"
- }
- def UberChooser(): # Essa função decide qual será o tipo da viagem
- TypeVar = random.randrange(1,100,1)
- if TypeVar <= 50:
- return 2 # UberX
- if TypeVar <= 70:
- return 3 # UberXL
- if TypeVar <= 90:
- return 5 # Uber Black
- if TypeVar <= 95:
- return 7 # Uber Vintage (inventado)
- return 11 # Uber Lux
- def FareFromType(Rtype): # Muda valor da corrida dependendo do tipo solicitado
- if Rtype == 2:
- return 1 # Taxa pra UberX
- if Rtype == 3:
- return 1.2 # Taxa pra UberXL
- if Rtype == 5:
- return 1.3 # Taxa pra Uber black
- if Rtype == 7:
- return 1.5 # Taxa pra Uber vintage
- return 2 # Taxa pra Uber lux
- def CalculateTip(aride): # Calcula a gorjeta dependendo do valor da corrida
- Tip = random.randrange(1,1000,1)
- if Tip <= 500:
- return 0 # 50% de chance de não ter gorjeta
- if Tip <= 800:
- return aride.price / 20 # 30% de chance de ter gorjeta equivalente a 5% da corrida
- if Tip <= 900:
- return aride.price / 10 # 10% de chance de ter gorjeta equivalente a 10% da corrida
- if Tip <= 950:
- return aride.price / 5 # 5% de chance de ter gorjeta equivalente a 20% da corrida
- if Tip <= 999:
- return aride.price / 4 # 4.9% de chance de ter gorjeta equivalente a 25% da corrida
- return aride.price # 0.1% de chance de ter gorjeta equivalente a 100% da corrida... boa sorte!
- def ChooseCar(owner): # Essa função dá um carro aleatório para um motorista
- if owner.name == "Fabrício Müller":
- return "Toyota AE86 Trueno"
- if owner.name == "Sofia Almeida":
- return "Mini Cooper"
- if owner.name == "Gabriel Garcia":
- return "Chevrolet Onix"
- CarChoice = random.randrange(1, 100, 1)
- if CarChoice <= 65:
- return random.choice(CarList1) # Escolhe um carro da lista básica
- if CarChoice <= 95:
- return random.choice(CarList2) # Escolhe um carro da lista avançada
- return random.choice(CarList3) # Escolhe um carro da lista premium
- def GetNewCar(owner): # Função dá um novo carro para um motorista aleatório
- aux = False
- loops = 0
- ncar = ""
- while not aux and loops <= 100:
- CarChoice = random.randrange(1, 100, 1)
- if CarChoice <= 65:
- ncar = random.choice(CarList1)
- elif CarChoice <= 95:
- ncar = random.choice(CarList2)
- else:
- ncar = random.choice(CarList3)
- if ncar not in owner.cars:
- owner.cars.append(ncar)
- print(owner.name,"just got a", ncar)
- aux = True
- else:
- loops = loops + 1
- return owner
- # Lista que contém os primeiros nomes possíves para passageiros e motoristas
- Fnames = ["Otávio", "Fabrício", "Sofia", "Gabriel", "Fábio", "Felipe", "Vanessa", "Carol", "Iasmin", "Cláudia", "Henrique", "Thadeu", "Sasha", "Sarah", "Marcelo", "Sushi", "Raul"]
- # Lista que contém os últimos nomes possíveis para passageiros e motoristas
- Lnames = ["Lemos", "Müller", "Almeida", "Garcia", "Cappabianco", "Marcondes", "Cesarini", "Andrade", "Campos", "Tanaka", "Senne", "Oliveira", "Rodela", "Tomita", "Gama", "Benito"]
- @dataclass
- class Position:
- Xpos: float
- Ypos: float
- def CityFinder(pos): # Essa função descobre em qual cidade qualquer posição específica é localizada
- xpos = pos.Xpos
- ypos = pos.Ypos
- if xpos > 170 and ypos > 170:
- return "Caçapava"
- if 0 <= xpos <= 170 and 0 <= ypos <= 190:
- return "São José dos Campos"
- if -50 < xpos < 0 and 150 < ypos < 190:
- return "Urbanova"
- if -80 <= xpos <= 0 and -50 <= ypos <= 150:
- return "Jacareí"
- if 0 < xpos < 30 and -70 < ypos < -50:
- return "Santa Branca"
- if -30 < xpos < 0 and -70 < ypos < -50:
- return "Santa Preta"
- if -80 < xpos < -30 and -80 < ypos < -50:
- return "Guararema"
- if 150 < xpos < 170 and -70 < ypos < -50:
- return "Jambeiro"
- if xpos > 170 and 0 < ypos < 170:
- return "Desaparecida"
- if -200 < xpos < -80 and -100 < ypos < 0:
- return "Mogi das Cruzes"
- return "???"
- def IsInCity(pos): # Essa função descobre se uma posição específica está ou não em uma cidade
- xpos = pos.Xpos
- ypos = pos.Ypos
- if xpos > 170 and ypos > 170:
- return True
- if 0 <= xpos <= 170 and 0 <= ypos <= 190:
- return True
- if -50 < xpos < 0 and 150 < ypos < 190:
- return True
- if -80 <= xpos <= 0 and -50 <= ypos <= 150:
- return True
- if 0 < xpos < 30 and -70 < ypos < -50:
- return True
- if -30 < xpos < 0 and -70 < ypos < -50:
- return True
- if -80 < xpos < -30 and -80 < ypos < -50:
- return True
- if 150 < xpos < 170 and -70 < ypos < -50:
- return True
- if xpos > 170 and 0 < ypos < 170:
- return True
- if -200 < xpos < -80 and -100 < ypos < 0:
- return True
- return False
- def FindDistance(pos1, pos2): # Calcula a distância mínima entre duas posições
- x1 = pos1.Xpos
- y1 = pos1.Ypos
- x2 = pos2.Xpos
- y2 = pos2.Ypos
- varX = x1 - x2
- if 0 > varX:
- varX = varX * -1
- varY = y1 - y2
- if 0 > varY:
- varY = varY * -1
- x1 = math.sqrt(varX * varX + varY * varY)
- return x1
- def MakeBoostZone():
- aux = False
- while not aux:
- pos = Position(random.uniform(-200, 200), random.uniform(-100, 200))
- aux = IsInCity(pos)
- return pos
- @dataclass
- class Driver:
- name: str
- position: Position
- cars: List[str] = field(default_factory=list) # Lista de carros, usada para definir carro atual
- CurrCar: str = ""
- streak: int = 0 # Sequencia de corridas em um dia do motorista
- city: str = ""
- def __str__(self):
- if self.streak == 0:
- return f"{self.name} is in {self.city} and is driving a {self.CurrCar}"
- return f"{self.name} is in {self.city}, is driving a {self.CurrCar} and has a streak of {self.streak} rides"
- def FindCity(self):
- return CityFinder(self.position)
- def CalculateEarnings(self, ridecost, ridetip):
- tax = 25 # Taxa da Uber inicia como 25%
- if 0 <= self.streak <= 5:
- tax = tax - self.streak # Diminui a taxa da Uber de acordo com a sequência de corridas (limíte em 5 corridas)
- elif self.streak > 5:
- tax = 20
- return ridecost - (tax / 100 * ridecost) + ridetip
- @dataclass
- class Passenger:
- name: str
- position: Position
- city: str = ""
- def FindCity(self):
- return CityFinder(self.position)
- def __str__(self):
- return f"{self.name} is currently in {self.city}"
- def PrintRide(aride, tip, earnings, fboost, rtype):
- if not fboost:
- print("The driver was " + aride.driver.name + " the passenger was " + aride.passenger.name + ", the destination was " + CityFinder(aride.destination) + ", the price for the " + str(Uber_Types.get(rtype)) + " was " + str(aride.price) + ", there was a tip of " + str(tip) + " and the driver earned " + str(earnings))
- else:
- print("The driver was " + aride.driver.name + " the passenger was " + aride.passenger.name + ", the destination was " + CityFinder(aride.destination) + ", the price for the " + str(Uber_Types.get(rtype)) + " was a boosted " + str(aride.price) + ", there was a tip of " + str(tip) + " and the driver earned " + str(earnings))
- return
- @dataclass
- class Ride:
- driver: Driver
- passenger : Passenger
- destination: Position
- price: float = 0.0
- boost: bool = False
- type: float = 1.0
- def __str__(self):
- return f"The driver was {self.driver.name} and the passenger was {self.passenger.name}, the destination was {CityFinder(self.destination)} and the price was {self.price}"
- def CalcPrice(self):
- # Distância entre motorista e passageiro e entre passageiro e destino
- dist = FindDistance(self.driver.position, self.passenger.position) + FindDistance(self.passenger.position, self.destination)
- # Calcula a taxa base usando a cidade do passageiro e cidade destino
- bfare = (City_Fares.get(self.passenger.city) + City_Fares.get(CityFinder(self.destination))) / 2
- # Calcula o tempo baseado na distância total e aleatoriedade
- rideTime = random.uniform(dist - dist / 2, dist + dist / 2) / 5
- # Faz o calculo do preço da corrida usando a tarifa base, a distância, a cidade e o tempo
- bfare = bfare + dist * (0.10 + bfare / 20) + (rideTime * 0.10)
- # Aumenta o preço se a corrida estiver em uma zona booster
- if self.boost is True:
- bfare = bfare * 1.3
- # Multiplica por um valor que depende do tipo da corrida
- bfare = bfare * self.type
- return bfare
- opt = 0
- day = 1
- boolAux = False
- position = 0
- Dlist = []
- Plist = []
- booster = MakeBoostZone()
- while opt != 8:
- print("Welcome to Uber simulator! We are currently in day", day, "of the simulation!\nPick an option :\n1) Add driver\n2) Add passenger\n3) Make Uber ride\n4) Give car to driver\n5) Go to next day\n6) Print drivers\n7) Print passengers\n8) Exit")
- opt = int(input())
- if opt == 1: # Cria um novo motorista
- if random.randrange(1, 500,1) == 123:
- dname = "Passos Dias Aguiar"
- else:
- dname = (random.choice(Fnames) + " " + random.choice(Lnames))
- boolAux = False
- while not boolAux:
- position = Position(random.uniform(-200 ,200),random.uniform(-100,200))
- boolAux = IsInCity(position)
- driver = Driver(dname, position)
- driver.city = driver.FindCity()
- driver.cars.append(ChooseCar(driver))
- driver.CurrCar = random.choice(driver.cars)
- Dlist.append(driver)
- print(driver)
- if opt == 2: # Cria um novo passageiro
- pname = (random.choice(Fnames) + " " + random.choice(Lnames))
- boolAux = False
- while not boolAux:
- position = Position(random.uniform(-200 ,200),random.uniform(-100,200))
- boolAux = IsInCity(position)
- passenger = Passenger(pname, position)
- passenger.city = passenger.FindCity()
- Plist.append(passenger)
- print(passenger)
- if opt == 3: # Faz uma corrida com um motorista e um passageiro aleatório
- boolAux = False
- while not boolAux:
- random.shuffle(Plist)
- passenger = Plist.pop() # Sorteia um passageiro para a corrida
- random.shuffle(Dlist)
- driver = Dlist.pop() # Sorteia um motorista para a corrida
- RideType = UberChooser() # Escolhe o tipo de Uber desejado pra viagem
- if Car_List.get(driver.CurrCar) % RideType == 0: # Verifica se o motorista pode efetuar o tipo desejado de viagem
- boolAux = True
- else:
- Plist.append(passenger)
- Dlist.append(driver)
- boolAux = False
- while not boolAux: # Pega um destino para a corrida
- position = Position(random.uniform(-200 ,200),random.uniform(-100,200))
- boolAux = IsInCity(position)
- ride = Ride(driver, passenger, position)
- if FindDistance(passenger.position, booster) <= 30 and CityFinder(booster) == passenger.city:
- ride.boost = True
- ride.type = FareFromType(RideType) # Muda o valor da taxa dependendo do tipo de Uber solicitado
- ride.price = ride.CalcPrice() # Calcula o preço da corrida
- tip = CalculateTip(ride) # Calcula a gorjeta
- earnings = driver.CalculateEarnings(ride.price, tip)
- PrintRide(ride, tip, earnings, ride.boost, RideType)
- passenger.position = position
- passenger.city = passenger.FindCity()
- driver.position = position
- driver.city = driver.FindCity()
- driver.streak = driver.streak + 1
- Dlist.append(driver)
- Plist.append(passenger)
- if opt == 4: # Dá um carro novo para um motorista
- random.shuffle(Dlist)
- driver = Dlist.pop()
- driver = GetNewCar(driver)
- Dlist.append(driver)
- if opt == 5:
- print("Day", day,"is over and streak bonuses were reset...")
- booster = MakeBoostZone()
- print("A booster zone currently exists in part of", CityFinder(booster))
- day = day + 1
- for drivers in Dlist:
- drivers.streak = 0
- drivers.CurrCar = random.choice(drivers.cars)
- if opt == 6:
- for drivers in Dlist:
- print(drivers)
- print()
- if opt == 7:
- for passengers in Plist:
- print(passengers)
- print()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement