Exemplo n.º 1
0
    def __init__(self, schid, cid, password, rootdir):
        """
        Instantiates a new object.
        @param schid: the id of the serverconnection handler
        @type schid: int
        @param cid: the id of the channel
        @type cid: int
        @param password: the password of the channel
        @type password: str
        @param rootdir: the root download directory
        @type rootdir: str
        """
        super().__init__()

        self.schid = schid
        self.cid = cid
        self.password = password
        self.rootdir = rootdir

        self.collectionFinished = Signal()
        self.collectionError = Signal()

        self.queue = {}
        self.files = {}

        PluginHost.registerCallbackProxy(self)
Exemplo n.º 2
0
    def __init__(self, schid, cid, password, parent=None, *, readonly=False):
        super(QAbstractItemModel, self).__init__(parent)

        self.schid = schid
        self.cid = cid
        self.password = password

        self.readonly = readonly

        self.pathChanged = Signal()
        self.error = Signal()

        self._path = None
        self.newpath = None
        self.files = []
        self.newfiles = []

        self.retcode = None
        self.renretcode = None
        self.renfile = ()

        self.titles = [
            self._tr("Name"),
            self._tr("Size"),
            self._tr("Type"),
            self._tr("Last Changed")
        ]

        PluginHost.registerCallbackProxy(self)
Exemplo n.º 3
0
    def setup_method(self, method):
        self.signal_a = Signal(threadsafe=True)
        self.signal_b = Signal(args=['foo'])

        self.slot_a = mock.Mock(spec=lambda **kwargs: None)
        self.slot_a.return_value = None
        self.slot_b = mock.Mock(spec=lambda **kwargs: None)
        self.slot_b.return_value = None
Exemplo n.º 4
0
 def __init__(self, num, height):
     """
     height = ft
     """
     self.__num = num
     self.__height = height
     self.__people = [] # people currently on the floor (not necessarily waiting for elevators)
     self.__queue = [] # people requested the elevator and currently waiting for one
     self.__signal_elevator_requested = Signal(args=['from_floor', 'to_floor'])
     self.__signal_people_boarded = Signal(args=['elevator_id', 'floor_num', 'people'])
Exemplo n.º 5
0
    def __init__(self, floors=[], elevators=[]):
        self.__floors = floors

        # absolute coords
        self.__floor_coords = [0] * len(self.__floors)
        for i in range(1, len(self.__floor_coords)):
            self.__floor_coords[i] += self.__floor_coords[i-1] + self.__floors[i-1].height

        self.__elevators = {e.id : e for e in elevators}
        # indicates a command to an elevator to change velocity
        self.__signal_change_velocity = Signal(args=['elevator_id', 'velocity'])
        self.__signal_stop = Signal(args=['elevator_id'])
Exemplo n.º 6
0
class zmqReceiverLoggerThread(threading.Thread):

    data_received = Signal(args=[], threadsafe=True)

    def __init__(self, port=5556):
        super(zmqReceiverLoggerThread, self).__init__()
        self.context = zmq.Context()
        self.socket = self.context.socket(zmq.PULL)
        self.port = port
        self.interrupt = False

    def run(self):
        self.socket.bind("tcp://*:%s" % (self.port))

        while True:
            try:
                data = self.socket.recv_pyobj()
                if len(data) > 0:
                    print data
                    self.data_received.emit(args=data)
            except (KeyboardInterrupt, SystemExit):
                self.socket.close()
                self.context.term()
            else:
                pass
Exemplo n.º 7
0
    def setup_method(self, method):
        self.signal = Signal(threadsafe=False)
        self.seen_exception = False

        def failing_slot(**args):
            raise MyTestError('die!')

        self.signal.connect(failing_slot)
Exemplo n.º 8
0
    def __init__(self, x, y, width, height, text='Button', text_size=25):
        self.button_down = False
        self.clicked = Signal()

        super().__init__(x, y, width, height, text=text, text_size=text_size)
        self.hold_function = self.hold
        self.release_function = self.release

        self.redraw()
Exemplo n.º 9
0
    def setup_method(self, method):
        class MyObject(object):
            def __init__(self):
                self.called = False

            def slot(self, **kwargs):
                self.called = True

        self.obj_ref = MyObject()
        self.slot = Slot(self.obj_ref.slot, weak=True)
        self.signal = Signal()
        self.signal.connect(self.slot)
Exemplo n.º 10
0
 def __init__(self, id, size=10, height=10):
     """
     people - list of people currently in the elevator
     size - elevator capacity in terms of people count
     velocity - velocity along y axis
     position - current y coordinate
     door_opening_time - time taken to open doors in seconds
     door_closing_time - time taken to close doors in seconds
     """
     self.__id = id
     self.__people = []
     self.__signal_person_inside = Signal(args=['person'])
     self.__signal_position_change = Signal(args=['elevator_id', 'x', 'y'])
     # direction: True = up, Down = False
     self.__signal_door_opened = Signal(args=['elevator_id', 'direction', 'people_inside', 'available_capacity', 'floor_num'])
     self.__signal_door_closed = Signal(args=['elevator_id', 'people_inside'])
     self.__size = size
     self.__velocity = 0
     self.__position = (0, 0)
     self.__height = height
     self.__door_opening_time = 1.5
     self.__door_closing_time = 2.5
Exemplo n.º 11
0
    def __init__(self, x, y, width, height, texts, text_size=25):
        super().__init__(x, y, width, height)
        self.list_selected = Signal(args=['text'])

        self.font = pygame.font.SysFont("None", text_size)
        self.texts = texts
        self.text_rects = []
        self.y_offset = 0
        self.selected = -1
        self.outline_thickness = 3
        self.selected_colour = (255, 0, 0)
        self.max_offset = 0

        self.replace_list(texts)
        self.release_function = self.check_click_pos
Exemplo n.º 12
0
    def test_semaphore(self, inspect):
        slot = mock.Mock()
        slot.side_effect = lambda **k: time.sleep(.3)

        signal = Signal('tost')
        signal.connect(slot)

        x = Task.get_or_create(signal, dict(some_kwarg='foo'))
        y = Task.get_or_create(signal, dict(some_kwarg='foo'))

        eventlet.spawn(x)
        time.sleep(.1)
        eventlet.spawn(y)
        time.sleep(.1)

        assert slot.call_count == 1
        time.sleep(.4)
        assert slot.call_count == 2
Exemplo n.º 13
0
    def __init__(self, result_copy=True, result_deepcopy=True):
        """
        Initialisation.  This should be overridden by subclasses to accept and
        validate the inputs presented for the operation, raising an appropriate
        Exception subclass if the inputs are found to be invalid.

        These should be stored here by the initialisation function as private
        variables in suitably sanitised form.  The core state machine object
        shall then be created and stored before the object is returned to the
        caller.
        """
        # Event object to represent when this operation is "done"
        self._done_evt = Event()

        # Signal emitted when the operation is "done"
        self.done_sig = Signal(name="done", threadsafe=True)

        # Result returned by operation
        self._result = None
        self._result_copy = result_copy
        self._result_deepcopy = result_deepcopy
Exemplo n.º 14
0
    def __init__(self, x, y, width, height):
        self.draw_update = Signal()

        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.rect = pygame.rect.Rect(x, y, width, height)
        self.visible = True
        self.clear_colour = (0, 0, 0)
        self.outline_colour = (255, 0, 0)
        self.outline_thickness = 3
        self.text_colour = (255, 255, 255)

        self.background = pygame.Surface((self.width, self.height))
        self.background.fill(self.clear_colour)
        self.background.set_colorkey(self.clear_colour)
        self.background = self.background.convert()

        self.hold_function = None
        self.release_function = None

        self.parent = None
        self.children = None
Exemplo n.º 15
0
 def __init__(self):
     self._loop = DummyLoop()
     self.bind_calls = []
     self.transmitted = []
     self.received_msg = Signal()
Exemplo n.º 16
0
    def __init__(self,
                 schid,
                 cid,
                 password='',
                 path='/',
                 parent=None,
                 *,
                 staticpath=False,
                 readonly=False,
                 downloaddir=None,
                 iconpack=None):
        """
        Instantiates a new object.
        @param schid: the id of the serverconnection handler
        @type schid: int
        @param cid: the id of the channel
        @type cid: int
        @param password: password to the channel, defaults to an empty string
        @type password: str
        @param path: path to display, defaults to the root path
        @type path: str
        @param parent: parent of the dialog; optional keyword arg;
        defaults to None
        @type parent: QWidget
        @param staticpath: if set to True, the initial path can't be
        changed by the user; optional keyword arg; defaults to False
        @type staticpath: bool
        @param readonly: if set to True, the user can't download, upload
        or delete files, or create new directories; optional keyword arg;
        defaults to False
        @type readonly: bool
        @param downloaddir: directory to download files to; optional keyword
        arg; defaults to None; if set to None, the TS3 client's download
        directory is used
        @type downloaddir: str
        @param iconpack: iconpack to load icons from; optional keyword arg;
        defaults to None; if set to None, the current iconpack is used
        @type iconpack: ts3client.IconPack
        """
        super(QDialog, self).__init__(parent)
        self.setAttribute(Qt.WA_DeleteOnClose)

        iconpackopened = False
        if not iconpack:
            try:
                iconpack = ts3client.IconPack.current()
                iconpack.open()
                iconpackopened = True
            except Exception as e:
                self.delete()
                raise e

        try:
            setupUi(self,
                    pytson.getPluginPath("ressources", "filebrowser.ui"),
                    iconpack=iconpack)

            self.statusbar = SmartStatusBar(self)
            self.layout().addWidget(self.statusbar)
            self.statusbar.hide()
        except Exception as e:
            self.delete()
            raise e

        err, cname = ts3lib.getChannelVariableAsString(
            schid, cid, ChannelProperties.CHANNEL_NAME)

        if err == ERROR_ok:
            self.setWindowTitle(
                self._tr("File Browser - {cname}").format(cname=cname))
        else:
            self.setWindowTitle(self._tr("File Browser"))

        self.schid = schid
        self.cid = cid
        self.password = password
        self.path = None

        self.staticpath = staticpath
        self.readonly = readonly

        self.createretcode = None
        self.delretcode = None

        if not self.readonly and not downloaddir:
            cfg = ts3client.Config()
            q = cfg.query("SELECT value FROM filetransfer "
                          "WHERE key='DownloadDir'")
            del cfg

            if q.next():
                self.downloaddir = q.value("value")
            else:
                self.delete()
                raise Exception("Error getting DownloadDir from config")
        else:
            self.downloaddir = downloaddir

        if not self.readonly:
            menu = self.menu = QMenu(self)

            self.openAction = menu.addAction(QIcon(iconpack.icon("FILE_UP")),
                                             self._tr("Open"))
            self.openAction.connect("triggered()",
                                    self.on_openAction_triggered)

            self.downAction = menu.addAction(QIcon(iconpack.icon("DOWN")),
                                             self._tr("Download"))
            self.downAction.connect("triggered()", self.downloadFiles)
            self.renameAction = menu.addAction(QIcon(iconpack.icon("EDIT")),
                                               self._tr("Rename"))
            self.renameAction.connect("triggered()",
                                      self.on_renameAction_triggered)
            self.copyAction = menu.addAction(QIcon(iconpack.icon("COPY")),
                                             self._tr("Copy URL"))
            self.copyAction.connect("triggered()",
                                    self.on_copyAction_triggered)
            self.delAction = menu.addAction(QIcon(iconpack.icon("DELETE")),
                                            self._tr("Delete"))
            self.delAction.connect("triggered()", self.deleteFiles)

            self.upAction = menu.addAction(QIcon(iconpack.icon("UP")),
                                           self._tr("Upload files"))
            self.upAction.connect("triggered()", self.uploadFiles)
            self.createAction = menu.addAction(QIcon.fromTheme("folder"),
                                               self._tr("Create Folder"))
            self.createAction.connect("triggered()", self.createFolder)
            self.refreshAction = menu.addAction(
                QIcon(iconpack.icon("FILE_REFRESH")), self._tr("Refresh"))
            self.refreshAction.connect("triggered()", self.refresh)

            self.allactions = [
                self.openAction, self.downAction, self.renameAction,
                self.copyAction, self.delAction, self.upAction,
                self.createAction, self.refreshAction
            ]

        self.collector = FileCollector(schid, cid, password, self.downloaddir)
        self.collector.collectionFinished.connect(self._startDownload)
        self.collector.collectionError.connect(self.showError)

        self.fileDoubleClicked = Signal()
        self.contextMenuRequested = Signal()

        self.transdlg = None

        self.listmodel = FileListModel(schid,
                                       cid,
                                       password,
                                       self,
                                       readonly=readonly)
        self.listmodel.pathChanged.connect(self.onPathChanged)
        self.listmodel.error.connect(self.showError)

        self.proxy = QSortFilterProxyModel(self)
        self.proxy.setSortRole(Qt.UserRole)
        self.proxy.setSortCaseSensitivity(Qt.CaseInsensitive)
        self.proxy.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.proxy.setSourceModel(self.listmodel)

        self.listmodel.path = path

        self._adjustUi()

        if iconpackopened:
            iconpack.close()

        PluginHost.registerCallbackProxy(self)
Exemplo n.º 17
0
 def setup_method(self, method):
     self.signal = Signal()
Exemplo n.º 18
0
    def __init__(self, x, y, width, height):
        super().__init__(x, y, width, height)
        self.background.set_colorkey(None)
        self.confirm_output = Signal(args=['output'])

        self.text_size = 20
        margins = 5
        ui_width = 80
        ui_height = 25
        width_spacings = (width - 2.5 * ui_width - 2 * margins) / 4
        height_spacings = (height - 2 * margins - 3 * ui_height) / 4
        self.output_text = ['', '']

        self.list1 = ScrollList(margins + width_spacings,
                                margins,
                                ui_width / 2,
                                height - 2 * margins,
                                texts=[str(i) for i in range(20)],
                                text_size=self.text_size)
        self.list1.list_selected.connect(
            lambda text, **z: self.print_list_selection(text, 0))

        self.list2 = ScrollList(margins + width_spacings * 2 + ui_width / 2,
                                margins,
                                ui_width,
                                height - 2 * margins,
                                texts=['a', 'b', 'c', 'd'],
                                text_size=self.text_size)
        self.list2.list_selected.connect(
            lambda text, **z: self.print_list_selection(text, 1))

        self.output_box = TextBox(margins + width_spacings * 3 +
                                  ui_width * 1.5,
                                  margins + height_spacings,
                                  ui_width,
                                  ui_height,
                                  text='-',
                                  text_size=self.text_size)

        self.confirm_button = Button(margins + width_spacings * 3 +
                                     ui_width * 1.5,
                                     margins + height_spacings * 2 + ui_height,
                                     ui_width,
                                     ui_height,
                                     text='Call',
                                     text_size=self.text_size)
        self.confirm_button.clicked.connect(self.emit_output)
        self.cancel_button = Button(
            margins + width_spacings * 3 + ui_width * 1.5,
            margins + height_spacings * 3 + ui_height * 2,
            ui_width,
            ui_height,
            text='Pass',
            text_size=self.text_size)

        self.cancel_button.visible = False
        self.cancel_button.clicked.connect(self.cancelling)
        #self.children = [self.label1, self.list1, self.label2, self.list2,
        self.children = [
            self.list1, self.list2, self.confirm_button, self.output_box,
            self.cancel_button
        ]
        for element in self.children:
            element.parent = self

        self.redraw()
Exemplo n.º 19
0
def test_named_signal_has_a_nice_repr():
    signal = Signal(name='update_stuff')
    assert repr(signal) == '<signalslot.Signal: update_stuff>'
Exemplo n.º 20
0
def test_anonymous_signal_has_nice_repr():
    signal = Signal()
    assert repr(signal) == '<signalslot.Signal: NO_NAME>'
Exemplo n.º 21
0
    def __init__(self, conn):
        self.connecting = Signal()
        self.connected = Signal()
        self.sleeping = Signal()
        self.disconnected = Signal()
        self.reconnecting = Signal()
        '''(remote)'''
        self.typing = Signal()
        '''(remote)'''
        self.typingPaused = Signal()
        '''(remote)'''
        self.available = Signal()
        '''(remote)'''
        self.unavailable = Signal()

        self.messageSent = Signal()

        self.messageDelivered = Signal()
        '''(fmsg)'''
        self.messageReceived = Signal()
        '''messageReceived with fmsg.author'''
        self.groupMessageReceived = Signal()
        '''
        (fmsg)
        -> media_type: image, audio, video, location, vcard
        -> data
            image:
            -> url
            -> preview
            audio, video:
            -> url
            location:
            -> latitude
            -> longitude
            -> preview
            vcard:
            -> contact (vcard format)
        '''
        self.mediaReceived = Signal()
        '''mediaReceived with fmsg.author'''
        self.groupMediaReceived = Signal()
        '''(group, author, subject)'''
        self.newGroupSubject = Signal()
        '''(group, who)'''
        self.groupAdd = Signal()
        '''(group, who)'''
        self.groupRemove = Signal()
        ''' (groups: [{subject, id, owner}]) '''
        self.groupsReceived = Signal()

        self.groupListReceived = Signal()

        self.lastSeenUpdated = Signal()

        self.sendTyping = Signal()
        self.sendPaused = Signal()
        self.getLastOnline = Signal()

        self.disconnectRequested = Signal()
        self.disconnectRequested.connect(self.onDisconnectRequested)

        self.loginFailed = Signal()
        self.loginSuccess = Signal()
        self.connectionError = Signal()
        self.conn = conn

        self.sendTyping.connect(self.conn.sendTyping)
        self.sendPaused.connect(self.conn.sendPaused)
        self.getLastOnline.connect(self.conn.getLastOnline)

        self.startPingTimer()
Exemplo n.º 22
0
class UDP_Server(object):
    def __init__(self, ip, port, ttl, type_, id_):
        handler = UDP_Communications.UDP_Server.SenderHandler(
            self.__packet_received)
        self._server = UDP_Communications.UDP_Server(handler)
        # debug=True for more outputs in the Python command line.
        self._server.debug = False
        # Turn off local adapter filter; Let it switched off
        self._server.adapter_filter(False)
        self._server.init_udp(ip, port, ttl, System.Byte(type_),
                              System.Byte(id_), True)

        if not self._server.udp_active():
            raise RuntimeError("Server is not running!")
        pass

    def send_command(self, command, **kwargs):
        data = ['command', str(command)]
        for k, v in kwargs.items():
            data.append(str(k))
            data.append(str(v))
        result = self._server.send_command(data)
        return result

    def send_data(self, **kwargs):
        data = []
        for k, v in kwargs.items():
            data.append(str(k))
            data.append(str(v))
        self._server.send_data(data)

    def send_command_wait_for_reply(self, command, data=None, **kwargs):
        dataCmd = ['command', str(command)]
        if data is not None:
            for k, v in data.items():
                dataCmd.extend([k, v])
        for k, v in kwargs.items():
            dataCmd.append(str(k))
            dataCmd.append(str(v))
        method = self._server.send_command.Overloads[
            System.Array[System.String],
            System.String("").GetType().MakeByRefType()]
        res = method(dataCmd, "")
        return res[1]

    def start_stream(self, rxType, rxId):
        result = self._server.startStream(System.Byte(rxType),
                                          System.Byte(rxId))
        return result

    def stop_stream(self, rxType, rxId):
        self._server.stopStream(System.Byte(rxType), System.Byte(rxId))

    def stop(self):
        self._server.stop_udp()

    def send_stream(self, rxType, rxId, data):
        result = self._server.write(data.tobytes(), System.Byte(rxType),
                                    System.Byte(rxId))
        return result

    def stream_data_available(self, rxType, rxId):
        result = self._server.StreamDataAvailable(System.Byte(rxType),
                                                  System.Byte(rxId))

        # Is any data available
        if result[0]:
            # Is it data from the desired stream?
            if result[1] != rxType or result[2] != rxId:
                return False

        # Return result
        return result[0]

    def get_stream_data(self, rxType, rxId):
        streamData = self._server.getStreamData(System.Byte(rxType),
                                                System.Byte(rxId))
        if streamData is None:
            return
        dataArray = []
        # NOTE: This is very inefficient; Has to be improved
        # The problem is conversion from System.Byte to e.g. numpy data type
        #for x in streamData:
        #    dataArray.append(x)
        # NOTE: For now we just convert the first 10 elements. However, everything is received.
        for x in range(9):
            dataArray.append(streamData[x])

        return dataArray

    def __packet_received(self, server, event):
        paket = event.Paket
        if paket is None:
            return
        res_packet = Packet(paket)
        self.packet_received.emit(packet=res_packet)

    packet_received = Signal(args=['packet'])
Exemplo n.º 23
0
    def __init__(self):
        # Init logging facility
        # From : http://sametmax.com/ecrire-des-logs-en-python/
        logger = logging.getLogger()
        logger.setLevel(logging.DEBUG)
        formatter = logging.Formatter('%(asctime)s :: %(levelname)s :: %(message)s')
        file_handler = RotatingFileHandler('api_log.log', 'a', 1000000, 1)
        file_handler.setLevel(logging.DEBUG)
        file_handler.setFormatter(formatter)
        logger.addHandler(file_handler)

        stream_handler = logging.StreamHandler()
        stream_handler.setLevel(logging.DEBUG)
        logger.addHandler(stream_handler)

        # Signals
        self.signal_MCU_state_changed = Signal(args=['alive'])
        self.signal_received_descriptor = Signal(args=['var_id','var_type','var_name','var_writeable','group_id'])
        self.signal_received_group_descriptor = Signal(args=['group_id','group_name'])
        self.signal_received_value = Signal(args=['var_id'])

        self.distantio = distantio_protocol()
        self.protocol = Protocol(self.unused)

        # Queue holding received characters to be processed by worker process
        self.input_queue = mp.Queue()
        # Queue holding decoded frames
        self.output_queue = mp.Queue()
        # Conditions for controlling run process
        self.condition_new_rx_data = mp.Event()
        self.condition_new_rx_data.clear()
        self.condition_run_process = mp.Event()
        self.condition_run_process.clear()

        # Worker process for decoding characters
        self.producer_conn, self.consumer_conn = mp.Pipe()
        self.worker = Worker(self.input_queue,self.producer_conn,self.condition_new_rx_data,self.condition_run_process)
        self.worker.start()

        # Array containing buffers with MCU variables values
        self.variables_values = dict()
        # max size of the buffers
        self.buffer_length = 128
        # Array containing last time each individual variable was updated
        self.last_variables_update = dict()
        # Min delay in seconds between two emit value received signal
        self.emit_signal_delay = 0.1
        self.time_start = time.time()

        # Timer for monitoring MCU alive
        self.mcu_died_delay = 2.0
        self.mcu_alive_timer = threading.Timer(self.mcu_died_delay,self.on_mcu_lost_connection)

        self.variable_list = dict()
        self.connected = False

        self.datalogger = Datalogger()

        # Start MCU timer
        self.mcu_alive_timer = threading.Timer(self.mcu_died_delay,self.on_mcu_lost_connection)
        self.mcu_alive_timer.start()

        logging.info('DistantIO API initialized successfully.')
Exemplo n.º 24
0
class Table:
    """
    A Table is the place where all actions takes place. It is essentially a FSM, doing different
    routines at each state. It needs to keep track of the score, roles, the rules, etc. It needs
    to ask each player for decisions and respond to them accordingly. The table will also need
    to inform any decision to the Main Screen so that it can update the screen to reflect that
    change through the use of callbacks (Signal and Slot). This call should be minimised by making
    all the changes before calling to update the screen in one go.

    FSM cycles
    ---
    Preloop - Prepare the cards once
            - Initiate Players and connect them to the Table
    1.  Shuffle and Deal out cards to Players.
    2a. Detect weak hands and ask for reshuffle.
    2b. Return to (1) if any reshuffle occurs, otherwise proceed.
    3.  Bidding round. Randomly pick a starting player, in clockwise manner
        ask for a bid until it is valid.
    3b. Proceed only if 3 consecutive skips are detected.
    3c. Ask the winner of the bid a card not in their hand.
    3d. Set up the player roles, trump suit, rounds to win for both side
    3e.  Play the game. Start with bid winner if NO TRUMP, otherwise
        Starting next to the bid winner.
    4a.  With the first player, ask for any card, excluding trump suits if trump
        is not broken
    4b. With subsequent players, ask for cards that follow the suit of the first player
        , include trump suit if trump is broken. Ask for any card if the player cannot
        follow suit.
    4c. Once all 4 players has made valid plays, announce results, update scoring. Announce
        player roles if the partner card is played. Break trump if trump is played.
    4d. Repeat 4 until 13 rounds are made. Maybe add early win if confirmed one side wins
    5.  Ask for a new game. Go back to 1 if true.

    All played cards go into a hidden discard pile.

    """
    update_table = Signal()

    def __init__(self,
                 x,
                 y,
                 width,
                 height,
                 clear_colour,
                 autoplay=False,
                 view_all_cards=False):
        # TODO: Reduce the amount of update_table call
        self.x = x
        self.y = y
        self.width = width
        self.height = height

        self.table_font = pygame.font.SysFont("None", 25)
        self.player_font = pygame.font.SysFont("None", 25)

        # For gameplay
        self.game_state = GameState.DEALING
        self.current_round = 0
        self.passes = 0
        self.current_player = 0
        self.first_player = False  # This is for bidding purposes
        self.players = []
        self.players_playzone = []
        # Table status will be made known to the player by reference
        self.table_status = {
            'played cards': [0, 0, 0, 0],
            'leading player': 0,
            'trump suit': 1,
            'trump broken': False,
            'round history': [],
            'bid': 0,
            'partner': 0,
            'partner reveal': False,
            'defender': {
                'target': 0,
                'wins': 0
            },
            'attacker': {
                'target': 0,
                'wins': 0
            }
        }

        # Prepare the surfaces for displaying
        self.background = pygame.Surface((self.width, self.height))
        self.background.fill(clear_colour)
        self.background = self.background.convert()

        # TODO: Update the drawing of the table?
        # Prepare the card with dimensions
        w_deck = min(self.height, self.width) * 0.18
        l_deck = min(self.width, self.height) * 0.7
        # This is not a deck as it will never be drawn
        self.discard_deck = cards.prepare_playing_cards(
            int(w_deck * 0.7), int(w_deck * 0.9))
        game_margins = 5

        # Players' deck positioning
        playerx = ((self.width - l_deck) // 2, game_margins,
                   (self.width - l_deck) // 2,
                   self.width - w_deck - game_margins)
        playery = (self.height - w_deck - game_margins,
                   (self.height - l_deck) // 2, game_margins,
                   (self.height - l_deck) // 2)
        h_spacing = 20
        v_spacing = 25

        # Middle playfield for announcer and player playing deck positioning
        playfield_margins = 5
        margins_with_w_deck = w_deck + playfield_margins + game_margins
        playfield_x = margins_with_w_deck
        playfield_y = margins_with_w_deck
        playfield_width = self.width - margins_with_w_deck * 2
        playfield_height = self.height - margins_with_w_deck * 2

        playdeckx = (playfield_x + (playfield_width - w_deck) / 2, playfield_x,
                     playfield_x + (playfield_width - w_deck) / 2,
                     playfield_x + playfield_width - w_deck)
        playdecky = (playfield_y + playfield_height - w_deck,
                     playfield_y + (playfield_height - w_deck) / 2,
                     playfield_y,
                     playfield_y + (playfield_height - w_deck) / 2)

        # Player stats positioning
        stats_width = 100
        self.stats_height = 100
        stats_spacing = 10
        self.player_stats_x = (playdeckx[0] - stats_width - stats_spacing,
                               playdeckx[1],
                               playdeckx[2] + w_deck + stats_spacing,
                               playdeckx[3])
        self.player_stats_y = (playdecky[0] + w_deck - self.stats_height,
                               playdecky[1] - self.stats_height -
                               stats_spacing, playdecky[2],
                               playdecky[3] + w_deck + stats_spacing)

        self.player_stats = [[], [], [], []]

        # TODO: change surface to use colorkey, maybe, if the performance is tanked
        # Prepare all the player surfaces
        for i in range(4):
            vert = i % 2 == 1
            spacing = h_spacing
            if vert:
                spacing = v_spacing

            reveal_mode = cards.DeckReveal.HIDE_ALL
            if i == 0 or view_all_cards:
                reveal_mode = cards.DeckReveal.SHOW_ALL
            self.players.append(
                Player(playerx[i],
                       playery[i],
                       l_deck,
                       w_deck,
                       spacing,
                       vert_orientation=vert,
                       deck_reveal=reveal_mode))
            self.players[i].connect_to_table(self.table_status)
            if i > 0:
                self.players[i].add_ai(ai.RandomAI(self.table_status))

            self.players_playzone.append(
                cards.Deck(playdeckx[i], playdecky[i], w_deck, w_deck, 0))
            for j in range(3):
                surf = pygame.Surface((stats_width, self.stats_height / 3),
                                      pygame.SRCALPHA)
                rendered_text = self.player_font.render(
                    "Player {0:d}".format(i), True,
                    (255, 0, 255)).convert_alpha()
                self.center_text_on_surface(
                    surf, rendered_text,
                    (255, 255, 255, 255 * VIEW_TRANSPARENT))
                self.player_stats[i].append(surf)

        if autoplay:
            self.players[0].add_ai(ai.RandomAI(self.table_status))

        # Announcer positioning and surface creation
        announcer_margins = 5
        announcer_spacing = announcer_margins + w_deck
        self.announcer_x = playfield_x + announcer_spacing
        self.announcer_y = playfield_y + announcer_spacing
        self.announcer_width = playfield_width - 2 * announcer_spacing
        self.announcer_height = playfield_height - 2 * announcer_spacing
        self.announcer_line = []
        for i in range(3):
            surf = pygame.Surface(
                (self.announcer_width, self.announcer_height / 3),
                pygame.SRCALPHA)
            self.announcer_line.append(surf)

        self.update_all_players(role=True, wins=True)

        self.write_message("Press P to play!")

        self.ongoing = False

    def center_text_on_surface(self, surf, rendered_text, clear_colour):
        line_center = surf.get_rect().center
        text_rect = rendered_text.get_rect(center=line_center)
        surf.fill(clear_colour)
        surf.blit(rendered_text, text_rect)

    def write_message(self, text, delay_time=0.5, line=0, update_now=True):
        """
        Write a message into the center board surface (announcer)
        :param text: String to be displayed on the center board
        :param delay_time: How much delay to put once the string is display
        :param line: Which line of the announcer to write to
        :return: None
        """
        if 0 <= line < len(self.announcer_line):
            print(text)
            text = text.strip('\n')
            rendered_text = self.table_font.render(
                text, True, (255, 255, 255)).convert_alpha()
            self.center_text_on_surface(
                self.announcer_line[line], rendered_text,
                (255, 255, 255, 255 * VIEW_TRANSPARENT))
            if update_now:
                self.update_table.emit()
                time.sleep(delay_time)

    def update_players_role(self, player_num, update_now=True):
        self.player_stats[player_num][1].fill(
            (255, 255, 255, 255 * VIEW_TRANSPARENT))
        if self.players[player_num].role == PlayerRole.DEFENDER:
            rendered_text = self.player_font.render(
                "Defender", True, (0, 64, 192)).convert_alpha()
            self.center_text_on_surface(
                self.player_stats[player_num][1], rendered_text,
                (255, 255, 255, 255 * VIEW_TRANSPARENT))
        elif self.players[player_num].role == PlayerRole.ATTACKER:
            rendered_text = self.player_font.render(
                "Attacker", True, (192, 0, 0)).convert_alpha()
            self.center_text_on_surface(
                self.player_stats[player_num][1], rendered_text,
                (255, 255, 255, 255 * VIEW_TRANSPARENT))
        if update_now:
            self.update_table.emit()

    def update_player_wins(self, player_num, update_now=True):
        self.player_stats[player_num][2].fill(
            (255, 255, 255, 255 * VIEW_TRANSPARENT))
        if self.players[player_num].score > 1:
            rendered_text = self.player_font.render(
                "Wins: {0:d}".format(self.players[player_num].score), True,
                (255, 255, 255)).convert_alpha()
        else:
            rendered_text = self.player_font.render(
                "Win: {0:d}".format(self.players[player_num].score), True,
                (255, 255, 255)).convert_alpha()
        self.center_text_on_surface(self.player_stats[player_num][2],
                                    rendered_text,
                                    (255, 255, 255, 255 * VIEW_TRANSPARENT))
        if update_now:
            self.update_table.emit()

    def update_all_players(self, role=False, wins=True):
        for i in range(4):
            if wins:
                self.update_player_wins(i, update_now=False)
            if role:
                self.update_players_role(i, update_now=False)
        self.update_table.emit()

    def display_current_player(self, current=-1):
        if current >= 0:
            print("Player {0:d}\n".format(current))
        for i in range(4):
            rendered_text = self.player_font.render(
                "Player {0:d}".format(i), True, (255, 0, 255)).convert_alpha()
            if i == current:
                self.center_text_on_surface(self.player_stats[i][0],
                                            rendered_text, (0, 64, 0, 255))
            else:
                self.center_text_on_surface(
                    self.player_stats[i][0], rendered_text,
                    (255, 255, 255, 255 * VIEW_TRANSPARENT))

        self.update_table.emit()

    def update_team_scores(self):
        if self.table_status['partner reveal']:
            msg = "Defender: {0:d}/{2:d}, Attacker: {1:d}/{3:d}\n".format(
                self.table_status['defender']['wins'],
                self.table_status['attacker']['wins'],
                self.table_status['defender']['target'],
                self.table_status['attacker']['target'])
            self.write_message(msg, line=2)
        else:
            msg = "Defender: {0:d}?/{1:d}, Attacker: ?/{2:d}\n".format(
                self.table_status['defender']['wins'],
                self.table_status['defender']['target'],
                self.table_status['attacker']['target'])
            self.write_message(msg, line=2)

    def get_pos(self):
        return self.x, self.y

    def continue_game(self):
        """
        This is where the FSM is. State transition should occur here.
        What takes place in the state should be in a function.
        :return: None
        """
        # TODO: Adjust the timing of sleep
        if self.game_state == GameState.DEALING:
            self.shuffle_and_deal()
            self.write_message("Shuffle Complete!")
            self.game_state = GameState.POINT_CHECK

        elif self.game_state == GameState.POINT_CHECK:
            if self.check_reshuffle():
                self.write_message('Reshuffle Initiated!', line=1)
                self.game_state = GameState.ENDING
            else:
                self.write_message('No Reshuffle needed!')
                self.game_state = GameState.BIDDING
                self.write_message("Start to Bid")
                self.prepare_bidding()
        elif self.game_state == GameState.BIDDING:
            bid_complete = self.start_bidding()
            if bid_complete:
                self.game_state = GameState.PLAYING
                self.update_all_players(role=True, wins=True)
                self.update_team_scores()

        elif self.game_state == GameState.PLAYING:
            self.play_a_round()
            if self.current_round == 13:
                self.write_message("Game Set! Press P to play again!")
                self.ongoing = False
                self.game_state = GameState.ENDING
        else:
            self.reset_game()
            self.game_state = GameState.DEALING

    def shuffle_and_deal(self):
        """
        Shuffle and deal the discard deck to the players, which should have 52 cards.
        :return: None
        """
        if self.discard_deck:
            for i in range(10):
                random.shuffle(self.discard_deck)
            for player in self.players:
                for i in range(STARTING_HAND):
                    player.add_card(self.discard_deck.pop())
            self.update_table.emit()

    def check_reshuffle(self):
        """
        Detect any possible reshuffle request within the players
        :return: True if reshuffle requested, else False
        """
        print("Player Point Count")
        for i, player in enumerate(self.players):
            print("Player {0:d}: {1:d}".format(i, player.get_card_points()))
            if player.get_card_points() < 4:
                self.write_message(
                    "Low points detected in Player {0:d}! ".format(i))
                return player.make_decision(self.game_state, 0)

    def prepare_bidding(self):
        # Randomly pick a starting player, whom also is the current bid winner
        self.current_player = random.randint(1, NUM_OF_PLAYERS) - 1
        print("Starting Player: {0:d}".format(self.current_player))
        self.passes = 0
        self.table_status["bid"] = 11  # Lowest Bid: 1 Club by default
        self.first_player = True  # Starting bidder "privilege" to raise the starting bid
        msg = "Current Bid: {0:d} {1:s}".format(
            self.table_status["bid"] // 10,
            cards.get_suit_string(self.table_status["bid"] % 10))
        self.write_message(msg, line=1, delay_time=0)
        self.display_current_player(self.current_player)
        msg = 'Bid Leader: Player {0:d}'.format(
            (self.current_player - self.passes - 1 *
             (not self.first_player)) % 4)
        self.write_message(msg, line=2, delay_time=1)

    def start_bidding(self):
        """
        The bidding procedure.
        :return: Whether bidding is completed
        """
        # Highest bid: 7 NoTrump. No further check required
        if self.passes < NUM_OF_PLAYERS - 1 and self.table_status["bid"] < 75:
            player_bid = self.players[self.current_player].make_decision(
                self.game_state, 0)
            if not player_bid:
                if not self.first_player:  # Starting bidder pass do not count at the start
                    self.passes += 1
            else:
                self.table_status["bid"] = player_bid
                self.passes = 0

            if self.table_status["bid"] < 75:
                self.current_player += 1
                self.current_player %= 4
            msg = "Current Bid: {0:d} {1:s}".format(
                self.table_status["bid"] // 10,
                cards.get_suit_string(self.table_status["bid"] % 10))
            self.write_message(msg, line=1, update_now=False)
            msg = 'Bid Leader: Player {0:d}'.format(
                (self.current_player - self.passes - 1 *
                 (not self.first_player)) % 4)
            self.write_message(msg, line=2, update_now=False)
            self.display_current_player(self.current_player)
            if self.first_player:
                self.first_player = False
            time.sleep(0.5)
            return False
        else:
            self.write_message("Player {0:d} is the bid winner!".format(
                self.current_player),
                               delay_time=1)
            msg = "Player {0:d} is calling a partner...".format(
                self.current_player)
            self.write_message(msg, delay_time=1)
            self.display_current_player(self.current_player)
            # Ask for the partner card
            self.table_status["partner"] = self.players[
                self.current_player].make_decision(self.game_state, 1)

            # Setup the table status before the play starts
            self.table_status['partner reveal'] = False
            self.table_status["trump suit"] = self.table_status["bid"] % 10
            self.table_status["trump broken"] = False
            self.table_status['played cards'] = [0, 0, 0, 0]
            if self.table_status['trump suit'] == 5:
                self.table_status["leading player"] = self.current_player
            else:
                self.table_status["leading player"] = (self.current_player +
                                                       1) % 4
            self.table_status['defender'][
                'target'] = self.table_status["bid"] // 10 + 6
            self.table_status['attacker'][
                'target'] = 14 - self.table_status['defender']['target']

            # Set the roles of the players
            self.players[self.current_player].role = PlayerRole.DEFENDER

            self.write_message('Bidding Complete', delay_time=0)
            msg = 'Trump: {1:s}, Partner: {0:s}'.format(
                cards.get_card_string(self.table_status["partner"]),
                cards.get_suit_string(self.table_status['trump suit']))
            self.write_message(msg, line=1, delay_time=1)
            return True

    def play_a_round(self):
        """
        Ask each player to play a valid card and determine the winner of the round
        :return: None
        """
        if not any(self.table_status["played cards"]):
            # Leading player starts with the leading card, which determines the leading suit
            self.current_player = self.table_status['leading player']
            self.display_current_player(self.current_player)
            card = self.players[self.current_player].make_decision(
                self.game_state, 0)
            self.table_status["played cards"][self.current_player] = card
            self.players_playzone[self.current_player].add_card(card)
        elif not all(self.table_status["played cards"]):
            # Subsequent player make their plays, following suit if possible
            self.display_current_player(self.current_player)
            print("Player {0:d}\n".format(self.current_player))
            card = self.players[self.current_player].make_decision(
                self.game_state, 1)
            self.players_playzone[self.current_player].add_card(card)
            self.table_status["played cards"][self.current_player] = card
        else:
            # Once all player played, find out who wins
            leading_card = self.table_status["played cards"][
                self.table_status['leading player']]
            card_suits = [
                card.suit() for card in self.table_status["played cards"]
            ]
            card_nums = [
                card.number() for card in self.table_status["played cards"]
            ]
            follow_suits = [suit == leading_card.suit() for suit in card_suits]
            trumps = [
                suit == self.table_status['trump suit'] for suit in card_suits
            ]
            trump_played = any(trumps)

            # Break trump if the trump suit is played
            if not self.table_status['trump broken']:
                if trump_played:
                    self.table_status['trump broken'] = True
                    self.write_message("Trump Broken!", delay_time=1)

            # Determine which players to check for winner, and determine winner
            valid_nums = [
                card_nums[i] *
                ((follow_suits[i] and not trump_played) or trumps[i])
                for i in range(4)
            ]
            winning_player = valid_nums.index(max(valid_nums))
            self.write_message("Player {0:d} wins!\n".format(winning_player),
                               delay_time=1)
            self.players[winning_player].score += 1
            self.update_player_wins(winning_player)

            # Clean up the cards, update score, set the next leading player, update round history
            for deck in self.players_playzone:
                self.discard_deck.append(deck.remove_card())

            if self.players[winning_player].role == PlayerRole.DEFENDER:
                self.table_status['defender']['wins'] += 1
            elif self.players[winning_player].role == PlayerRole.ATTACKER:
                self.table_status['attacker']['wins'] += 1

            self.table_status['leading player'] = winning_player
            self.table_status['round history'].append(
                copy.copy(self.table_status["played cards"]))
            self.update_team_scores()
            self.table_status["played cards"] = [0] * 4
            self.current_round += 1
            self.update_table.emit()
            return

        if not self.table_status['partner reveal']:
            if card.value == self.table_status['partner']:
                self.table_status['partner reveal'] = True
                self.write_message("Partner Revealed!", delay_time=1)
                self.reveal_all_roles(self.current_player)
                self.update_all_players(role=True, wins=False)

        self.current_player += 1
        self.current_player %= 4
        self.update_table.emit()
        time.sleep(0.5)

    def reveal_all_roles(self, partner):
        self.players[partner].role = PlayerRole.DEFENDER
        self.table_status['defender']['wins'] += self.players[partner].score
        for i in range(4):
            if self.players[i].role == PlayerRole.UNKNOWN:
                self.players[i].role = PlayerRole.ATTACKER
                self.table_status['attacker']['wins'] += self.players[i].score

    def reset_game(self):
        for player in self.players:
            while not player.is_empty():
                self.discard_deck.append(player.remove_card())
            player.score = 0
            player.role = PlayerRole.UNKNOWN

        for i in range(4):
            self.update_players_role(i)
            self.update_player_wins(i)
        self.table_status['defender']['wins'] = 0
        self.table_status['attacker']['wins'] = 0
        self.table_status["played cards"] = [0] * 4
        self.table_status['round history'] = []
        self.current_round = 0
        self.write_message("", line=1, update_now=False)
        self.write_message("", line=2)
        self.display_current_player()
        print(len(self.discard_deck))
        self.update_table.emit()
Exemplo n.º 25
0
    def __init__(self,
                 x,
                 y,
                 width,
                 height,
                 clear_colour,
                 autoplay=False,
                 view_all_cards=False,
                 terminal=False):
        # TODO: Reduce the amount of update_table call
        self.update_table = Signal()
        self.x = x
        self.y = y
        self.width = width
        self.height = height

        self.table_font = pygame.font.SysFont("None", 25)
        self.player_font = pygame.font.SysFont("None", 25)

        # For gameplay
        self.game_state = GameState.DEALING
        self.reshuffling_players = []
        self.current_round = 0
        self.passes = 0
        self.current_player = 0
        self.first_player = False  # This is for bidding purposes
        self.players = []
        self.players_playzone = []
        # Table status will be made known to the player by reference
        self.table_status = {
            'played cards': [0, 0, 0, 0],
            'leading player': 0,
            'trump suit': 1,
            'trump broken': False,
            'round history': [],
            'bid': 0,
            'partner': 0,
            'partner reveal': False,
            'defender': {
                'target': 0,
                'wins': 0
            },
            'attacker': {
                'target': 0,
                'wins': 0
            }
        }

        # Prepare the surfaces for displaying
        self.background = pygame.Surface((self.width, self.height))
        self.background.fill(clear_colour)
        self.background = self.background.convert()

        # TODO: Update the drawing of the table?
        # Prepare the card with dimensions
        w_deck = min(self.height, self.width) * 0.18
        l_deck = min(self.width, self.height) * 0.7
        # This is not a deck as it will never be drawn
        self.discard_deck = cards.prepare_playing_cards(
            int(w_deck * 0.6), int(w_deck * 0.6 * 97 / 71))
        game_margins = 5

        # Players' deck positioning
        playerx = ((self.width - l_deck) // 2, game_margins,
                   (self.width - l_deck) // 2,
                   self.width - w_deck - game_margins)
        playery = (self.height - w_deck - game_margins,
                   (self.height - l_deck) // 2, game_margins,
                   (self.height - l_deck) // 2)
        h_spacing = 20
        v_spacing = 25

        # Middle playfield for announcer and player playing deck positioning
        playfield_margins = 5
        margins_with_w_deck = w_deck + playfield_margins + game_margins
        playfield_x = margins_with_w_deck
        playfield_y = margins_with_w_deck
        playfield_width = self.width - margins_with_w_deck * 2
        playfield_height = self.height - margins_with_w_deck * 2

        playdeckx = (playfield_x + (playfield_width - w_deck) / 2, playfield_x,
                     playfield_x + (playfield_width - w_deck) / 2,
                     playfield_x + playfield_width - w_deck)
        playdecky = (playfield_y + playfield_height - w_deck,
                     playfield_y + (playfield_height - w_deck) / 2,
                     playfield_y,
                     playfield_y + (playfield_height - w_deck) / 2)

        # Player stats positioning
        stats_width = 100
        self.stats_height = 100
        stats_spacing = 10
        self.player_stats_x = (playdeckx[0] - stats_width - stats_spacing,
                               playdeckx[1],
                               playdeckx[2] + w_deck + stats_spacing,
                               playdeckx[3])
        self.player_stats_y = (playdecky[0] + w_deck - self.stats_height,
                               playdecky[1] - self.stats_height -
                               stats_spacing, playdecky[2],
                               playdecky[3] - w_deck - stats_spacing)

        self.player_stats = [[], [], [], []]

        # TODO: change surface to use colorkey, maybe, if the performance is tanked
        # Prepare all the player surfaces
        for i in range(NUM_OF_PLAYERS):
            vert = i % 2 == 1
            spacing = h_spacing
            if vert:
                spacing = v_spacing

            reveal_mode = cards.DeckReveal.HIDE_ALL
            if i == 0 or view_all_cards:
                reveal_mode = cards.DeckReveal.SHOW_ALL

            if i == 0:
                player_class = players.MainPlayer
                if terminal:
                    player_class = players.Player
                self.players.append(
                    player_class(playerx[i],
                                 playery[i],
                                 l_deck,
                                 w_deck,
                                 spacing,
                                 vert_orientation=vert,
                                 deck_reveal=reveal_mode))
            else:
                self.players.append(
                    players.Player(playerx[i],
                                   playery[i],
                                   l_deck,
                                   w_deck,
                                   spacing,
                                   vert_orientation=vert,
                                   deck_reveal=reveal_mode,
                                   flip=(i == 1 or i == 2),
                                   draw_from_last=(i == 2 or i == 3)))

            self.players[i].connect_to_table(self.table_status)
            if i > 0:
                self.players[i].add_ai(ai.VivianAI(self.table_status))

            self.players_playzone.append(
                cards.Deck(playdeckx[i], playdecky[i], w_deck, w_deck, 0))
            for j in range(3):
                surf = pygame.Surface((stats_width, self.stats_height / 3),
                                      pygame.SRCALPHA)
                rendered_text = self.player_font.render(
                    "Player {0:d}".format(i), True,
                    (255, 0, 255)).convert_alpha()
                self.center_text_on_surface(
                    surf, rendered_text,
                    (255, 255, 255, 255 * VIEW_TRANSPARENT))
                self.player_stats[i].append(surf)

        if autoplay:
            self.players[0].add_ai(ai.VivianAI(self.table_status))

        # Announcer positioning and surface creation
        announcer_margins = 5
        announcer_spacing = announcer_margins + w_deck
        self.announcer_x = playfield_x + announcer_spacing
        self.announcer_y = playfield_y + announcer_spacing
        self.announcer_width = playfield_width - 2 * announcer_spacing
        self.announcer_height = playfield_height - 2 * announcer_spacing
        self.announcer_line = []
        for i in range(3):
            surf = pygame.Surface(
                (self.announcer_width, self.announcer_height / 3),
                pygame.SRCALPHA)
            self.announcer_line.append(surf)

        self.update_all_players(role=True, wins=True, clear_wins=True)

        self.write_message("Press P to play!")

        self.ongoing = False
        self.require_player_input = False

        self.terminal_play = terminal
        self.calling_panel = UI.CallPanel(playdeckx[0] + w_deck + 5,
                                          playdecky[0] + w_deck - 100, 220,
                                          100)
        self.calling_panel.parent = self
        self.calling_panel.visible = False
        self.parent = None

        self.calling_panel.confirm_output.connect(self.emit_call)

        self.yes_button = UI.Button(playdeckx[0] + w_deck + 5,
                                    playdecky[0],
                                    50,
                                    25,
                                    text='yes')
        self.yes_button.visible = False
        self.yes_button.clicked.connect(lambda **z: pygame.event.post(
            pygame.event.Event(CALL_EVENT, call=True)))

        self.no_button = UI.Button(playdeckx[0] + w_deck + 5,
                                   playdecky[0] + 25 + 25,
                                   50,
                                   25,
                                   text='no')
        self.no_button.clicked.connect(lambda **z: pygame.event.post(
            pygame.event.Event(CALL_EVENT, call=False)))
        self.no_button.visible = False

        self.UI_elements = [
            self.calling_panel, self.yes_button, self.no_button
        ]