from coldcall import ColdCall
import re
import discord
+import config
+import random
## create the coldcall object
cc = ColdCall()
async def on_ready(self):
print(f'Logged on as {self.user}! Ready for class!')
- async def on_message(self, message):
+ async def on_message(self, message, voice_channel = 'Class Sessions'):
if message.author == self.user:
return
if message.content.startswith('$next'):
- classroom = discord.utils.get(message.guild.voice_channels, name='Classroom Voice')
-
+ if message.channel.category:
+ if cc.course != message.channel.category:
+ cc.update_course(message.channel.category)
+ classroom = [x for x in message.guild.voice_channels if x.name == voice_channel and x.category_id == message.channel.category_id][0]
+
present_students = []
for member in classroom.members:
if 'Students' in [r.name for r in member.roles]:
msg_text = "I don't see any students currently in the Classroom Voice channel!"
else:
msg_text = cc.coldcall(present_students)
-
+
await message.channel.send(msg_text)
+ # TODO: Only let admin send this command
+ if (message.content.startswith('$network game')) and ('Teachers' in [r.name for r in message.author.roles]):
+ print("Starting the game")
+ if message.channel.category:
+ if cc.course != message.channel.category:
+ cc.update_course(message.channel.category)
+ classroom = [x for x in message.guild.voice_channels if x.name == voice_channel and x.category_id == message.channel.category_id][0]
+
+ present_students = []
+ for member in classroom.members:
+ if 'Students' in [r.name for r in member.roles]:
+ present_students.append(member)
+
+ self.assignments = get_assignments(present_students, edgelist = './network_game/test_edgelist.csv')
+ # Build a mapping from names to user objects so that people can refer to users
+ self.active_list = {x.name: x for x in self.assignments}
+ self.observers = [x for x in classroom.members if x not in self.assignments]
+ if self.assignments is not None:
+ for student in self.assignments:
+ await student.send(f"You are allowed to talk to:")
+ for neighbor in self.assignments[student]['neighbors']:
+ await student.send(f"{neighbor.mention}")
+ await student.send(f"You have these resources: {self.assignments[student]['has']}.")
+ await student.send(f"You need: {self.assignments[student]['needs']}.")
+ else:
+ for student in present_students:
+ await student.send("Not enough students to play")
+
+ if message.content.startswith('$send'):
+ try:
+ _, resource, u_to = message.content.split(' ')
+ except:
+ await message.author.send("Badly formed command. It has to be '$send resource @user'")
+ if u_to not in self.active_list:
+ await message.author.send(f"I can't find {u_to} in the list of users. Make sure the command is formatted as $send resource @user")
+ else:
+ u_to = self.active_list[u_to]
+ gave_resource = self.give_resource(resource, message.author, u_to)
+ if gave_resource == True:
+ finished = self.is_finished(u_to)
+ await message.author.send(f"{resource} sent to {u_to}")
+ await message.author.send(f"You now have {self.assignments[message.author]['has']} and you need {self.assignments[message.author]['needs']}")
+ if finished:
+ await u_to.send("You have everything you need! Well done! You can keep passing resources and talking with your 'neighbors' if you like. Just make sure to keep the resources that you need!")
+ else:
+ await u_to.send(f"You now have {self.assignments[u_to]['has']} and you need {self.assignments[u_to]['needs']}")
+
+ for o in self.observers:
+ await o.send(f"{message.author.name} sent {resource} to {u_to.name}")
+ if finished:
+ await o.send(f"{u_to.name} has everything they need!!!")
+
+ else:
+ await message.author.send(f"Resource not sent. Are you sure you have {resource}?")
+ def is_finished(self, u_to):
+ if set(self.assignments[u_to]['needs']) <= set(self.assignments[u_to]['has']):
+ return True
+ return False
+
+
+
+
+
+
+ def give_resource(self, resource, u_from, u_to):
+ if resource not in self.assignments[u_from]['has']:
+ return False
+ else:
+ self.assignments[u_from]['has'].remove(resource)
+ self.assignments[u_to]['has'].append(resource)
+ return True
+
+
+def get_assignments(student_list,
+ edgelist = './network_game/edgelist.csv',
+ resource_prefix = './network_game/resources_'
+ ):
+
+
+ def _add_connection(node1, node2):
+ node1 = int(node1)
+ node2 = int(node2)
+ for i in range(len(mapping[node1])):
+ s1 = mapping[node1][i]
+ s2 = mapping[node2][i]
+ if s1 in assignments:
+ assignments[s1]['neighbors'].append(s2)
+ else:
+ assignments[s1] = {'neighbors': [s2]}
+
+ def _add_resources():
+ fn = f"{resource_prefix}{group_size}.csv"
+ with open(fn, 'r') as f:
+ i = 1
+ for line in f.readlines():
+ resources = line.strip().split(',')
+ curr_students = mapping[i]
+ for s in curr_students:
+ assignments[s]['has'] = resources[:3]
+ assignments[s]['needs'] = resources[3:]
+ i += 1
+
+
+
+ assignments = {}
+ group_size = _get_group_size(len(student_list))
+ if len(student_list) < group_size:
+ return None
+ mapping = _make_mapping(student_list, group_size)
+ with open(edgelist, 'r') as f:
+ for line in f.readlines():
+ node1, node2 = line.strip().split(',')
+ if int(node2) <= group_size:
+ _add_connection(node1, node2)
+ _add_connection(node2, node1)
+ _add_resources()
+ return assignments
+
+
+
+def _make_mapping(students, group_size):
+ random.shuffle(students)
+ n_observers = len(students) % group_size
+ mapping = {}
+ if n_observers > 0:
+ mapping['observers'] = students[-n_observers:]
+ for i, student in enumerate(students[-n_observers:]):
+ j = i % group_size
+ idx = j + 1
+ if idx in mapping:
+ mapping[idx].append(student)
+ else:
+ mapping[idx] = [student]
+ return mapping
+
+
+def _get_group_size(n):
+ min_observers = None
+ for x in range(7,10):
+ observers = n % x
+ if min_observers is None or observers < min_observers:
+ best_fit = x
+ min_observers = observers
+ return best_fit
+
+
+
+
# this is necessary to get information about who is online
intents = discord.Intents.default()
intents.presences = True
ccb = ColdCallBot(intents=intents)
-ccb.run('CHANGEME')
-
+ccb.run(config.key)