예제 #1
0
def main():
    # First of all, load the registry
    registry = Registry()

    # Initialize player, display_manager
    player = Actor(Actors.HERO,
                   "Player",
                   '@',
                   Colors.WHITE,
                   behavior=None,
                   registry=registry)
    # XXX: Give player level boost for testing purposes
    player.level = 10

    # Initialize Dungeon
    dungeon = Dungeon()
    dungeon.initialize(player, registry)

    # Initialize Display Manager
    display_manager = DisplayManager(player, dungeon)
    message("Hello world!", Colors.RED)

    # Initialize Action Manager
    action_manager = ActionManager(player, dungeon)

    # Game loop
    while not tdl.event.is_window_closed():
        display_manager.refresh()
        # TODO: Add player and enemy turn states and cycle between both
        # Player turn
        # TODO: Use game states to handle turns

        action_manager.get_user_input()
        if action_manager.handle_key_input() is False:
            continue

        # Enemy turn
        for entity in dungeon.current_level.entities:
            entity.take_turn(player)

        # Check for player death
        # TODO: Handle player death as a game state
        if player.dead:
            # TODO: Show death screen
            print("You died!")
            return 0
예제 #2
0
class NodeManager:
    def __init__(self):
        self.db = database.DataBase()
        self.action_manager = ActionManager()
        # self.nodes = self.db.get_nodes()

    def get_start_node(self):
        reply = ReplyNode(self.db.get_reply_buttons('MENU', 'USER'),
                          self.db.get_reply_text('MENU'), 'MENU')
        return reply

    def get_node_id(self, message):
        status = self.db.get_status(message.from_user.id)
        role = self.db.get_role(message.from_user.id)
        next_node_id = self.db.get_next_node(message.text, status, role)
        action = self.action_manager.check_action(next_node_id)
        if action == "NONE":
            reply = ReplyNode(self.db.get_reply_buttons(next_node_id, role),
                              self.db.get_reply_text(next_node_id),
                              next_node_id, None)
            return reply
        elif action == 0:
            reply = ReplyNode(
                self.db.get_reply_buttons(status, role),
                configurer.config['REPLY']['unfinished'],
                status,
            )
            return reply
        else:
            return self.action_manager.get_node(action, status, message, role)

    def add_user(self, user_id, username):
        if not self.db.check(user_id):
            self.db.add_user(user_id, username)
        else:
            self.db.change_status(user_id, 'MENU')

    def check_inline_reply(self, node_id):
        return self.db.check_inline_reply(node_id)

    def change_status(self, message):
        status = self.db.get_status(message.from_user.id)
        role = self.db.get_status(message.from_user.id)
        next_node_id = self.db.get_next_node(message.text, status, role)
        self.db.change_status(message.from_user.id, next_node_id)
예제 #3
0
    def __init__(self):

        espeak.synth("Hello Master!")

        self.rec = VoiceRecognizer()

        self.actions = ActionManager().loadActions()

        self.canHear = True
예제 #4
0
    def __init__(self):

        espeak.synth("Hello Master!")

        self.rec = VoiceRecognizer()

        self.actions = ActionManager().loadActions()

        # Variable used for command voice control, if True the voice command is executed
        self.canHear = True
예제 #5
0
    def initialize(self, id, num_players, k, board, deck_type, my_hand, hands,
                   discard_pile, deck_size):
        """
        To be called once before the beginning.
        """
        self.id = id
        self.num_players = num_players
        self.k = k  # number of cards per hand
        self.board = board
        self.deck_type = deck_type

        # store a copy of the full deck
        self.full_deck = get_appearance(DECKS[deck_type]())
        self.full_deck_composition = Counter(self.full_deck)

        # hands
        self.my_hand = my_hand  # says in which positions there is actually a card
        self.hands = hands

        # discard pile
        self.discard_pile = discard_pile

        # deck size
        self.deck_size = deck_size

        # for each of my card, store its possibilities
        self.possibilities = [Counter(self.full_deck) for i in range(self.k)]

        # remove cards of other players from possibilities
        self.update_possibilities()

        # knowledge of all players
        self.knowledge = [[
            Knowledge(color=False, number=False) for j in range(k)
        ] for i in range(num_players)]

        # hints scheduler
        self.hints_scheduler = HintsScheduler(self)

        # action manager
        self.action_manager = ActionManager(self)
예제 #6
0
    def __init__(self, version, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.version = version
        self.modules = []
        self.viewers = {}
        self.menus = MenuManager(self)
        self.actions = ActionManager(self)
        self.createUI()
        self.createActions()
        self.createMenus()
        self.themes = ThemeManager(self)
        self.plugins = {}
        self.setContextMenuPolicy(QtCore.Qt.NoContextMenu)
        self.dockWidgets = []
        self.windowManager = WindowManager(self)

        self.statusBar().showMessage(
            self.tr("Gorgon: Protein Visualization Suite"))
        self.setWindowTitle(self.tr("Gorgon - v" + self.version))
        pathname = os.path.abspath(os.path.dirname(sys.argv[0]))
        self.setWindowIcon(QtGui.QIcon(pathname + '/gorgon.ico'))
예제 #7
0
 def __init__(self, dir):
     self.message_manager = self._create_message_manager(None)
     from action_manager import ActionManager
     self.action_manager = ActionManager(self.message_manager)
     self.tasks = []
     from TodoManager import TodoManager
     self.todo_manager = TodoManager()
     
     if dir:
         import os
         options_path = os.path.join(dir,"options.shelf")
         profile_path = os.path.join(dir,"profile.shelf")
         
         from shelve import open
         self.options = open(options_path)
         self.profile = open(profile_path)
         
         if not self.profile.has_key("name"):
             self.profile["name"] = "DefaultCarlos"
     else:
         self.options = {}
         self.profile = {"name":"DefaultCarlos"}
     
     self._dirty_add_actions()
예제 #8
0
def custom_objects(robot: cozmo.robot.Robot):

    # Gestionnaires d'évennements à chaque fois que Cozmo vois ou arrète de voir un objet
    robot.add_event_handler(cozmo.objects.EvtObjectAppeared,
                            handle_object_appeared)
    robot.add_event_handler(cozmo.objects.EvtObjectDisappeared,
                            handle_object_disappeared)

    # Création des custom objects
    objs = objects(robot)
    if None not in objs:
        print("All objects defined successfully!")
    else:
        print("One or more object definitions failed!")
        return

    robot.say_text("À la recherche des objet").wait_for_completed()
    setup_camera(robot)
    origin = robot.pose
    am = ActionManager(robot)
    stops = 1

    while len(stops_visited) < 6:

        # Chercer les objest
        lookaround = robot.start_behavior(
            cozmo.behavior.BehaviorTypes.LookAroundInPlace)
        objs = robot.world.wait_until_observe_num_objects(
            num=1, object_type=CustomObject, timeout=60)
        lookaround.stop()

        if objs[0].object_type in stops_visited:
            continue

        stops_visited.append(objs[0].object_type)

        robot.say_text("Objet trouvé").wait_for_completed()

        if len(objs) > 0:

            photo(robot)

            pose = custom_object_pose(robot, objs[0])
            robot.go_to_pose(pose,
                             relative_to_robot=False).wait_for_completed()

            photo(robot)

            robot.say_text(f"Arrête {stops}").wait_for_completed()
            am.launch(objs[0])

            print("origin: ", origin)
            robot.go_to_pose(origin,
                             relative_to_robot=False).wait_for_completed()
            stops += 1

        else:
            print("Cannot locate custom box")

    robot.play_anim_trigger(
        cozmo.anim.Triggers.SparkSuccess).wait_for_completed()

    while True:
        time.sleep(0.1)
예제 #9
0
class MainWindowForm(QtGui.QMainWindow):
    def __init__(self, version, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.version = version
        self.modules = []
        self.viewers = {}
        self.menus = MenuManager(self)
        self.actions = ActionManager(self)
        self.createUI()
        self.createActions()
        self.createMenus()
        self.themes = ThemeManager(self)
        self.plugins = {}
        self.setContextMenuPolicy(QtCore.Qt.NoContextMenu)
        self.dockWidgets = []
        self.windowManager = WindowManager(self)

        self.statusBar().showMessage(
            self.tr("Gorgon: Protein Visualization Suite"))
        self.setWindowTitle(self.tr("Gorgon - v" + self.version))
        pathname = os.path.abspath(os.path.dirname(sys.argv[0]))
        self.setWindowIcon(QtGui.QIcon(pathname + '/gorgon.ico'))

    def addModule(self, module):
        self.modules.append(module)

    def createUI(self):
        pass

    def createActions(self):
        exitAct = QtGui.QAction(self.tr("E&xit"), self)
        exitAct.setShortcut(self.tr("Ctrl+Q"))
        exitAct.setStatusTip(self.tr("Exit the application"))
        self.connect(exitAct, QtCore.SIGNAL("triggered()"),
                     self.exitApplication)
        self.actions.addAction("exit_Application", exitAct)

    def createMenus(self):
        self.menus.addMenu("file", self.tr("&File"))
        self.menus.addMenu("file-open", self.tr("&Open"), "file")
        self.menus.addMenu("file-save", self.tr("&Save"), "file")
        self.menus.addMenu("file-export", self.tr("&Export"), "file")
        self.menus.addMenu("file-close", self.tr("&Close"), "file")
        self.menus.getMenu("file").addSeparator()
        self.menus.addAction("file-exit",
                             self.actions.getAction("exit_Application"),
                             "file")
        #self.menus.addMenu("options", self.tr("&Options"))
        self.menus.addMenu("actions", self.tr("&Actions"))
        self.menus.addMenu("window", self.tr("&Window"))
        self.menus.addMenu("themes", self.tr("&Themes"))
        self.menus.addMenu("help", self.tr("&Help"))

    def addDockWidget(self, area, dockwidget):
        QtGui.QMainWindow.addDockWidget(self, area, dockwidget)
        dockwidget.area = area
        otherwidget = None
        for widget in self.dockWidgets:
            if (widget.area == area) and (widget != dockwidget):
                otherwidget = widget
        if (otherwidget):
            self.tabifyDockWidget(otherwidget, dockwidget)
        self.dockWidgets.append(dockwidget)
        self.connect(
            dockwidget,
            QtCore.SIGNAL("dockLocationChanged ( Qt::DockWidgetArea )"),
            self.dockLocationChanged(dockwidget))

    def removeDockWidget(self, dockwidget):
        QtGui.QMainWindow.removeDockWidget(self, dockwidget)
        if (dockwidget in self.dockWidgets):
            self.dockWidgets.remove(dockwidget)
            self.disconnect(
                dockwidget,
                QtCore.SIGNAL("dockLocationChanged ( Qt::DockWidgetArea )"),
                self.dockLocationChanged(dockwidget))

    def isDockWidget(self, dockWidget):
        isWidget = False
        for widget in self.dockWidgets:
            isWidget = isWidget or (widget == dockWidget)
        return isWidget

    def exitApplication(self):
        QtGui.qApp.closeAllWindows()

    def closeEvent(self, event):
        exitText = "This will close Gorgon, you will lose all unsaved data.\nAre you sure?"

    def dockLocationChanged(self, widget):
        def dockLocationChanged_widget(area):
            widget.area = area

        return dockLocationChanged_widget

    def keyPressEvent(self, event):
        self.emitKeyPressed(event)

    def keyReleaseEvent(self, event):
        self.emitKeyReleased(event)

    def emitKeyPressed(self, event):
        self.emit(QtCore.SIGNAL("keyPressed(QKeyEvent)"), event)

    def emitKeyReleased(self, event):
        self.emit(QtCore.SIGNAL("keyReleased(QKeyEvent)"), event)

    def loadPlugins(self):
        self.pluginManager = PluginManager(self)
예제 #10
0
    def __init__(self):
        parser_description = 'Syncronizes a folder with a Google Drive account'
        parser_epilog = 'Please notice that this software is still under development'
        main_parser = argparse.ArgumentParser(prog='jds',
                                              description=parser_description,
                                              epilog=parser_epilog,
                                              add_help=False)
        subparsers = main_parser.add_subparsers(title='Commands',
                                                dest='command',
                                                metavar='')

        # Basic ops
        download_parser = subparsers.add_parser('download',
                                                help=HELPS['download'][0],
                                                add_help=False)
        list_parser = subparsers.add_parser('list',
                                            help=HELPS['list'][0],
                                            add_help=False)
        mkdir_parser = subparsers.add_parser('mkdir',
                                             help=HELPS['mkdir'][0],
                                             add_help=False)
        move_parser = subparsers.add_parser('move',
                                            help=HELPS['move'][0],
                                            add_help=False)
        rename_parser = subparsers.add_parser('rename',
                                              help=HELPS['rename'][0],
                                              add_help=False)
        rm_parser = subparsers.add_parser('remove',
                                          help=HELPS['remove'][0],
                                          add_help=False)
        untrash_parser = subparsers.add_parser('untrash',
                                               help=HELPS['untrash'][0],
                                               add_help=False)

        # Sync ops
        start_parser = subparsers.add_parser('start',
                                             help=HELPS['start'][0],
                                             add_help=False)
        subparsers.add_parser('stop', help=HELPS['stop'][0])
        subparsers.add_parser('pause', help=HELPS['pause'][0])

        self.add_download_parser(download_parser)
        self.add_list_parsers(list_parser)
        self.add_move_parsers(move_parser)
        self.add_mkdir_parsers(mkdir_parser)
        self.add_rename_parsers(rename_parser)
        self.add_rm_parsers(rm_parser)
        self.add_untrash_parsers(untrash_parser)

        self.add_start_parsers(start_parser)

        self.add_options(main_parser)

        if len(sys.argv) == 1:
            print(main_parser.format_help())
            return

        args = main_parser.parse_args()
        # Just need drive session if performing any task with session
        if args.command is not None\
           or args.sync_cache\
           or args.sync_mirror:
            session = DriveSession(CREDENTIALS_FILE)
            print('Drive session started')
            root_file = session.get_service().files().get(
                fileId='root').execute()
            am = ActionManager(session.get_service(), root_file)
            sc = SyncController(session.get_service(), am, root_file)
        else:
            am = ActionManager(None, None)
            sc = SyncController(None, am, None)

        config_manager = ConfigManager()

        #Operations
        if args.command == 'download':
            for file1 in args.download_files:
                am.download(file1, destination=args.download_destination)
        elif args.command == 'list':
            if args.list_file == 'root':
                am.list_files('root', args.list_trash)
            else:
                for file1 in args.list_file:
                    if len(args.list_file) > 1:
                        print(file1, ':', sep='')
                    am.list_files(file1)
        elif args.command == 'mkdir':
            for file1 in args.mkdir_file:
                am.mkdir(file1)
        elif args.command == 'move':
            am.move(args.move_origin, args.move_destination[0])
        elif args.command == 'rename':
            am.rename(args.rename_file, args.rename_name[0])
        elif args.command == 'remove':
            for file1 in args.rm_files:
                am.rm(file1, args.force_remove, args.trash_remove)
        elif args.command == 'untrash':
            for file1 in args.untrash_files:
                am.untrash(file1)

        #Sync
        elif args.command == 'start':
            sc.start(args.start_target)
        elif args.command == 'stop':
            sc.stop()
        elif args.command == 'pause':
            sc.pause()

        #Options
        # -sc
        if args.show_cache:
            am.show_cache()
        # -cc
        if args.clear_cache:
            am.clear_cache()
        # -syc
        if args.sync_cache:
            am.sync_cache()
        # -sym
        if args.sync_mirror:
            sc.sync_mirror(filter_enabled=config_manager.get_filter_enabled())
        # -sm
        if args.show_mirror:
            sc.show_mirror()
        # -cm
        if args.clear_mirror:
            sc.clear_mirror()

        # filter settings

        # -b
        if args.add_blacklist is not None:
            if args.add_blacklist:
                config_manager.append_blacklist_files(args.add_blacklist)
                if not config_manager.get_blacklist_enabled():
                    config_manager.switch_blacklist_enabled()
            else:
                config_manager.switch_blacklist_enabled()
        # -w
        elif args.add_whitelist is not None:
            if args.add_whitelist:
                config_manager.append_whitelist_files(args.add_whitelist)
                if not config_manager.get_whitelist_enabled():
                    config_manager.switch_whitelist_enabled()
            else:
                config_manager.switch_whitelist_enabled()
        # -rb
        elif args.remove_blacklist is not None:
            config_manager.remove_from_blacklist(args.remove_blacklist)
        # -rw
        elif args.remove_whitelist is not None:
            config_manager.remove_from_whitelist(args.remove_whitelist)
        # -B
        elif args.set_blacklist is not None:
            config_manager.set_blacklist_files(args.set_blacklist)
            if not config_manager.get_blacklist_enabled():
                config_manager.switch_blacklist_enabled()
        # -W
        elif args.set_whitelist is not None:
            config_manager.set_whitelist_files(args.set_whitelist)
            if not config_manager.get_whitelist_enabled():
                config_manager.switch_whitelist_enabled()
        # -sf
        if args.show_filter:
            config_manager.show_filter_status()

        # -dc
        if args.download_cache:
            am.download_cache()

        # -dm
        if args.download_mirror:
            sc.download_mirror()
예제 #11
0
class Strategy(BaseStrategy):
    """
    An instance of this class represents a player's strategy.
    It only has the knowledge of that player, and it must make decisions.
    """

    DECK_SIZE_BEFORE_FULL_SEARCH = {
        4: 10,
        5: 4,
    }  # k (number of cards per hand): size of the deck when we want to consider all combinations of cards

    def __init__(self, verbose=False, params={}):
        self.COLORS_TO_NUMBERS = {
            color: i
            for (i, color) in enumerate(Card.COLORS)
        }
        self.verbose = verbose
        self.params = params

    def initialize(self, id, num_players, k, board, deck_type, my_hand, hands,
                   discard_pile, deck_size):
        """
        To be called once before the beginning.
        """
        self.id = id
        self.num_players = num_players
        self.k = k  # number of cards per hand
        self.board = board
        self.deck_type = deck_type

        # store a copy of the full deck
        self.full_deck = get_appearance(DECKS[deck_type]())
        self.full_deck_composition = Counter(self.full_deck)

        # hands
        self.my_hand = my_hand  # says in which positions there is actually a card
        self.hands = hands

        # discard pile
        self.discard_pile = discard_pile

        # deck size
        self.deck_size = deck_size

        # for each of my card, store its possibilities
        self.possibilities = [Counter(self.full_deck) for i in range(self.k)]

        # remove cards of other players from possibilities
        self.update_possibilities()

        # knowledge of all players
        self.knowledge = [[
            Knowledge(color=False, number=False) for j in range(k)
        ] for i in range(num_players)]

        # hints scheduler
        self.hints_scheduler = HintsScheduler(self)

        # action manager
        self.action_manager = ActionManager(self)

    def visible_cards(self):
        """
        Counter of all the cards visible by me.
        """
        res = Counter(self.discard_pile)
        for hand in self.hands.values():
            res += Counter(hand)

        return res

    def update_possibilities(self):
        """
        Update possibilities removing visible cards.
        """
        visible_cards = self.visible_cards()
        for p in self.possibilities:
            for card in self.full_deck_composition:
                if card in p:
                    # this card is still possible
                    # update the number of possible occurrences
                    p[card] = self.full_deck_composition[card] - visible_cards[
                        card]

                    if p[card] == 0:
                        # remove this card
                        del p[card]

        assert all(
            sum(p.values()) > 0 or self.my_hand[card_pos] is None
            for (card_pos, p) in enumerate(self.possibilities)
        )  # check to have at least one possible card!

    def update_possibilities_with_combinations(self):
        """
        Update possibilities examining all combinations of my hand.
        Better to do it with only few cards remaining!
        """
        possible_cards = Counter()
        for p in self.possibilities:
            assert all(x > 0 for x in list(p.values()))
            possible_cards |= p

        new_possibilities = [set() for card_pos in range(self.k)]

        num_cards = len([x for x in self.my_hand if x is not None])
        assert num_cards <= self.k

        # cycle over all combinations
        for comb in itertools.permutations(list(possible_cards.elements()),
                                           num_cards):
            # construct hand
            hand = copy.copy(self.my_hand)
            i = 0
            for card_pos in range(self.k):
                if hand[card_pos] is not None:
                    hand[card_pos] = comb[i]
                    i += 1

            # check if this hand is possible
            if all(card is None or self.possibilities[card_pos][card] > 0
                   for (card_pos, card) in enumerate(hand)):
                # this hand is possible
                # self.log("possible hand %r" % hand)

                for (card_pos, card) in enumerate(hand):
                    if card is not None:
                        new_possibilities[card_pos].add(card)

        self.log("old possibilities %r" % [len(p) for p in self.possibilities])
        self.log("new possibilities %r" % [len(p) for p in new_possibilities])

        # update possibilities
        for (card_pos, p) in enumerate(self.possibilities):
            self.possibilities[card_pos] = p & Counter(
                new_possibilities[card_pos])

        self.update_possibilities()  # set the right multiplicities

    def next_player_id(self):
        return (self.id + 1) % self.num_players

    def other_players_id(self):
        return [i for i in range(self.num_players) if i != self.id]

    def reset_knowledge(self, player_id, card_pos, new_card_exists):
        self.knowledge[player_id][card_pos] = Knowledge(False, False)

    def print_knowledge(self):
        print("Knowledge")
        for i in range(self.num_players):
            print("Player %d:" % i, end=' ')
            for card_pos in range(self.k):
                print(self.knowledge[i][card_pos], end=' ')
            print()
        print()

    def feed_turn(self, player_id, action):
        """
        Receive information about a played turn.
        """
        if action.type in [Action.PLAY, Action.DISCARD]:
            # reset knowledge of the player
            new_card = self.my_hand[
                action.
                card_pos] if player_id == self.id else self.hands[player_id][
                    action.card_pos]
            self.reset_knowledge(player_id, action.card_pos, new_card
                                 is not None)

            if player_id == self.id:
                # check for my new card
                self.possibilities[action.card_pos] = Counter(
                    self.full_deck) if self.my_hand[
                        action.card_pos] is not None else Counter()

        elif action.type == Action.HINT:
            # someone gave a hint!
            # the suitable hints manager must process it
            hints_manager = self.hints_scheduler.select_hints_manager(
                player_id, action.turn)
            hints_manager.receive_hint(player_id, action)

        # update possibilities with visible cards
        self.update_possibilities()

        # print knowledge
        if self.verbose and self.id == self.num_players - 1:
            self.print_knowledge()

    def get_best_discard(self):
        """
        Choose the best card to be discarded.
        """
        # first see if I can be sure to discard a useless card
        for (card_pos, p) in enumerate(self.possibilities):
            if len(p) > 0 and all(not card.useful(self.board, self.full_deck,
                                                  self.discard_pile)
                                  for card in p):
                self.log("considering to discard useless card")
                return card_pos, 0.0, 0.0

        # Try to avoid cards that are (on average) more relevant, then choose cards that are (on average) less useful
        tolerance = 1e-3
        best_cards_pos = []
        best_relevant_ratio = 1.0

        WEIGHT = {
            number: Card.NUM_NUMBERS + 1 - number
            for number in range(1, Card.NUM_NUMBERS + 1)
        }
        best_relevant_weight = max(WEIGHT.values())

        for (card_pos, p) in enumerate(self.possibilities):
            if len(p) > 0:
                num_relevant = sum(p[card] for card in p if card.relevant(
                    self.board, self.full_deck, self.discard_pile))
                relevant_weight_sum = sum(
                    WEIGHT[card.number] * p[card] for card in p
                    if card.relevant(self.board, self.full_deck,
                                     self.discard_pile))

                relevant_ratio = float(num_relevant) / sum(p.values())
                relevant_weight = float(relevant_weight_sum) / sum(p.values())

                num_useful = sum(p[card] for card in p if card.useful(
                    self.board, self.full_deck, self.discard_pile))
                useful_weight_sum = sum(
                    WEIGHT[card.number] * p[card] for card in p if card.useful(
                        self.board, self.full_deck, self.discard_pile))
                useful_ratio = float(num_useful) / sum(p.values())
                useful_weight = float(useful_weight_sum) / sum(p.values())

                if relevant_weight < best_relevant_weight - tolerance:
                    # better weight found
                    best_cards_pos, best_relevant_weight, = [], relevant_weight

                if relevant_weight < best_relevant_weight + tolerance:
                    # add this card to the possibilities
                    # self.log("new possibility for discard, pos %d, cards %r, useful weight %.3f" % (card_pos, p, useful_weight))
                    best_cards_pos.append((useful_weight, card_pos))

        assert len(best_cards_pos) > 0
        useful_weight, card_pos = sorted(best_cards_pos)[0]

        self.log(
            "considering to discard a card (pos %d, relevant weight ~%.3f, useful weight %.3f)"
            % (card_pos, best_relevant_weight, useful_weight))
        return card_pos, relevant_weight, useful_weight

    def get_best_play(self):
        """
        Choose the best card to play.
        """
        # prefer playing cards that allow a higher number of playable cards;
        # in case of tie, prefer (in this order):
        # NUM_NUMBERS, 1, 2, 3, ..., NUM_NUMBERS-1 (weights are given accordingly)

        WEIGHT = {
            number: Card.NUM_NUMBERS - number
            for number in range(1, Card.NUM_NUMBERS)
        }
        WEIGHT[Card.NUM_NUMBERS] = Card.NUM_NUMBERS

        tolerance = 1e-3
        best_card_pos = None
        best_avg_num_playable = -1.0  # average number of other playable cards, after my play
        best_avg_weight = 0.0  # average weight (in the sense above)
        for (card_pos, p) in enumerate(self.possibilities):
            if all(card.playable(self.board) for card in p) and len(p) > 0:
                # the card in this position is surely playable!
                # how many cards of the other players become playable, on average?
                num_playable = []
                for card in p:
                    fake_board = copy.copy(self.board)
                    fake_board[card.color] += 1
                    for i in range(p[card]):
                        num_playable.append(
                            sum(1 for (player_id, hand) in self.hands.items()
                                for c in hand
                                if c is not None and c.playable(fake_board)))

                avg_num_playable = float(sum(num_playable)) / len(num_playable)

                avg_weight = float(
                    sum(WEIGHT[card.number] * p[card]
                        for card in p)) / sum(p.values())

                if avg_num_playable > best_avg_num_playable + tolerance or avg_num_playable > best_avg_num_playable - tolerance and avg_weight > best_avg_weight:
                    self.log("update card to be played, pos %d, score %f, %f" %
                             (card_pos, avg_num_playable, avg_weight))
                    best_card_pos, best_avg_num_playable, best_avg_weight = card_pos, avg_num_playable, avg_weight

        if best_card_pos is not None:
            self.log(
                "playing card in position %d gives %f playable cards on average and weight %f"
                % (best_card_pos, best_avg_num_playable, best_avg_weight))
        return best_card_pos

    def get_best_play_last_round(self):
        """
        Choose the best card to play in the last round of the game.
        The players know almost everything, and it is reasonable to examine all the possibilities.
        """
        best_card_pos = None
        best_avg_score = 0.0

        for (card_pos, p) in enumerate(self.possibilities):
            if any(card.playable(self.board) for card in p):
                # at least a card (among the possible ones in this position) is playable

                obtained_scores = Counter()

                for card in p:
                    # simulate what happens if I play this card
                    best_score = 0
                    for comb in itertools.product(list(range(self.k)),
                                                  repeat=self.last_turn -
                                                  self.turn):
                        turn = self.turn
                        board = copy.copy(self.board)
                        player_id = self.id
                        lives = self.lives

                        if card.playable(board):
                            board[card.color] += 1
                        else:
                            lives -= 1

                        if lives >= 1:
                            # simulate other players
                            for (i, c_pos) in enumerate(comb):
                                turn += 1
                                player_id = (player_id + 1) % self.num_players

                                # this player plays the card in position c_pos
                                c = self.hands[player_id][c_pos]
                                if c.playable(board):
                                    board[c.color] += 1

                        score = sum(board.values())
                        best_score = max(
                            score, best_score
                        )  # assume that the other players play optimally! :)

                    # self.log("simulation for card %r in position %d gives best score %d" % (card, card_pos, best_score))
                    # self.log("obtained possible score %d (multiplicity %d)" % (best_score, p[card]))
                    obtained_scores[best_score] += p[card]

                avg_score = float(sum(obtained_scores.elements())) / sum(
                    obtained_scores.values())
                self.log(
                    "playing card in position %d gives an average score of %.3f"
                    % (card_pos, avg_score))

                if avg_score > best_avg_score:
                    best_card_pos, best_avg_score = card_pos, avg_score

        if best_card_pos is not None:
            self.log("playing card in position %d is the best choice" %
                     best_card_pos)
            return best_card_pos

    def get_turn_action(self):
        """
        Choose action for this turn.
        """
        # update possibilities checking all combinations
        if self.deck_size < self.DECK_SIZE_BEFORE_FULL_SEARCH[self.k]:
            self.update_possibilities_with_combinations()

        # use neural network to determine action
        action, card_pos = self.action_manager.select_action()
        self.log("chosen action is %r, %r" % (action, card_pos))

        if action == ActionManager.PLAY and card_pos is not None:
            """
            if self.last_turn is not None:
                card_pos = self.get_best_play_last_round()
            else:
                card_pos = self.get_best_play()
            """
            # play the card
            return PlayAction(card_pos=card_pos)

        if action == ActionManager.HINT and self.hints > 0:
            hints_manager = self.hints_scheduler.select_hints_manager(
                self.id, self.turn)
            hint_action = hints_manager.get_hint()

            if hint_action is not None:
                return hint_action

        if action == ActionManager.DISCARD and card_pos is not None:
            return DiscardAction(card_pos=card_pos)

        # discard card
        return DiscardAction(card_pos=self.get_best_discard()[0])

        ### backup plan follows (if failed to to the chosen action) ###

        # if this is the last round, play accordingly
        if self.last_turn is not None:
            card_pos = self.get_best_play_last_round()
            if card_pos is not None:
                # play the card
                return PlayAction(card_pos=card_pos)

        else:
            # check for playable cards in my hand
            card_pos = self.get_best_play()
            if card_pos is not None:
                # play the card
                return PlayAction(card_pos=card_pos)

        # discard card
        return DiscardAction(card_pos=self.get_best_discard()[0])

        if self.hints == 0:
            # discard card
            return DiscardAction(card_pos=self.get_best_discard()[0])

        if self.hints <= 1 and self.deck_size >= 2:
            # better to discard if the next player has many important cards
            self.log("there is only one hint, should I discard?")
            card_pos, relevant_weight, useful_weight = self.get_best_discard()
            tolerance = 1e-3

            # TODO: se il giocatore successivo ha almeno una carta giocabile di cui è a conoscenza,
            # controllare quello dopo ancora (e così via)

            if useful_weight < tolerance:
                # discard is surely good
                return DiscardAction(card_pos=card_pos)

            elif all(
                    card.relevant(self.board, self.full_deck,
                                  self.discard_pile)
                    for card in self.hands[self.next_player_id()]):
                if relevant_weight < 0.5 + tolerance:
                    # close your eyes and discard
                    self.log(
                        "next player has only relevant cards, so I discard")
                    return DiscardAction(card_pos=card_pos)

            elif all(
                    card.useful(self.board, self.full_deck, self.discard_pile)
                    for card in self.hands[self.next_player_id()]):
                if relevant_weight < tolerance and useful_weight < 1.0 + tolerance:
                    # discard anyway
                    self.log("next player has only useful cards, so I discard")
                    return DiscardAction(card_pos=card_pos)

        # try to give hint, using the right hints manager
        hints_manager = self.hints_scheduler.select_hints_manager(
            self.id, self.turn)
        assert hints_manager.is_usable(self.id)
        hint_action = hints_manager.get_hint()

        if hint_action is not None:
            return hint_action
        else:
            # failed to give indirect hint
            # discard card
            self.log("failed to give a hint")
            return DiscardAction(card_pos=self.get_best_discard()[0])
예제 #12
0
class MainClass:

    def __init__(self, dir):
        self.message_manager = self._create_message_manager(None)
        from action_manager import ActionManager
        self.action_manager = ActionManager(self.message_manager)
        self.tasks = []
        from TodoManager import TodoManager
        self.todo_manager = TodoManager()
        
        if dir:
            import os
            options_path = os.path.join(dir,"options.shelf")
            profile_path = os.path.join(dir,"profile.shelf")
            
            from shelve import open
            self.options = open(options_path)
            self.profile = open(profile_path)
            
            if not self.profile.has_key("name"):
                self.profile["name"] = "DefaultCarlos"
        else:
            self.options = {}
            self.profile = {"name":"DefaultCarlos"}
        
        self._dirty_add_actions()
    
    def get_new_messages (self):
        return self.message_manager.get_new_messages()
    
    def get_all_messages (self, n = None):
        return self.message_manager.get_all_messages(n)
        
    def execute_command(self, cmd):
        from UserMessage import UserMessage
        self.message_manager.add(UserMessage(cmd))
        return self.action_manager.execute(cmd.lower())
        
    def _add_task(self, *args):
        t = datetime.now() + timedelta(seconds = 5)
        from SystemMessage import SystemMessage
        m = SystemMessage(self.profile["name"] + ", no te duermas.")
        task = {'time':t,'message':m}
        self.tasks.append(task)
        self.message_manager.add(SystemMessage("Ok, te aviso en 5s"))
        
    def update(self):
        torem = []
        for task in self.tasks:
            if datetime.now() > task["time"]:
                self.message_manager.add(task["message"])
                torem.append(task)
                
        for task in torem:
            self.tasks.remove(task)

    def _set_name_to_carlos(self, *args):
        self.profile_set("name","Carlos")
        from SystemMessage import SystemMessage
        self.message_manager.add(SystemMessage("Ok, ahora te llamas Carlos."))
    
    def _say_hi(self, *args):
        from SystemMessage import SystemMessage
        self.message_manager.add(SystemMessage("Hola, " + self.profile["name"]))
    
    def _dirty_add_actions(self):
        from GetTimeAction import GetTimeAction
        from StringAction import StringAction
        from ReminderAction import ReminderAction
        act = GetTimeAction(self)
        self.action_manager.add(act)
        act = ReminderAction(self)
        self.action_manager.add(act)
        act = StringAction(self._add_task,"Recordame","Recordarme","Recuerdame")
        self.action_manager.add(act)
        act = StringAction(self._set_name_to_carlos,"Dime Carlos")
        self.action_manager.add(act)
        act = StringAction(self._say_hi,"Hola")
        self.action_manager.add(act)
        from SetTaskAction import SetTaskAction
        self.action_manager.add(SetTaskAction(self))
        from GetTaskAction import GetTaskAction
        self.action_manager.add(GetTaskAction(self))
        from SetNameAction import SetNameAction
        self.action_manager.add(SetNameAction(self))


    def profile_set(self,key,value):
        self.profile[key] = value
        self.profile.sync()
    
    def profile_get(self,key):
        return self.profile[key]
    
    def options_set(self,key,value):
        self.options[key] = value
        self.options.sync()
        
    def options_get(self,key):
        return self.options[key]
    
    def _create_message_manager(self,dir):
        if dir:
            from MessageManagerWShelf import MessageManagerWShelf
            return MessageManagerWShelf(dir)
        from MessageManager import MessageManager
        print "Mensajes sin persistencia"
        return MessageManager()
예제 #13
0
 def __init__(self):
     self.contexts = {}
     self.previous_contexts = {}
     self.switching_contexts = Lock()
     self.am = ActionManager(self)
예제 #14
0
class ContextManager(object):

    current_context = None
    exclusive_context = None
    fallback_context = "main"
    initial_contexts = ["main"]
    start_context = "main"
    allowed_exclusive_contexts = ["apps.lockscreen", "apps.firstboot_wizard"]

    def __init__(self):
        self.contexts = {}
        self.previous_contexts = {}
        self.switching_contexts = Lock()
        self.am = ActionManager(self)

    def init_io(self, input_processor, screen):
        """
        Saves references to hardware IO objects and creates initial contexts.
        """
        self.input_processor = input_processor
        self.screen = screen
        self.create_initial_contexts()

    def create_initial_contexts(self):
        """
        Creates contexts specified in ``self.initial_contexts`` - since
        targets aren't set, marks them as non-threaded.
        """
        for context_alias in self.initial_contexts:
            c = self.create_context(context_alias)
            c.threaded = False

    def switch_to_start_context(self):
        """
        Switches to the defined start context - usually "main",
        but could also be some other context defined by someone
        integrating ZPUI into their workflow.
        """
        self.unsafe_switch_to_context(self.start_context, do_raise=False)

    def get_context_names(self):
        """
        Gets names of all contexts available.
        """
        return self.contexts.keys()

    def get_current_context(self):
        """
        Returns the alias (name) of the current context.
        """
        return self.current_context

    def register_context_target(self, context_alias, target):
        """
        A context manager-side function that sets the target for a context.
        """
        logger.debug("Registering a thread target for the {} context".format(
            context_alias))
        self.contexts[context_alias].set_target(target)

    def set_menu_name(self, context_alias, menu_name):
        """
        A context manager-side function that associates a menu name with a context.
        """
        self.contexts[context_alias].menu_name = menu_name

    def switch_to_context(self, context_alias, start_thread=True):
        """
        Lets you switch to another context by its alias.
        """
        # Saving the current context alias in the "previous context" storage
        if context_alias != self.current_context:
            self.previous_contexts[context_alias] = self.current_context
            with self.switching_contexts:
                try:
                    self.unsafe_switch_to_context(context_alias,
                                                  start_thread=start_thread)
                except ContextError:
                    logger.exception("A ContextError was caught")
                    self.previous_contexts.pop(context_alias)
                    return False
                else:
                    return True

    def unsafe_switch_to_context(self,
                                 context_alias,
                                 do_raise=True,
                                 start_thread=True):
        """
        This is a non-thread-safe context switch function. Not to be used directly
        - is only for internal usage. In case an exception is raised, sets things as they
        were before and re-raises the exception.
        """
        logger.info("Switching to {} context".format(context_alias))
        previous_context = self.current_context
        self.current_context = context_alias
        # First, activating IO - if it fails, restoring the previous context's IO
        try:
            self.activate_context_io(context_alias)
        except:
            logger.exception(
                "Switching to the {} context failed - couldn't activate IO!".
                format(context_alias))
            try:
                self.activate_context_io(previous_context)
            except:
                logger.exception(
                    "Also couldn't activate IO for the previous context: {}!".
                    format(previous_context))
                self.failsafe_switch_to_fallback_context()
                if do_raise:
                    raise
            self.current_context = previous_context
            # Passing the exception back to the caller
            if do_raise:
                raise
        # Activating the context - restoring everything if it fails
        try:
            self.contexts[context_alias].activate(start_thread=start_thread)
        except:
            logger.exception(
                "Switching to the {} context failed - couldn't activate the context!"
                .format(context_alias))
            # Activating IO of the previous context
            try:
                self.activate_context_io(previous_context)
            except:
                logger.exception(
                    "Also couldn't activate IO for the previous context: {}!".
                    format(previous_context))
                self.failsafe_switch_to_fallback_context()
                if do_raise:
                    raise
            # Activating the previous context itself
            try:
                self.contexts[previous_context].activate()
            except:
                logger.exception(
                    "Also couldn't activate context for the previous context: {}!"
                    .format(previous_context))
                self.failsafe_switch_to_fallback_context()
                if do_raise:
                    raise
            self.current_context = previous_context
            # Passing the exception back to the caller
            if do_raise:
                raise
        else:
            logger.debug("Switched to {} context!".format(context_alias))

    def failsafe_switch_to_fallback_context(self):
        """
        Last resort function for the ``unsafe_switch_to_context`` to use
        when both switching to the context and failsafe switching fails.
        """
        logger.warning(
            "Some contexts broke, switching to fallback context: {}".format(
                self.fallback_context))
        self.current_context = self.fallback_context
        # In case something f****d up in the previous context dictionary, fixing that
        # More like - working around, preventing the user from making more mistakes
        self.previous_contexts[self.fallback_context] = self.fallback_context
        self.activate_context_io(self.current_context)
        self.contexts[self.current_context].activate()
        logger.info("Fallback switched to {} - proceed with caution".format(
            self.current_context))

    def activate_context_io(self, context_alias):
        """
        This method activates input and output objects associated with a context.
        """
        logger.debug("Activating IO for {} context".format(context_alias))
        proxy_i, proxy_o = self.contexts[context_alias].get_io()
        if not isinstance(proxy_i, InputProxy) or not isinstance(
                proxy_o, OutputProxy):
            raise ContextError(
                "Non-proxy IO objects for the context {}".format(
                    context_alias))
        self.input_processor.attach_new_proxy(proxy_i)
        self.screen.attach_new_proxy(proxy_o)

    def create_context(self, context_alias):
        """
        Creates a context object (with IO) and saves it internally
        (by the given context alias).
        """
        logger.debug("Creating {} context".format(context_alias))
        context = Context(context_alias, self.signal_event)
        context.set_io(*self.create_io_for_context(context_alias))
        self.contexts[context_alias] = context
        return context

    def create_io_for_context(self, context_alias):
        """
        Creates IO objects for the context, registers them and returns them.
        """
        proxy_i = InputProxy(context_alias)
        proxy_o = OutputProxy(context_alias)
        self.input_processor.register_proxy(proxy_i)
        self.screen.init_proxy(proxy_o)
        self.set_default_callbacks_on_proxy(context_alias, proxy_i)
        return proxy_i, proxy_o

    def set_default_callbacks_on_proxy(self, context_alias, proxy_i):
        """
        Sets some default callbacks on the input proxy. For now, the only
        callback is the KEY_LEFT maskable callback exiting the app -
        in case the app is hanging for some reason.
        """
        flc = lambda x=context_alias: self.failsafe_left_handler(x)
        proxy_i.maskable_keymap["KEY_LEFT"] = flc

    def get_io_for_context(self, context_alias):
        """
        Returns the IO objects for the context.
        """
        return self.contexts[context_alias].get_io()

    def get_previous_context(self, context_alias, pop=False):
        """
        Returns name of the previous context for a given context. If ``pop``
        is set to True, also removes the name from the internal dictionary.
        """
        # WORKAROUND, future self - TODO please reconsider
        # (after you move between different contexts a lot and trigger something,
        # say, use ZeroMenu to switch to main context,
        # pressing LEFT in main context can move you to another context,
        # probably because of context switcing mechanics and previous context stuff.
        if context_alias == self.fallback_context:
            return context_alias
        if pop:
            prev_context = self.previous_contexts.pop(context_alias,
                                                      self.fallback_context)
        else:
            prev_context = self.previous_contexts.get(context_alias,
                                                      self.fallback_context)
        # If previous context is, by some chance, the same, let's fall back
        if prev_context == context_alias:
            prev_context = self.fallback_context
        return prev_context

    def failsafe_left_handler(self, context_alias):
        """
        This function is set up as the default maskable callback for new contexts,
        so that users can exit on LEFT press if the context is waiting.
        """
        previous_context = self.get_previous_context(context_alias)
        if not previous_context:
            previous_context = self.fallback_context
        self.switch_to_context(previous_context)

    def signal_event(self, context_alias, event, *args, **kwargs):
        """
        A callback for context objects to use to signal/receive events -
        providing an interface for apps to interact with the context manager.
        This function will, at some point in the future, be working through
        RPC.
        """
        if event == "finished" or event == "background":
            # For now, those two events are handled the same - later on,
            # there will be differences.
            with self.switching_contexts:
                #Locking to avoid a check-then-do race condition
                if self.current_context == context_alias:
                    #Current context is the active one, switching to the previous context
                    next_context = self.get_previous_context(context_alias,
                                                             pop=True)
                    logger.debug("Next context: {}".format(next_context))
                    try:
                        self.unsafe_switch_to_context(next_context)
                    except ContextError:
                        logger.exception("A ContextError was caught")
                        self.previous_contexts[context_alias] = next_context
                        return False
                    return True
                else:
                    return False
        elif event == "get_previous_context_image":
            # This is a special-case function for screenshots. I'm wondering
            # if there's a better way to express this.
            previous_context = self.get_previous_context(self.current_context)
            return self.contexts[previous_context].get_io(
            )[1].get_current_image()
        elif event == "get_context_image":
            # This is a special-case function for lockscreens. I'm wondering
            # if there's a better way to express this.
            context = args[0]
            return self.contexts[context].get_io()[1].get_current_image()
        elif event == "is_active":
            return context_alias == self.current_context
        elif event == "register_action":
            action = args[0]
            action.full_name = "{}-{}".format(context_alias, action.name)
            action.context = context_alias
            if isinstance(
                    action,
                    ContextSwitchAction) and action.target_context is None:
                action.target_context = context_alias
            self.am.register_action(action)
        elif event == "register_firstboot_action":
            action = args[0]
            self.am.register_firstboot_action(action, context_alias)
        elif event == "request_exclusive":
            if self.exclusive_context and self.exclusive_context != context_alias:
                logger.warning(
                    "Context {} requested exclusive switch but {} already got it"
                    .format(context_alias, self.exclusive_context))
                return False
            if context_alias in self.allowed_exclusive_contexts:
                logger.warning(
                    "Context {} requested exclusive switch, allowing".format(
                        context_alias))
                self.exclusive_context = context_alias
                self.switch_to_context(context_alias)
                return True
            else:
                logger.warning(
                    "Context {} requested exclusive switch - not allowed!".
                    format(context_alias))
                return False
        elif event == "rescind_exclusive":
            if self.exclusive_context == context_alias:
                self.exclusive_context = None
                return True
            else:
                return False
        elif event == "exclusive_status":
            return True if self.exclusive_context else False
        elif event == "get_actions":
            return self.am.get_actions()
        elif event == "list_contexts":
            logger.info(
                "Context list requested by {} app".format(context_alias))
            c_list = []
            for name in self.contexts:
                c = {}
                context = self.contexts[name]
                c["name"] = name
                c["menu_name"] = context.menu_name
                c["previous_context"] = self.get_previous_context(name)
                if not context.is_threaded():
                    c["state"] = "non-threaded"
                else:
                    c["state"] = "running" if context.thread_is_active(
                    ) else "inactive"
                c_list.append(c)
            return c_list
        elif event == "request_switch":
            # As usecases appear, we will likely want to do some checks here
            logger.info(
                "Context switch requested by {} app".format(context_alias))
            if self.exclusive_context:
                # If exclusive context is active, only an app that has it
                # can initiate a switch.
                if context_alias != self.exclusive_context:
                    return False
            return self.switch_to_context(context_alias,
                                          start_thread=kwargs.get(
                                              "start_thread", True))
        elif event == "request_switch_to":
            # If app is not the one active, should we honor its request?
            # probably not, but we might want to do something about it
            # to be considered
            if self.exclusive_context:
                # If exclusive context is active, only an app that has it
                # can initiate a switch to other context
                if context_alias != self.exclusive_context:
                    return False
            new_context = args[0]
            logger.info("Context switch to {} requested by {} app".format(
                new_context, context_alias))
            return self.switch_to_context(new_context,
                                          start_thread=kwargs.get(
                                              "start_thread", True))
        elif event == "request_context_start":
            context_alias = args[0]
            return self.contexts[context_alias].activate()
        elif event == "request_global_keymap":
            results = {}
            keymap = args[0]
            for key, cb in keymap.items():
                try:
                    self.input_processor.set_global_callback(key, cb)
                except Exception as e:
                    logger.warning(
                        "Context {} couldn't set a global callback on {} (function: {})"
                        .format(context_alias, key, cb.__name__))
                    results[key] = e
                else:
                    logger.warning(
                        "Context {} set a global callback on {} (function: {})"
                        .format(context_alias, key, cb.__name__))
                    results[key] = True
            return results
        else:
            logger.warning("Unknown event: {}!".format(event))
예제 #15
0
 def __init__(self):
     self.db = database.DataBase()
     self.action_manager = ActionManager()