script_ok2.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. '''
  2. @author: olivier.massot, 2019
  3. '''
  4. import sys
  5. def log(x):
  6. print(x, file=sys.stderr)
  7. # Cells
  8. BLUEBERRIES_CRATE = "B"
  9. ICE_CREAM_CRATE = "I"
  10. WINDOW = "W"
  11. EMPTY_TABLE = "#"
  12. DISHWASHER = "D"
  13. FLOOR_CELL = "."
  14. # Items
  15. NONE = "NONE"
  16. DISH = "DISH"
  17. ICE_CREAM = "ICE_CREAM"
  18. BLUEBERRIES = "BLUEBERRIES"
  19. location = {DISH: DISHWASHER,
  20. ICE_CREAM: ICE_CREAM_CRATE,
  21. BLUEBERRIES: BLUEBERRIES_CRATE,
  22. WINDOW: WINDOW}
  23. class Base():
  24. def __repr__(self):
  25. return f"<{self.__class__.__name__}: {self.__dict__}>"
  26. class Customer(Base):
  27. def __init__(self, item, award):
  28. self.item = item
  29. self.award = int(award)
  30. class Cook(Base):
  31. def __init__(self, x, y, item):
  32. self.x = int(x)
  33. self.y = int(y)
  34. self.item = item
  35. self.order = ""
  36. @property
  37. def pos(self):
  38. return (self.x, self.y)
  39. def use(self, x, y, msg=""):
  40. print("USE", x, y, msg)
  41. def move(self, x, y):
  42. print("MOVE", x, y)
  43. class Table(Base):
  44. def __init__(self, x, y, item):
  45. self.x = int(x)
  46. self.y = int(y)
  47. self.item = item
  48. class Oven(Base):
  49. def __init__(self, contents, timer):
  50. self.contents = contents
  51. self.timer = int(timer)
  52. class Grid(Base):
  53. def __init__(self, cells):
  54. self.cells = cells
  55. def at(self, x, y):
  56. return self.cells[y][x]
  57. def flatten(self):
  58. return [(x, y, c) for y, row in enumerate(self.cells) for x, c in enumerate(row)]
  59. def where_are(self, content):
  60. return [(x, y) for x, y, c in self.flatten() if c == content]
  61. @staticmethod
  62. def distance(from_, to_):
  63. return abs(from_[0] - to_[0]) + abs(from_[1] - to_[1])
  64. def closest(self, from_, content):
  65. return sorted([(c, Grid.distance(from_, c)) for c in self.where_are(content)], key=lambda k: k[1])[0]
  66. # input vars
  67. num_all_customers = int(input())
  68. all_customers = [Customer(*input().split()) for _ in range(num_all_customers)]
  69. grid = Grid([list(input()) for i in range(7)])
  70. log(f"{num_all_customers} customers: {all_customers}")
  71. log(f"grid: {grid}")
  72. class Task(Base):
  73. def __init__(self, name, from_):
  74. self.name = name
  75. self.loc = location[name]
  76. self.pos, self.dist = grid.closest(from_, self.loc)
  77. while True:
  78. turns_remaining = int(input())
  79. player = Cook(*input().split())
  80. log(f"*** player: {player}")
  81. partner = Cook(*input().split())
  82. log(f"*** partner: {partner}")
  83. num_tables_with_items = int(input()) # the number of tables in the kitchen that currently hold an item
  84. tables = [Table(*input().split()) for _ in range(num_tables_with_items)]
  85. log(f"*** tables: {tables}")
  86. oven = Oven(*input().split())
  87. log(f"*** oven: {oven}")
  88. num_customers = int(input()) # the number of customers currently waiting for food
  89. customers = [Customer(*input().split()) for _ in range(num_customers)]
  90. log(f"*** customers: {customers}")
  91. ### SCRIPT
  92. # if no current order, take the most beneficial
  93. if not player.order:
  94. queue = sorted(customers, reverse=True, key=lambda x: x.award)
  95. player.order = queue[0].item.split('-')
  96. log(f'>>> new order taken: {player.order}')
  97. todo = [Task(t, player.pos) for t in player.order if t not in player.item]
  98. log(f"todo: {todo}")
  99. if not todo:
  100. # no task left, target is the window
  101. next_task = Task(WINDOW, player.pos)
  102. player.order, todo = [], []
  103. elif player.item != NONE and not DISH in player.item:
  104. # cook has something in its hands and no dish, he have to take one
  105. next_task = next((t for t in todo if t.name == "DISH"))
  106. else:
  107. # else, go for the closest task
  108. tasks = sorted(todo, key= lambda x: x.dist)
  109. next_task = next(iter(tasks), None)
  110. log(f"next_task: {next_task}")
  111. player.use(*next_task.pos)