Consider a list of items (take a list of voice channels) where each item has these attributes
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:
- When a member joins a
VoiceChannelit should make the first invisible and empty channel in the list visible. - If one empty
VoiceChannelis already visible then don't make any new ones visible. - If more than one empty channel is visible then only make the first empty channel visible.
Notes
- All
VoiceChannelitems except the first are invisible in initial state. - A member can only join one
VoiceChannelat a time. - A member needs to join at least one
VoiceChannelbefore 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?

make_visibleandmake_invisiblemethods 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.on_leavemean if you passed two voice channels instead of one and NULL (which means leave all)?