Advertisement
oleh_korkh

Untitled

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