-3

Consider a list of items (take a list of voice channels) where each item has these attributes

UML Diagram

System::vc: List of voice channels.

System::on_join(member, before, after): On the event when a member joins a VoiceChannel the first time, it's before is Null and after is a VoiceChannel. When a member switches voice channels, before and after are different VoiceChannels.

System::on_leave(member, before, after): On the event when a member leaves all voice channels (ie: does not switch to another VoiceChannel), before will be a VoiceChannel and after will be Null.

System::get_room(no): Get a VoiceChannel from it's number.

VoiceChannel::number: The number of the VoiceChannel (ie, index of System::vc + 1).

VoiceChannel::is_empty(): Returns True if there are no members in the channel, else False.

VoiceChannel::is_visible(): Returns True if the channel is currently visible, else False.

VoiceChannel::make_visible(): Makes a channel visible to all members. Returns True if successful and False if not.

VoiceChannel::make_invisible(): Makes a channel invisible to all members. Returns True if successful and False if not.


I'm trying to develop an algorithm to obtain this result when applied on System::vc:

  1. When a member joins a VoiceChannel it should make the first invisible and empty channel in the list visible.
  2. If one emptyVoiceChannel is already visible then don't make any new ones visible.
  3. If more than one empty channel is visible then only make the first empty channel visible.

Notes

  1. All VoiceChannel items except the first are invisible in initial state.
  2. A member can only join one VoiceChannel at a time.
  3. A member needs to join at least one VoiceChannel before they can switch between voice channels. So it's not possible to switch from channel 1 to channel 2 without having first already joined channel 1.

What I have tried

Psuedocode

def on_join(member, before, after):
    vc_visible = []
    for vc in self.vc:  # self is an instance of System
        if is_visible(vc):
            vc_visible.append(vc)
    
    last_vc_number = len(vc_visible) + 1
    if last_vc_number == 21:  # Total number of VoiceChannels + 1
        return
    
    self.vc_last = self.get_room(last_vc_number)
    for vc in self.vc:
        if is_visible(vc) and is_empty(vc) and vc.number != 1:
            self.vc_next_visible = vc
            return
        elif vc == self.vc_next_visible:
            await make_visible(self.vc_next_visible)
            return
        else:
            await make_visible(self.vc_last)
            return

async def on_leave(member, before, after):
    vc_visible = []
    for vc in self.vc:  # self is an instance of System
        if is_visible(vc):
            vc_visible.append(vc)

    # Cycle through list from second last to front
    for vc in vc_visible[:len(vc_visible) * -1 :-1]:
        if is_empty(vc) and is_empty(vc_visible[0]):
            await make_invisible(vc)
        elif is_empty(vc):
            if vc != self.vc_next_visible and vc.number != 2:
                await make_invisible(vc)

    for vc in self.vc:
        if is_visible(vc) and is_empty(vc) and vc.number != 1:
            self.vc_next_visible = vc
            return

Question

How do I go about writing psuedo code or a concrete algorithm to make this work with just on_join and on_leave events?

  • "When a member joins a VoiceChannel it should make the next one in the list visible." to whom? Everyone or just that member? – Erik Eidt Nov 20 at 16:10
  • @ErikEidt To everyone. The make_visible and make_invisible methods make the channels visible and invisible to everyone. The details of how the function works is not important, just know that it automatically does it for all members. – daegontaven Nov 20 at 16:17
  • "On the event when a member leaves all voice channels (ie: does not switch to another VoiceChannel), before will be a VoiceChannel and after will be Null." Why do you need to pass one VoiceChannel if they are leaving all of them? Which one is passed? – Erik Eidt Nov 20 at 17:00
  • What would on_leave mean if you passed two voice channels instead of one and NULL (which means leave all)? – Erik Eidt Nov 20 at 17:01
  • Maintain a list of "currently invisible" channels in sorted order. Whenever there's need to convert a currently invisible channel into a visible one, pick from the top of this list. When a channel turns into invisible, put that channel into the list, and sort it. – rwong Nov 20 at 22:07
2
+50

Stop asking things about their state and start telling them what you want. Also, don't use null if you can help it.

With that in mind here's a redesign:

System::on_join(member, after, emptyChannel) On the event when a member joins a VoiceChannel the first time, after is the VoiceChannel they join.

System::on_switch(member, before, after, emptyChannel) When a member switches voice channels, before and after are different VoiceChannels.

System::on_leave(member, before, after, emptyChannel) On the event when a member leaves all voice channels (ie: does not switch to another VoiceChannel), before will be a VoiceChannel and after will be Null.

Both on_switch and on_leave can call leaveChannel(member, before, emptyChannel) and tell the channel about the member leaving. The channel can update it's member list, update it's visibility, or file a tax return, whatever the channel wants to do.

Both on_switch and on_join can call joinChannel(member, after, emptyChannel) and tell the channel about the member leaving. The channel can update it's member list, update it's visibility, or send the member spam email, whatever the channel wants to do.

This might seem weird but you can make the channels smart enough to handle this stuff on their own. All they need to know is that it's time to check if they should be visible, how many members they have, and if empty, if emptyChannel is lower numbered or conversely if it just got filled. With that info they can figure out visibility themselves. You don't have to keep building lists.

| improve this answer | |
  • Can you explain what is emptyChannel? I'm still not following your algorithm. – daegontaven Nov 25 at 5:04
  • nvm i figured it out – daegontaven Nov 25 at 8:37
  • Rather than before and after consider the names leaving and joining. – candied_orange Nov 25 at 16:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.