LoginSignup
4
5

More than 3 years have passed since last update.

ランダムでチーム分けをするDiscord Botを作った😇

Last updated at Posted at 2019-07-20

https://github.com/HGBBs/random_team
unknown (2).png
GODFIELDとか紅白戦をやるときに、サクッとチーム分けてくれるツールがあったら便利だなぁと思い、作ることにした。
すでにそのようなWebサイト12やDiscord Bot34もあるが、勉強と遊びを兼ねて開発していく(車輪の再発明サイコー😍)

仕様

仕様としては、コマンド(!rt)とチーム数を受け取り、コマンドを打った人が参加しているVoiceChannelの参加メンバーでチーム分けをする(ココ重要)。通話に参加しているメンバーでチーム分けするので、メンバーの名前や一覧をいちいち入力する必要がないという天才的発想😜🤔

使った言語はDart🎯で、nyxxというDiscrod APIのwrapper Packageを使った。

チーム分けロジック実装

チームが割り切れない場合どうするかかなり悩んだが、潔く余った人を補欠にして、判断はその状況に任せることにした😇

random_team.dart
   Map<String, List<String>> getRondomTeam(int teamNum) {
     int fill = players.length % teamNum;
     Map<String, List<String>> teams = {};
     teamNameList.shuffle();
     players.shuffle();
     int peoplePerTeam = players.length ~/ teamNum;
     teamNameList.take(teamNum).toList().asMap().forEach(
         (i, teamName) => 
            teams[teamName] = players.skip(i * peoplePerTeam).take(peoplePerTeam);
     teams['😇 sub'] = players.sublist(players.length - fill, players.length);
     return teams;
   }

players.length ~/ teamNum(players.length/teamNum).toInt()と同義で、~/演算子はよくやる除算とintへのキャストを同時にやってくれる😍
チーム名はガルパンになぞった絵文字にしようと思ってたけど、あんこうの絵文字がなかったので、仕方なくなんかそれっぽい動物の絵文字にすることにした😢 詳しい実装はGitHubみてどうぞ👀 Panzer vor !

DiscordBot Embed実装

embed(埋め込みメッセージ)は↓みたいなやつ
image.png

メインの実装はnyxxのドキュメントを見るか、これを参考にしてもらって、ここではembed_builderの注意点を書く🚨

embed_builder.dart
   EmbedBuilder embed = (EmbedBuilder()
     ..title = "random team"
     ..color = DiscordColor.fromInt(13369286));
   randomTeam.forEach((key, value) => embed.addField(
       name: key,
       content: value.isNotEmpty ? ' ' + value.join(', ') : '👻',
       inline: true));

↑のコードのようにembed_builderでembedを作成して、send(embed: embed)のような感じでembedを表示出来るんだけど、embed.addField(name: name, content: '')のように、contentに空文字('')を渡すとエラーを吐かずにembedも表示されないので、何かしら渡してあげる必要がある(ゼロ幅スペースとかでいいかもしれない、自分の場合は可愛いから👻にしたけど)

VoiceChannelに参加しているメンバーの取得

大事なとこ書くの忘れてた🤣

get_vc_member.dart
      var channel = (e.message.author as Member).voiceState.channel;
      List<String> users = channel.connectedUsers
          .map((voiceState) => voiceState.user.username)
          .toList();

一行目で、コマンドを打ったuserの参加しているVoiceChannelを取得し、2行目のchannel.connectedUsersで、通話に参加しているメンバーのリストを取得できる📞

おわりに

個人的にBotは、作りやすく実用的で勉強にもなる最強の教材だと思うのでぜひ作ってみてほしい🤖 とりわけDiscordBotは、ほとんどの言語でライブラリが用意されているので超オススメ😘 

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5