Advertisement
Guest User

Untitled

a guest
Jan 16th, 2018
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.58 KB | None | 0 0
  1.  
  2. SIMULATION_TIME = 300
  3.  
  4.  
  5. class Customer:
  6.     TIME_ON_CASE = 2    # Max value of delay on case
  7.     TIME_ON_START = 4    # Max value of delay on case
  8.  
  9.     def __init__(self, id, position, supermarket):
  10.         self.id = id
  11.         self.position = position
  12.         self.supermarket = supermarket
  13.         self.purchasing = None
  14.  
  15.         self.path = []
  16.         for i in self.supermarket.key_points.keys():
  17.             if self.id % i == 0:
  18.                 self.path += self.supermarket.key_points[i]
  19.         self.update_path()
  20.         self.start_delay = -1
  21.         self.cash_wait = -1
  22.         self.customer_symbols = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
  23.  
  24.  
  25.     def update_path(self):
  26.         self.path = sorted(
  27.             self.path,
  28.             key=lambda t: ((t[0]-self.position[0])**2 + (t[1]-self.position[1])**2)**0.5,
  29.             )
  30.         # print(self.path)
  31.  
  32.     def free_to_walk(self, target):
  33.         d_x = target[0] - self.position[0]
  34.         d_y = target[1] - self.position[1]
  35.  
  36.         x_direction = 0 if d_x == 0 else 1 if d_x > 0 else -1
  37.         y_direction = 0 if d_y == 0 else 1 if d_y > 0 else -1
  38.         new_position = (
  39.             self.position[0] + x_direction,
  40.             self.position[1] + y_direction)
  41.         if self.start_delay == 0:
  42.             if self.supermarket.is_cell_free(new_position):
  43.                 return new_position
  44.             else:
  45.                 possible_new_positions = [
  46.                     (self.position[0]-1, self.position[1]),
  47.                     (self.position[0]-1, self.position[1]-1),
  48.                     (self.position[0], self.position[1]-1),
  49.                     (self.position[0]+1, self.position[1]-1),
  50.                     (self.position[0]+1, self.position[1]),
  51.                     (self.position[0]+1, self.position[1]+1),
  52.                     (self.position[0], self.position[1]+1),
  53.                     (self.position[0]-1, self.position[1]+1),
  54.                 ]
  55.                 possible_new_positions = [
  56.                     x for x in possible_new_positions
  57.                     if self.supermarket.is_cell_free(x)]
  58.                 if possible_new_positions:
  59.                     new_positions = sorted(
  60.                         possible_new_positions,
  61.                         key=lambda t: ((t[0]-target[0])**2 + (t[1]-target[1])**2)**0.5,
  62.                     )
  63.                     return new_positions[0]
  64.                     # print('::', self.id, new_positions)
  65.         elif self.start_delay > 0:
  66.             self.start_delay -=1
  67.             print (self.start_delay)
  68.         else:
  69.             import random
  70.             self.start_delay = random.randint(1, self.TIME_ON_START)-1
  71.             print ('user %d have to wait %d steps' %(self.id, self.start_delay+1))
  72.  
  73.     def walk(self):
  74.         if self.position in self.path:
  75.             if self.purchasing == 'go_to_cash':
  76.                 self.purchasing = 'cash'
  77.             self.path.remove(self.position)
  78.             self.update_path()
  79.  
  80.         # print(self.id, self.purchasing, self.path)
  81.  
  82.         if self.path:
  83.             target = self.path[0]
  84.             new_position = self.free_to_walk(target)
  85.             if new_position:
  86.                 self.position = new_position
  87.                 # print('customer #%d is trying to go to (%d, %d)' % (
  88.                 #     self.id,
  89.                 #     self.position[0],
  90.                 #     self.position[1],
  91.                 #     ))
  92.         elif self.purchasing == 'finished':
  93.             print('customer #%d went out' % self.id)
  94.             self.supermarket.customers.remove(self)
  95.             self.supermarket.customers_out += 1
  96.         elif self.purchasing == 'cash':
  97.             if self.cash_wait > 0:
  98.                 print('left to wait for Customer #%d steps...%d' % (self.id, self.cash_wait))
  99.                 self.cash_wait -=1
  100.             elif self.cash_wait == 0:
  101.                 self.purchasing = 'purchased'
  102.                 # print('PURCHASED' + str(self.id))
  103.             else:
  104.                 import random
  105.                 self.cash_wait = random.randint(1, self.TIME_ON_CASE)
  106.                 # if self.cash_wait
  107.            
  108.         elif self.purchasing == 'purchased':
  109.             new_positions = sorted(
  110.                     self.supermarket.finish_slots,
  111.                     key=lambda t: ((t[0]-self.position[0])**2 + (t[1]-self.position[1])**2)**0.5,
  112.                 )
  113.             if new_positions:
  114.                 self.position = new_positions[0]
  115.                 self.purchasing = 'finished'
  116.                 print('customer #%d is going out' % self.id)
  117.         elif self.purchasing != 'go_to_cash':
  118.             import random
  119.             self.path = [random.choice(self.supermarket.cash_registers)]
  120.             new_position = self.free_to_walk(self.path[0])
  121.             if new_position:
  122.                 self.position = new_position
  123.                 self.purchasing = 'go_to_cash'
  124.  
  125.     def view(self):
  126.  
  127.         if self.id < len(self.customer_symbols):
  128.             return self.customer_symbols[self.id-1]
  129.         else:
  130.  
  131.             return self.customer_symbols[(self.id % len(self.customer_symbols))]
  132.             # return self.customer_symbols[self.id % len(self.customer_symbols)]
  133.         # elif self.id % 3 == 0:
  134.         #     return '☀'
  135.         # return '*'
  136.  
  137.  
  138. class Supermarket:
  139.     WALL = '#'
  140.     CASH = 'C'
  141.     START = 'S'
  142.     FINISH = 'F'
  143.  
  144.     def __init__(self, file_name):
  145.         from collections import defaultdict
  146.  
  147.         with open(file_name) as f:
  148.             self.data = [list(x.strip()) for x in f]
  149.  
  150.         self.height = len(self.data)
  151.         self.width = len(self.data[0])
  152.  
  153.         self.walls = []
  154.         self.cash_registers = []
  155.         self.start_slots = []
  156.         self.finish_slots = []
  157.         self.key_points = defaultdict(list)
  158.  
  159.         for y, row in enumerate(self.data):
  160.             for x, ch in enumerate(row):
  161.                 if ch == self.WALL:
  162.                     self.walls.append((x, y))
  163.                 elif ch == self.CASH:
  164.                     self.cash_registers.append((x, y))
  165.                 elif ch == self.START:
  166.                     self.start_slots.append((x, y))
  167.                 elif ch == self.FINISH:
  168.                     self.finish_slots.append((x, y))
  169.                 elif ch.isdigit():
  170.                     self.key_points[int(ch)].append((x, y))
  171.  
  172.         self.customers = []
  173.         self.next_customer_id = 1
  174.         self.customers_in = 0
  175.         self.customers_out = 0
  176.  
  177.     def get_customer_for_cell(self, position):
  178.         for x in self.customers:
  179.             if position == x.position:
  180.                 return x
  181.  
  182.     def is_cell_free(self, position, allow_finish=False):
  183.         if (0 <= position[0] <= self.width - 1) and \
  184.                 (0 <= position[1] <= self.height - 1):
  185.             if position not in self.walls and \
  186.                     position not in [x.position for x in self.customers]:
  187.                 if position in self.finish_slots and not allow_finish:
  188.                     return False
  189.                 return True
  190.         return False
  191.  
  192.     def add_customer(self):
  193.         entries = [x for x in self.start_slots if self.is_cell_free(x)]
  194.         if entries:
  195.             customer = Customer(
  196.                 self.next_customer_id,
  197.                 entries[0],
  198.                 self)
  199.             self.customers.append(customer)
  200.             self.next_customer_id += 1
  201.             self.customers_in += 1
  202.             return customer
  203.  
  204.     def move_customers(self):
  205.         for x in self.customers:
  206.             x.walk()
  207.  
  208.     def draw(self):
  209.         for y, row in enumerate(self.data):
  210.             for x, c in enumerate(row):
  211.                 t = self.get_customer_for_cell((x, y))
  212.                 print(t.view() if t else c, end='')
  213.             print()
  214.  
  215. supermarket = Supermarket('input.txt')
  216.  
  217. customer_limit =100
  218. current_time = 0
  219. customer_count = 0
  220. while current_time < SIMULATION_TIME:
  221.     print('Time: %d Customers inside: %d Customers in: %d Customers out: %d' % (
  222.         current_time, len(supermarket.customers),
  223.         supermarket.customers_in,
  224.         supermarket.customers_out))
  225.     supermarket.move_customers()
  226.  
  227.    
  228.     customer_count += 1
  229.     if customer_count <= customer_limit:
  230.         customer = supermarket.add_customer()
  231.     if customer:
  232.         print('New customer #%d just came in at (%d, %d)' % (
  233.             customer.id,
  234.             customer.position[0],
  235.             customer.position[1]))
  236.     else:
  237.         print('New customer cannot come into the supermarket.')
  238.  
  239.     supermarket.draw()
  240.     current_time += 1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement