Browse Source

rename cook.py

olinox 6 years ago
parent
commit
9bc61268e3
4 changed files with 0 additions and 1306 deletions
  1. 0 596
      code_a_la_mode/cook_svg.py
  2. 0 601
      code_a_la_mode/cook_svg2.py
  3. 0 109
      code_a_la_mode/recurse_try.py
  4. 0 0
      code_a_la_mode/script.py

+ 0 - 596
code_a_la_mode/cook_svg.py

@@ -1,596 +0,0 @@
-'''
-
-@author: olivier.massot, 2019
-'''
-import heapq
-import sys
-
-DEBUG = True
-
-
-def log(x):
-    if DEBUG: print(x, file=sys.stderr)
-
-
-# -- Base class
-class Base():
-
-    def __repr__(self):
-        return f"<{self.__class__.__name__}: {self.__dict__}>"
-
-
-# --- locations
-class Location(Base):
-    name = ""
-    passable = False
-
-class SpecialLocation(Location):
-    pass
-
-class DishWasher(SpecialLocation):
-    pass
-
-class IcecreamCrate(SpecialLocation):
-    pass
-
-class BlueberriesCrate(SpecialLocation):
-    pass
-
-class StrawberriesCrate(SpecialLocation):
-    pass
-
-class DoughCrate(SpecialLocation):
-    pass
-
-class ChoppingBoard(SpecialLocation):
-    pass
-
-class Oven(SpecialLocation):
-    def __init__(self):
-        self._content = None
-        self._timer = 0
-
-    @property
-    def content(self):
-        return self._content
-    
-    @content.setter
-    def content(self, content):
-        self._content = match[content]
-        
-    @property
-    def timer(self):
-        return self._timer
-    
-    @timer.setter
-    def timer(self, timer):
-        self._timer = int(timer)
-        
-    def update(self, content, timer):
-        self.content = content
-        self.timer = timer
-
-class Window(SpecialLocation):
-    pass
-
-class Start(Location):
-    passable = True
-
-class Start0(Start): pass
-class Start1(Start): pass
-
-class FloorCell(Location):
-    passable = True
-
-class EmptyTable(Location):
-    pass
-
-locations = [DishWasher, IcecreamCrate, BlueberriesCrate, StrawberriesCrate, DoughCrate, ChoppingBoard, Oven, Window, Start0, Start1, FloorCell, EmptyTable]
-special_locations = [l for l in locations if l is SpecialLocation]
-
-# -- Grid
-class PathNode(tuple):
-    def __new__(self, x, y, parent=None):
-        n = tuple.__new__(self, (x, y))
-        n.parent = parent
-        n.cost = 0
-        return n
-
-class Grid(Base):
-    def __init__(self, cells):
-        self.cells = cells
-        self.w, self.h = len(cells[0]), len(cells)
-        self.add_costs = {}
-
-    def at(self, x, y):
-        return self.cells[y][x]
-
-    def flatten(self):
-        return [(x, y, c) for y, row in enumerate(self.cells) for x, c in enumerate(row)]
-
-    @property
-    def coords(self):
-        return [(x, y) for y in range(self.h) for x in range(self.w)]
-
-    def where_are(self, content):
-        return [(x, y) for x, y, c in self.flatten() if c is content]
-
-    @staticmethod
-    def distance(from_, to_):
-        return abs(from_[0] - to_[0]) + abs(from_[1] - to_[1])
-
-    def items(self):
-        return [c for row in self.cells for c in row]
-
-    def closest_in(self, from_, coords):
-        return sorted([(c, Grid.distance(from_, c)) for c in coords], key=lambda k: k[1])[0]
-
-    def closest(self, from_, content):
-        return self.closest_in(from_, self.where_are(content))
-
-    def neighbors(self, x, y, diags=True):
-        neighs = [(x, y - 1), (x - 1, y), (x + 1, y), (x, y + 1)]
-        if diags:
-            neighs += [(x - 1, y - 1), (x + 1, y - 1), (x - 1, y + 1), (x + 1, y + 1)]
-        return [(x, y) for x, y in neighs if 0 <= x < self.w and 0 <= y < self.h]
-
-    def passable(self, x, y):
-        return self.at(x, y).passable
-
-    def cost(self, x, y):
-        return 10 + self.add_costs.get((x, y), 0)
-
-    def path(self, origin, target, incl_start=False):
-        nodes = []
-        origin = PathNode(*origin)
-        targets = grid.neighbors(*target)
-        heapq.heappush(nodes, (0, origin))
-
-        while nodes:
-            current = heapq.heappop(nodes)[1]
-
-            if current in targets:
-                path = []
-                next_ = current
-                while next_:
-                    if next_ != origin or incl_start:
-                        path.insert(0, next_)
-                    next_ = next_.parent
-                return path
-
-            neighbors = self.neighbors(*current, False)
-
-            for x, y in neighbors:
-
-                if not self.passable(x, y):
-                    continue
-
-                cost = current.cost + self.cost(x, y)
-                priority = cost + 10 * (abs(x - target[0]) + abs(y - target[1]))
-
-                node = PathNode(x, y, current)
-                node.cost = cost
-                heapq.heappush(nodes, (priority, node))
-        else:
-            return None
-
-
-class Order(Base):
-    def __init__(self, order):
-        self.order = order
-
-class Plate(Base):
-    def __init__(self):
-        self.pos = (-1, -1)
-        self.content = []
-
-class Dish(Base):
-    location = DishWasher
-
-class BaseDessert(Base):
-    name = ""
-
-class SimpleDessert(BaseDessert):
-    location = None
-
-class PreparedDessert(BaseDessert):
-    ingredients = []
-
-class CookedDessert(BaseDessert):
-    ingredients = []
-
-class Ingredient(Base):
-    location = None
-    transformer = None
-
-class CookIngredient():
-    location = None
-    cooking_time = 0
-    
-# --- desserts
-class IceCream(SimpleDessert):
-    location = IcecreamCrate
-
-class Blueberries(SimpleDessert):
-    location = BlueberriesCrate
-
-class Strawberries(Ingredient):
-    location = StrawberriesCrate
-    transformer = ChoppingBoard
-
-class ChoppedStrawberries(PreparedDessert):
-    ingredients = [Strawberries]
-
-class Dough(CookIngredient):
-    location = DoughCrate
-    cooking_time = 10
-
-class Croissant(CookedDessert):
-    location = Oven
-    ingredients = [Dough]
-
-class Customer(Base):
-    def __init__(self, item, award):
-        self.order = [match[i] for i in item.split('-')]
-        self.award = int(award)
-
-class Table(Base):
-    def __init__(self, x, y, item):
-        self.x = int(x)
-        self.y = int(y)
-        self.item = [match[i] for i in item.split('-')]
-
-    @property
-    def pos(self):
-        return (self.x, self.y)
-
-
-# --- Actions
-
-class Action(Base):
-    needs_dish = False
-    needs_hands = False
-    
-    def __init__(self, location):
-        self.location = location
-    
-    def locate(self, player):
-        self.pos, self.dist = grid.closest(player.pos, self.location)
-
-class GetAction(Action):
-
-    def __init__(self, subject):
-        self.subject = subject
-        self.location = self.subject.location
-    
-    def locate(self, player):
-        available = grid.where_are(self.location)
-        available += [t.pos for t in tables if self.subject == [t.item]]
-        self.pos, self.dist = grid.closest_in(player.pos, available)
-
-class GetDessert(GetAction):
-    needs_dish = True
-
-class GetIngredient(GetAction):
-    needs_hands = True
-
-class GetDish(GetAction):
-    def __init__(self):
-        super().__init__(Dish)
-
-class Transform(Action):
-    def __init__(self, subject):
-        self.location = subject.transformer
-
-class Cook(Action):
-    def __init__(self):
-        self.location = Oven
-
-class GetCookedDessert(GetDessert):
-    def __init__(self, subject):
-        super().__init__(subject)
-        self.location = Oven
-        
-class Deliver(Action):
-    def __init__(self):
-        self.location = Window
-
-class DropDish(Action):
-    def __init__(self):
-        self.subject = None
-        self.location = EmptyTable
-
-# class GetBackDish(Action):
-#     def __init__(self, pos):
-#         self._pos = pos
-#     
-#     def locate(self, player):
-#         self.pos = self._pos
-#         self.dist = Grid.distance(player.pos, self._pos)
-        
-class GetOnTable(Action):
-    def __init__(self, pos):
-        self._pos = pos
-    
-    def locate(self, player):
-        self.pos = self._pos
-        self.dist = Grid.distance(player.pos, self._pos)
-
-class Cooker(Base):
-    def __init__(self):
-        self._x = -1
-        self._y = -1
-        self._in_hand = []
-#         self.plate = Plate()
-        self.order = []
-#         self.unexpected = []
-
-    @property
-    def x(self):
-        return self._x
-
-    @x.setter
-    def x(self, x):
-        self._x = int(x)
-
-    @property
-    def y(self):
-        return self._y
-
-    @y.setter
-    def y(self, y):
-        self._y = int(y)
-
-    @property
-    def pos(self):
-        return (self.x, self.y)
-
-    @property
-    def in_hand(self):
-        return self._in_hand
-
-    @in_hand.setter
-    def in_hand(self, item):
-        self._in_hand = [x for x in [match[i] for i in item.split('-')] if x is not None]
-
-    def take_order(self, order):
-        self.order = order
-
-    def order_fullfilled(self):
-        self.order = []
-
-    def update(self, x, y, item):
-        self.x = x
-        self.y = y
-        self.in_hand = item
-
-    @property
-    def hands_free(self):
-        return len(self._in_hand) == 0
-
-    @property
-    def dish_handed(self):
-        return Dish in self.in_hand
-
-    def eval_orders(self, customers):
-        waiting = sorted(customers, reverse=True, key=lambda x: x.award)
-        self.take_order(waiting[0].order)
-        
-        
-    def todo(self):
-        todo = []
-        
-        store = None
-        
-        for table in tables:
-            if all((i in self.order and not i in self.in_hand) for i in table.item):
-                store = table
-        
-        for item in self.order:
-
-            if item in self.in_hand or (store and item in store.item):
-                # already done
-                continue
-            
-            if issubclass(item, SimpleDessert):
-                todo.append(GetDessert(item))
-                
-            elif issubclass(item, PreparedDessert):
-                for ingredient in item.ingredients:
-                    if ingredient in self.in_hand:
-                        todo.append(Transform(ingredient))
-                    else:
-                        todo.append(GetIngredient(ingredient))
-                    
-            elif issubclass(item, CookedDessert):
-                for ingredient in item.ingredients:
-                    if ingredient in self.in_hand:
-                        todo.append(Cook())
-                    elif type(ingredient) == type(oven.content) or type(item) == type(oven.content):
-                        if oven.timer < 3:
-                            todo.append(GetCookedDessert(item))
-                    else:
-                        todo.append(GetIngredient(ingredient))
-                        
-            elif issubclass(item, Dish):
-                todo.append(GetDish())
-                 
-            else:
-                log(f"<!> Unknown order: {item}")
-        
-        if store:
-            todo.append(GetOnTable(store.pos))
-        
-        # nothing left to do: deliver
-        if not todo:
-            todo = [Deliver()]
-        
-        # if the current order is not anymore in the queue, drop the dish
-        if not self.order in [c.order for c in customers]:
-            player.order = []
-            todo = [DropDish()]
-        
-        for action in todo:
-            action.locate(self)
-        
-        return todo
-
-
-    def act(self, action):
-        if isinstance(action, Deliver) and action.pos in grid.neighbors(*self.pos):
-            self.order = []
-            
-        elif isinstance(action, GetIngredient) and self.dish_handed:
-            # cannot act, needs to drop the dish
-            log("need to drop")
-            action = DropDish()
-            action.locate(self)
-#             self.unexpected.append(GetBackDish(action.pos))
-            
-        self.use(*action.pos)
-
-    def use(self, x, y, msg=""):
-        print("USE", x, y, msg)
-
-    def move(self, x, y):
-        print("MOVE", x, y)
-
-    def wait(self):
-        print("WAIT")
-
-# --- constants
-match = {
-            '0': Start0,
-            '1': Start1,
-            'B': BlueberriesCrate,
-            'I': IcecreamCrate,
-            'S': StrawberriesCrate,
-            'C': ChoppingBoard,
-            'H': DoughCrate,
-            'W': Window,
-            '#': EmptyTable,
-            'D': DishWasher,
-            '.': FloorCell,
-            'O': Oven,
-            'NONE': None,
-            'DISH': Dish,
-            'ICE_CREAM': IceCream,
-            'BLUEBERRIES': Blueberries,
-            'STRAWBERRIES': Strawberries,
-            'CHOPPED_STRAWBERRIES': ChoppedStrawberries,
-            'DOUGH': Dough,
-            'CROISSANT': Croissant
-        }
-
-# --- input vars
-
-num_all_customers = int(input())
-all_customers = [Customer(*input().split()) for _ in range(num_all_customers)]
-
-grid = Grid([[match[c] for c in input()] for i in range(7)])
-
-log(f"{num_all_customers} customers: {all_customers}")
-log(f"grid: {grid}")
-
-player = Cooker()
-partner = Cooker()
-oven = next((i for i in grid.items() if type(i) is Oven), Oven())
-
-while True:
-    # <--- turn input
-    turns_remaining = int(input())
-
-    player.update(*input().split())
-    log(f"*** player: {player}")
-
-    partner.update(*input().split())
-    log(f"*** partner: {partner}")
-
-    num_tables_with_items = int(input())  # the number of tables in the kitchen that currently hold an item
-    tables = [Table(*input().split()) for _ in range(num_tables_with_items)]
-    log(f"*** tables: {tables}")
-
-    oven.update(*input().split())
-    log(f"*** oven: {oven}")
-
-    num_customers = int(input())  # the number of customers currently waiting for food
-    customers = [Customer(*input().split()) for _ in range(num_customers)]
-    log(f"*** customers: {customers}")
-    # --->
-
-    # ## SCRIPT
-
-    # if no current order, take the most awarded
-    if not player.order:
-        player.eval_orders(customers)
-        log(f'>>> new order taken: {player.order}')
-
-    todo = player.todo()
-    log(f"todo: {todo}")
-    
-    next_task = None
-    for action in todo:
-        if isinstance(action, Deliver):
-            # order fulfilled: deliver
-            next_task = action
-            break
-            
-        elif isinstance(action, Transform):
-            # If cook has an ingredient in hands, he needs to prepare it
-            next_task = action
-            break
-        
-        elif isinstance(action, Cook):
-            # If cook has an cook_ingredient in hands, he needs to cook it
-            next_task = action
-            break
-
-        elif action.needs_hands and player.hands_free:
-            # If hands are free and an ingredient is needed, we go for it first
-            next_task = action
-            break
-
-        elif isinstance(action, GetOnTable):
-            # there is a dish waiting on a table
-            next_task = action
-            break    
-        
-        elif isinstance(action, GetDish) and any(h for h in player.in_hand if issubclass(h, BaseDessert)):
-            # cook has a dessert in its hands and no dish, he have to take one
-            next_task = action
-            break
-        
-    if not next_task:
-        # else, go for the closest task
-        tasks = sorted(todo, key=lambda x: x.dist)
-        next_task = next(iter(tasks))
-
-    log(f"next task: {next_task}")
- 
-    # <--- Update moving costs
-    # update grid movement costs following the probability of finding the partner here
-    partner_could_be_there = [(x, y) for x, y in grid.coords if grid.passable(x, y) and grid.distance(partner.pos, (x, y)) <= 4]
-    grid.add_costs = {}
-    for x, y in partner_could_be_there:
-        k1 = 2 if (x, y) == partner.pos else 1
-        # cell is next to a special cell, partner has more chance to stop there
-        k2 = 2 if any((c for c in grid.neighbors(x, y) if isinstance(grid.at(*c), SpecialLocation))) else 1
-        grid.add_costs[(x, y)] = k1 * k2 * 3
-    log(grid.add_costs)
-    # --->
- 
-    # <--- compute shortest path
-    path = grid.path(player.pos, next_task.pos)
-    log(path)
-    # --->
- 
-    if path is not None:
-        if len(path) > 0:
-            if len(path) > 4:
-                player.move(*path[3])
-            else:
-                player.move(*path[-1])
-        else:
-            player.act(next_task)
-    else:
-        player.act(next_task)

+ 0 - 601
code_a_la_mode/cook_svg2.py

@@ -1,601 +0,0 @@
-'''
-
-@author: olivier.massot, 2019
-'''
-import heapq
-import sys
-
-DEBUG = True
-
-
-def log(x):
-    if DEBUG: print(x, file=sys.stderr)
-
-
-# -- Base class
-class Base():
-
-    def __repr__(self):
-        return f"<{self.__class__.__name__}: {self.__dict__}>"
-
-
-# --- locations
-class Location(Base):
-    name = ""
-    passable = False
-
-class SpecialLocation(Location):
-    pass
-
-class DishWasher(SpecialLocation):
-    pass
-
-class IcecreamCrate(SpecialLocation):
-    pass
-
-class BlueberriesCrate(SpecialLocation):
-    pass
-
-class StrawberriesCrate(SpecialLocation):
-    pass
-
-class DoughCrate(SpecialLocation):
-    pass
-
-class ChoppingBoard(SpecialLocation):
-    pass
-
-class Oven(SpecialLocation):
-    def __init__(self):
-        self._content = None
-        self._timer = 0
-
-    @property
-    def content(self):
-        return self._content
-    
-    @content.setter
-    def content(self, content):
-        self._content = match[content]
-        
-    @property
-    def timer(self):
-        return self._timer
-    
-    @timer.setter
-    def timer(self, timer):
-        self._timer = int(timer)
-        
-    def update(self, content, timer):
-        self.content = content
-        self.timer = timer
-
-class Window(SpecialLocation):
-    pass
-
-class Start(Location):
-    passable = True
-
-class Start0(Start): pass
-class Start1(Start): pass
-
-class FloorCell(Location):
-    passable = True
-
-class EmptyTable(Location):
-    pass
-
-locations = [DishWasher, IcecreamCrate, BlueberriesCrate, StrawberriesCrate, DoughCrate, ChoppingBoard, Oven, Window, Start0, Start1, FloorCell, EmptyTable]
-special_locations = [l for l in locations if l is SpecialLocation]
-tables = []
-
-# -- Grid
-class PathNode(tuple):
-    def __new__(self, x, y, parent=None):
-        n = tuple.__new__(self, (x, y))
-        n.parent = parent
-        n.cost = 0
-        return n
-
-class Grid(Base):
-    def __init__(self, cells):
-        self.cells = cells
-        self.w, self.h = len(cells[0]), len(cells)
-        self.add_costs = {}
-
-    def at(self, x, y):
-        return self.cells[y][x]
-
-    def flatten(self):
-        return [(x, y, c) for y, row in enumerate(self.cells) for x, c in enumerate(row)]
-
-    @property
-    def coords(self):
-        return [(x, y) for y in range(self.h) for x in range(self.w)]
-
-    def where_are(self, content):
-        return [(x, y) for x, y, c in self.flatten() if c is content]
-
-    @staticmethod
-    def distance(from_, to_):
-        return abs(from_[0] - to_[0]) + abs(from_[1] - to_[1])
-
-    def items(self):
-        return [c for row in self.cells for c in row]
-
-    def closest_in(self, from_, coords):
-        return sorted([(c, Grid.distance(from_, c)) for c in coords], key=lambda k: k[1])[0]
-
-    def closest(self, from_, content):
-        return self.closest_in(from_, self.where_are(content))
-
-    def neighbors(self, x, y, diags=True):
-        neighs = [(x, y - 1), (x - 1, y), (x + 1, y), (x, y + 1)]
-        if diags:
-            neighs += [(x - 1, y - 1), (x + 1, y - 1), (x - 1, y + 1), (x + 1, y + 1)]
-        return [(x, y) for x, y in neighs if 0 <= x < self.w and 0 <= y < self.h]
-
-    def passable(self, x, y):
-        return self.at(x, y).passable
-
-    def cost(self, x, y):
-        return 10 + self.add_costs.get((x, y), 0)
-
-    def path(self, origin, target, incl_start=False):
-        nodes = []
-        origin = PathNode(*origin)
-        targets = grid.neighbors(*target)
-        heapq.heappush(nodes, (0, origin))
-
-        while nodes:
-            current = heapq.heappop(nodes)[1]
-
-            if current in targets:
-                path = []
-                next_ = current
-                while next_:
-                    if next_ != origin or incl_start:
-                        path.insert(0, next_)
-                    next_ = next_.parent
-                return path
-
-            neighbors = self.neighbors(*current, False)
-
-            for x, y in neighbors:
-
-                if not self.passable(x, y):
-                    continue
-
-                cost = current.cost + self.cost(x, y)
-                priority = cost + 10 * (abs(x - target[0]) + abs(y - target[1]))
-
-                node = PathNode(x, y, current)
-                node.cost = cost
-                heapq.heappush(nodes, (priority, node))
-        else:
-            return None
-
-
-class Order(Base):
-    def __init__(self, order):
-        self.order = order
-
-class Dish(Base):
-    location = DishWasher
-
-class BaseDessert(Base):
-    name = ""
-
-class SimpleDessert(BaseDessert):
-    location = None
-
-class PreparedDessert(BaseDessert):
-    ingredients = []
-
-class CookedDessert(BaseDessert):
-    ingredients = []
-
-class Ingredient(Base):
-    location = None
-    transformer = None
-
-class CookIngredient():
-    location = None
-    cooking_time = 0
-    
-# --- desserts
-class IceCream(SimpleDessert):
-    location = IcecreamCrate
-
-class Blueberries(SimpleDessert):
-    location = BlueberriesCrate
-
-class Strawberries(Ingredient):
-    location = StrawberriesCrate
-    transformer = ChoppingBoard
-
-class ChoppedStrawberries(PreparedDessert):
-    ingredients = [Strawberries]
-
-class Dough(CookIngredient):
-    location = DoughCrate
-    cooking_time = 10
-
-class Croissant(CookedDessert):
-    location = Oven
-    ingredients = [Dough]
-
-class Customer(Base):
-    def __init__(self, item, award):
-        self.order = [match[i] for i in item.split('-')]
-        self.award = int(award)
-
-class Table(Base):
-    def __init__(self, x, y, item):
-        self.x = int(x)
-        self.y = int(y)
-        self.item = [match[i] for i in item.split('-')]
-
-    @property
-    def pos(self):
-        return (self.x, self.y)
-
-
-# --- Actions
-
-class Action(Base):
-    needs_dish = False
-    needs_hands = False
-     
-    def __init__(self, location):
-        self.location = location
-     
-    def locate(self, player):
-        self.pos, self.dist = grid.closest(player.pos, self.location)
- 
-class GetAction(Action):
- 
-    def __init__(self, subject):
-        self.subject = subject
-        self.location = self.subject.location
-     
-    def locate(self, player):
-        available = grid.where_are(self.location)
-        available += [t.pos for t in tables if self.subject == [t.item]]
-        self.pos, self.dist = grid.closest_in(player.pos, available)
- 
-class GetDessert(GetAction):
-    needs_dish = True
- 
-class GetIngredient(GetAction):
-    needs_hands = True
- 
-class GetDish(GetAction):
-    def __init__(self):
-        super().__init__(Dish)
- 
-class Transform(Action):
-    def __init__(self, subject):
-        self.location = subject.transformer
- 
-class Cook(Action):
-    def __init__(self):
-        self.location = Oven
- 
-class GetCookedDessert(GetDessert):
-    def __init__(self, subject):
-        super().__init__(subject)
-        self.location = Oven
-         
-class Deliver(Action):
-    def __init__(self):
-        self.location = Window
- 
-class DropHanded(Action):
-    def __init__(self):
-        self.subject = None
-        self.location = EmptyTable
-         
-class GetOnTable(GetAction):
-    def __init__(self, pos):
-        self._pos = pos
-     
-    def locate(self, player):
-        self.pos = self._pos
-        self.dist = Grid.distance(player.pos, self._pos)
-
-class GetDishOnTable(GetOnTable):
-    pass
-
-class Cooker(Base):
-    def __init__(self):
-        self._x = -1
-        self._y = -1
-        self._in_hand = []
-        self.order = []
-
-    @property
-    def x(self):
-        return self._x
-
-    @x.setter
-    def x(self, x):
-        self._x = int(x)
-
-    @property
-    def y(self):
-        return self._y
-
-    @y.setter
-    def y(self, y):
-        self._y = int(y)
-
-    @property
-    def pos(self):
-        return (self.x, self.y)
-
-    @property
-    def in_hand(self):
-        return self._in_hand
-
-    @in_hand.setter
-    def in_hand(self, item):
-        self._in_hand = [x for x in [match[i] for i in item.split('-')] if x is not None]
-
-    def take_order(self, order):
-        self.order = order
-
-    def order_fullfilled(self):
-        self.order = []
-
-    def update(self, x, y, item):
-        self.x = x
-        self.y = y
-        self.in_hand = item
-
-    @property
-    def hands_free(self):
-        return len(self._in_hand) == 0
-
-    @property
-    def hands_full(self):
-        return any(issubclass(i, Ingredient) for i in self._in_hand)
-
-    @property
-    def dish_handed(self):
-        return Dish in self.in_hand
-
-    def eval_orders(self, customers):
-        waiting = sorted(customers, reverse=True, key=lambda x: x.award)
-        self.take_order(waiting[0].order)
-        
-    def todo(self):
-        todo = []
-        
-        store = None
-        
-        for table in tables:
-            if Dish in table.item and all((i in self.order and not i in self.in_hand) for i in table.item):
-                store = table
-        
-        for item in self.order:
-
-            if item in self.in_hand or (store and item in store.item):
-                # already done
-                continue
-            
-            if issubclass(item, SimpleDessert):
-                todo.append(GetDessert(item))
-                
-            elif issubclass(item, PreparedDessert):
-                
-                on_table = next((t for t in tables if [item] == t.item), None)
-                if on_table:
-                    todo.append(GetOnTable(on_table.pos))
-
-                else:
-                    for ingredient in item.ingredients:
-                        if ingredient in self.in_hand:
-                            todo.append(Transform(ingredient))
-                        else:
-                            todo.append(GetIngredient(ingredient))
-                    
-            elif issubclass(item, CookedDessert):
-                
-                on_table = next((t for t in tables if [item] in t.item), None)
-                if on_table:
-                    todo.append(GetOnTable(on_table.pos))
-
-                else:
-                    for ingredient in item.ingredients:
-                        if ingredient in self.in_hand:
-                            todo.append(Cook())
-                            
-                        elif type(item) == type(oven.content):
-                            todo.append(GetCookedDessert(item))
-                            
-                        elif type(ingredient) == type(oven.content):
-                            if oven.timer < 3:
-                                todo.append(GetCookedDessert(item))
-                                
-                        else:
-                            todo.append(GetIngredient(ingredient))
-                        
-            elif issubclass(item, Dish):
-                todo.append(GetDish())
-                 
-            else:
-                log(f"<!> Unknown order: {item}")
-        
-        if store:
-            todo.append(GetOnTable(store.pos))
-        
-        # nothing left to do: deliver
-        if not todo:
-            todo = [Deliver()]
-        
-        # if the current order is not anymore in the queue, drop the dish
-        if not self.order in [c.order for c in customers]:
-            player.order = []
-            todo = [DropHanded()]
-        
-        for action in todo:
-            action.locate(self)
-        
-        return todo
-
-
-    def act(self, action):
-        log("{}, {}, {}, {}".format(action.needs_hands, self.hands_free, isinstance(action, GetAction), self.hands_full))
-        if isinstance(action, Deliver) and action.pos in grid.neighbors(*self.pos):
-            self.order = []
-        
-        elif (action.needs_hands and not self.hands_free) or (isinstance(action, GetAction) and self.hands_full):
-            # cannot act, needs to drop the dish
-            log("need to drop")
-            action = DropHanded()
-            action.locate(self)
-            
-        self.use(*action.pos)
-
-    def use(self, x, y, msg=""):
-        print("USE", x, y, msg)
-
-    def move(self, x, y):
-        print("MOVE", x, y)
-
-    def wait(self):
-        print("WAIT")
-
-# --- constants
-match = {
-            '0': Start0,
-            '1': Start1,
-            'B': BlueberriesCrate,
-            'I': IcecreamCrate,
-            'S': StrawberriesCrate,
-            'C': ChoppingBoard,
-            'H': DoughCrate,
-            'W': Window,
-            '#': EmptyTable,
-            'D': DishWasher,
-            '.': FloorCell,
-            'O': Oven,
-            'NONE': None,
-            'DISH': Dish,
-            'ICE_CREAM': IceCream,
-            'BLUEBERRIES': Blueberries,
-            'STRAWBERRIES': Strawberries,
-            'CHOPPED_STRAWBERRIES': ChoppedStrawberries,
-            'DOUGH': Dough,
-            'CROISSANT': Croissant
-        }
-
-# --- input vars
-
-num_all_customers = int(input())
-all_customers = [Customer(*input().split()) for _ in range(num_all_customers)]
-
-grid = Grid([[match[c] for c in input()] for i in range(7)])
-
-log(f"{num_all_customers} customers: {all_customers}")
-log(f"grid: {grid}")
-
-player = Cooker()
-partner = Cooker()
-oven = next((i for i in grid.items() if type(i) is Oven), Oven())
-
-while True:
-    # <--- turn input
-    turns_remaining = int(input())
-
-    player.update(*input().split())
-    log(f"*** player: {player}")
-
-    partner.update(*input().split())
-    log(f"*** partner: {partner}")
-
-    num_tables_with_items = int(input())  # the number of tables in the kitchen that currently hold an item
-    tables = [Table(*input().split()) for _ in range(num_tables_with_items)]
-    log(f"*** tables: {tables}")
-
-    oven.update(*input().split())
-    log(f"*** oven: {oven}")
-
-    num_customers = int(input())  # the number of customers currently waiting for food
-    customers = [Customer(*input().split()) for _ in range(num_customers)]
-    log(f"*** customers: {customers}")
-    # --->
-
-    # ## SCRIPT
-
-    # if no current order, take the most awarded
-    if not player.order:
-        player.eval_orders(customers)
-        log('>>> new order taken')
-
-    log(f"order: {player.order}")
-
-    todo = player.todo()
-    log(f"todo: {todo}")
-    
-
-    priorities = [p for p in [
-            # order fulfilled: deliver
-            next((a for a in todo if type(a) is Deliver), None),
-            
-            # something to take out from the oven!
-            next((a for a in todo if type(a) is GetCookedDessert), None),
-            
-            # If cook has an ingredient in hands, he needs to prepare it
-            next((a for a in todo if type(a) is Transform), None),
-            
-            # If cook has an cook_ingredient in hands, he needs to cook it
-            next((a for a in todo if type(a) is Cook), None),
-            
-            # If hands are free and an ingredient is needed, we go for it first
-            next((a for a in todo if a.needs_hands and player.hands_free), None),
-            
-            # there is a dish waiting on a table
-            next((a for a in todo if type(a) is GetDishOnTable), None),
-            
-            # cook has a dessert in its hands and no dish, he have to take one
-            next((a for a in todo if isinstance(a, GetDish) and any(h for h in player.in_hand if issubclass(h, BaseDessert))), None),
-        ] if p is not None]
-    
-    if priorities:
-        next_task = priorities[0]
-        log(f"next task (priority): {next_task}")
-    else:
-        # else, go for the closest task
-        tasks = sorted(todo, key=lambda x: x.dist)
-        next_task = next(iter(tasks))
-        log(f"next task (closest): {next_task}")
- 
-    # <--- Update moving costs
-    # update grid movement costs following the probability of finding the partner here
-    partner_could_be_there = [(x, y) for x, y in grid.coords if grid.passable(x, y) and grid.distance(partner.pos, (x, y)) <= 4]
-    grid.add_costs = {}
-    for x, y in partner_could_be_there:
-        k1 = 2 if (x, y) == partner.pos else 1
-        # cell is next to a special cell, partner has more chance to stop there
-        k2 = 2 if any((c for c in grid.neighbors(x, y) if isinstance(grid.at(*c), SpecialLocation))) else 1
-        grid.add_costs[(x, y)] = k1 * k2 * 3
-    log(grid.add_costs)
-    # --->
- 
-    # <--- compute shortest path
-    path = grid.path(player.pos, next_task.pos)
-    log(path)
-    # --->
- 
-    if path is not None:
-        if len(path) > 0:
-            if len(path) > 4:
-                player.move(*path[3])
-            else:
-                player.move(*path[-1])
-        else:
-            player.act(next_task)
-    else:
-        player.act(next_task)

+ 0 - 109
code_a_la_mode/recurse_try.py

@@ -1,109 +0,0 @@
-'''
-Created on 17 mars 2019
-
-@author: olinox
-'''
-class Base(): pass
-
-
-
-class Location(Base):
-    name = ""
-    passable = False
-
-class SpecialLocation(Location):
-    pass
-class DishWasher(SpecialLocation):
-    pass
-class IcecreamCrate(SpecialLocation):
-    pass
-class BlueberriesCrate(SpecialLocation):
-    pass
-class StrawberriesCrate(SpecialLocation):
-    pass
-class DoughCrate(SpecialLocation):
-    pass
-class ChoppingBoard(SpecialLocation):
-    pass
-
-
-
-class Recipe(Base):
-    location = None
-    cooking_time = 0
-    requirements = []
-    needs_free_hands = False
-    
-    def available(self):
-        return []
-    
-    def get(self):
-        
-        pass
-        
-#         if available:
-#             # get it
-#         else:
-#             # does it have requirements?
-#             # if it has requirements that we don't hold: 
-#             #   recurse on those.
-#             
-#             # if it has requirements that we hold:
-#             # does it have a cooking time?
-#             
-#             # if yes: cook it
-#             # if no: go to self.location
-        
-        
-class FinalProduct(Recipe):
-    needs_dish = True
-    
-class Ingredient(Recipe):
-    needs_free_hands = True    
-
-class Dish(Recipe):
-    location = DishWasher
-
-class IceCream(FinalProduct):
-    location = IcecreamCrate
-
-class Blueberries(FinalProduct):
-    location = BlueberriesCrate
-    
-class Strawberries(Ingredient):
-    location = StrawberriesCrate
-    needs_free_hands = True
-    
-class ChoppedStrawberries(FinalProduct):
-    location = ChoppingBoard
-    requirements = [Strawberries]
-    
-class Dough(Ingredient):
-    location = DoughCrate
-    needs_free_hands = True
-
-class Croissant(FinalProduct):
-    requirements = [Dough]
-    cooking_time = 10
-    
-class ChoppedDough(Ingredient):
-    requirements = [Dough]
-    location = ChoppingBoard
-    
-class RawTart(Ingredient):
-    ingredients = [ChoppedDough, Blueberries]
-    
-class Tart(FinalProduct):
-    ingredients = [RawTart]
-    cooking_time = 10
-
-
-
-class ExampleOrder():
-    elements = [Dish, IceCream, ChoppedStrawberries, Croissant]
-    
-    def available(self):
-        # special
-        return []
-    
-    

+ 0 - 0
code_a_la_mode/cook.py → code_a_la_mode/script.py