https://github.com/HGBBs/random_team
GODFIELDとか紅白戦をやるときに、サクッとチーム分けてくれるツールがあったら便利だなぁと思い、作ることにした。
すでにそのようなWebサイト12やDiscord Bot34もあるが、勉強と遊びを兼ねて開発していく(車輪の再発明サイコー😍)
仕様
仕様としては、コマンド(!rt)とチーム数を受け取り、コマンドを打った人が参加しているVoiceChannelの参加メンバーでチーム分けをする(ココ重要)。通話に参加しているメンバーでチーム分けするので、メンバーの名前や一覧をいちいち入力する必要がないという天才的発想😜🤔
使った言語はDart🎯で、nyxxというDiscord APIのwrapper Packageを使った。
チーム分けロジック実装
チームが割り切れない場合どうするかかなり悩んだが、潔く余った人を補欠にして、判断はその状況に任せることにした😇
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 実装
メインの実装はnyxxのドキュメントを見るか、これを参考にしてもらって、ここではembed_builderの注意点を書く🚨
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 に参加しているメンバーの取得
大事なとこ書くの忘れてた🤣
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は、ほとんどの言語でライブラリが用意されているので超オススメ😘