From: Jeremy Foote Date: Sun, 10 Jan 2021 03:45:48 +0000 (-0500) Subject: I added a network game to the bot. Need to refactor it but it's working for now X-Git-Url: https://code.communitydata.science/coldcallbot-discord.git/commitdiff_plain/46796e647a212663fa3821ffd4459c4133b97bb3?hp=788ed2de621c56cd0cbd262c6c83559d31608f76 I added a network game to the bot. Need to refactor it but it's working for now --- diff --git a/coldcallbot.py b/coldcallbot.py index fd7669f..621870d 100755 --- a/coldcallbot.py +++ b/coldcallbot.py @@ -4,6 +4,7 @@ from coldcall import ColdCall import re import discord import config +import random ## create the coldcall object cc = ColdCall() @@ -33,11 +34,157 @@ class ColdCallBot (discord.Client): if len(present_students) < 1: msg_text = "I don't see any students currently in the Classroom Voice channel!" else: - if cc is None: - print('hi') 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()