]> code.communitydata.science - coldcallbot-discord.git/commitdiff
I added a network game to the bot. Need to refactor it but it's working for now foote_spring_2021
authorJeremy Foote <jdfoote1@gmail.com>
Sun, 10 Jan 2021 03:45:48 +0000 (22:45 -0500)
committerJeremy Foote <jdfoote1@gmail.com>
Sun, 10 Jan 2021 03:45:48 +0000 (22:45 -0500)
coldcallbot.py

index fd7669f7ceea6414baedb2677d1535755261811d..621870d4920d629fc18f06444966656c63318fcb 100755 (executable)
@@ -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()

Community Data Science Collective || Want to submit a patch?