soukouki’s diary

誰かの役に立つ記事をかけたらいいなあ

LispでDiscordBotを作る!

wispというaltJSの方言(clojureに近い)を使い、discord.jsというライブラリを使って楽をします。

discord.jsは活発なライブラリなので、新機能とかが出てきても安心ですね!

まずは、node.jsをインストール。

それぞれのライブラリをインストール npm install discord.js npm install wisp

そしてプログラムを入力

test.wisp

(def token "*****TOKEN*****")

(def Discord (require "discord.js"))

(def client (Discord.Client.))

(client.on "message"
  (fn [msg]
      (let [args (msg.content.split " ")]
        (console.log args)
        (cond
          (== (get args 0) "!dice")
            (let [num (let [n (parse-int (get args 1) 10)]
                           (if (naN? n) 6 n))]
                 (msg.channel.send (+ (num.->string 10)
                                      "面ダイズを振った。\nカランコロン....\n__"
                                      (+ 1 (Math.floor(* (Math.random) num))) "__")))))))

(client.login token)

(wisp初心者なので間違っているところなどありましたらコメントにお願いします ><)

(naN?問題()) (連続let・・・)

Discord側の設定や、トークンについては discordapp.com ここから

イチからDiscord Bot 。for Ruby - Qiita

Discord Bot の 簡単な作り方 – Asamac blog

ここらを適当に参考にしてください。

cat test.wisp | node_modules/.bin/wisp --no-map > test.js

すると、こんなソースコードが出力されます。

test.js

var token = exports.token = '*****TOKEN*****';
var Discord = exports.Discord = require('discord.js');
var client = exports.client = new Discord.Client();
client.on('message', function (msg) {
    return function () {
        var argsø1 = msg.content.split(' ');
        console.log(argsø1);
        return (argsø1 || 0)[0] == '!dice' ? function () {
            var numø1 = function () {
                var nø1 = parseInt((argsø1 || 0)[1], 10);
                return isNaN(nø1) ? 6 : nø1;
            }.call(this);
            return msg.channel.send(numø1.toString(10) + '面ダイズを振った\u3002\nカランコロン....\n__' + (1 + Math.floor(Math.random() * numø1)) + '__');
        }.call(this) : void 0;
    }.call(this);
});
client.login(token);

node test.js

f:id:soukouki:20171115222912p:plain

あなたに快適なBOTライフを!

node v8.9.1 discord.js@11.2.1 wisp@0.10.0

メモ Ruby対数正規分布の乱数

(2017/11/16)あああタイトル間違ってましたぁ・・更新前に見た方申し訳ないです・・

合っているかは自信ないです・・

ゲームの乱数くらいにお使いください。

require "random_bell"

# http://pmsl.planet.sci.kobe-u.ac.jp/~seto/?page_id=316
# をRubyに移植
def lognormal mu, sigma
    return Float::NAN if (mu <= 0)
    bell = RandomBell.new(
        mu: Math.log(mu*mu) - Math.log(mu*mu + sigma*sigma) / 2.0,
        sigma: Math.sqrt(Math.log(1 + (sigma / mu) * (sigma / mu))),
        range: -10..10)
    Math.exp(bell.rand)
end

分布確認用

require"./lognormal"
puts (1..10000).to_a.map{|n|lognormal(平均,分布).to_i}.inject({}){|r,n|r[n]||=0;r[n]+=1;r}.sort_by{|n,v|n}.map{|n,v|"#{n} #{"*"*v}"}

C++(標準ライブラリ)にもPython(NumPy)にもC#(Math.net)にもあるのに
Rubyにはない悲しみ

gem install random_bell random_bellを使用しています。

random_bell (0.1.1) ruby 2.3.3p222 (2016-11-21 revision 56859) [x64-mingw32]

Hamlの組み込み

Hamlをテキストから直接実行したいときのメモ

require "haml"
template = <<'EOS'
%p= a1
%p= a2*3
- a3.each do |i|
  %p= i**2
EOS

haml_engine = Haml::Engine.new(template)
puts haml_engine.render(Object.new, a1:123, a2:10, a3:[1, 2, 3, 5])

ヒアドキュメントはインデントが合わなくなるから嫌いです・・・

参考

File: REFERENCE — Haml Documentation

Ruby:実行中のソースコードのファイルがあるディレクトリ

いいページがあるものの、検索でなかなか引っかからないので自分でページを作ってみた。

d.hatena.ne.jp

これのものです。

File.expand_path(File.dirname(__FILE__))