PLAYNOTE 変愚蛮怒のモンスターたちがおしゃべりするTwitterのbot

2010年08月22日

変愚蛮怒のモンスターたちがおしゃべりするTwitterのbot

[ネット・PC] 2010/08/22 23:14
hengband_speak.png
こんなん

Rogue→Moria→Angbandの系譜上にある日本製の変態Variant・変愚蛮怒の頭トチ狂った台詞をひたすら吐き続けるTwitterのBotです。あなたのTLに恐竜バーニーちゃんや灰色のガンダルフ、アルベリヒやハーゲンや世紀末覇者ラオウのつぶやきが並びます。

何をするのか

  • 不定期につぶやきます。
  • ラッキーなときは30分に一回、運が悪いと2~3日更新されず、アンラッキーなときには5分に一回つぶやきます。更新は自動なのですが、条件が複雑なのでそういうことが起こります。
  • モンスターの台詞をつぶやきます。
  • 内容は、変愚蛮怒1.6.2のmonspeak_j.txtmonfear_j.txtmonfrien_j.txtmondeath_j.txtからの抜粋です。
  • 本来喋らないはずのr_info.txtCAN_SPEAKフラグがついていない奴も、たまに喋ります。(ここが適当)
  • ユニークモンスターのお喋りは、割と原作通りのはずです。

「え、お前が作ったの?」

と思われそうでヒヤヒヤしていますが、あんまりにも文系脳をぐるぐる回していたので、筆休めに久々にPerl書いてみました。モジュールって本当に便利だね。Twitter APIなんか一つも理解してないのにすぐ作れたよ。

それにしても誰にも意味のわからないものですみません(><)。

作り方

Strawberry Perl なんていう新しいPerl実行環境がリリースされていたのでインストール。PadreというIDEを使いました。便利ですねこれ。

r_info.txtからモンスター番号と名前の対照表を作成r_info.csvmonspeak.txtとかからモンスター番号とセリフの対照表を作成data.csv。この辺のデータの準備はPerlとExcelとxyzzyでズルしました。

プログラム内ではまずr_info.csvからモンスター番号と名前の対象表をロードし、その後、data.csvからセリフデータをロードし、乱数を発生させてセリフをチョイスしています。

データ生成のルーチンが完成したので次はTwitterとの通信。CPANからNet::TwitterLWP::UserAgentJSON::Anyなんかをインストール。【CGI・Perl】Twitterのステータスを更新するNet::Twitterで超簡単にPostしてみる - ナマアシタノム等々を参考に、さくっと通信部分をコピペ。どうもありがとうございます(><)。ログインしてポストし、結果をコンソールにPrintし、ウェブブラウザでTwitter画面を開いています。

サーバーに上げてCronで回そうかと思ったんだけど、XREAには必要なモジュールがインストールされていなかったので断念。しょうがねーからローカルPCでTClockのアラーム機能を使って30分に1回動かしています。

ソース

以下ソース。設計なんか何もしないままゴリゴリ書いた&Perlいじるの3年ぶりくらいなので酷いソースですが。

use strict;
use utf8;
use warnings;
 
my %monster = get_monster_list();
my $serifu  = get_serifu();
post_twitter();
sleep 10;
exit;
 
# -----------サブルーチンだよ(><)-----------
 
sub get_monster_list{
  # モンスター番号と名前の対象表をロード
  open(READ, "./r_info.csv") or error('r_info.csv ログオープンに失敗');
  my @read = ;
  close(READ);
 
  # ハッシュ %monster に番号と名前をセット
  my %monster;
  foreach (@read) {
    my($num,$name)=split(/\t/,$_);
    $name =~ s/\n//;
    $monster{"$num"}=$name;
  }
 
  return(%monster);
}
 
sub get_serifu{
  # セリフデータをロード
  open(READ, "./data.csv") or error('data.csv ログオープンに失敗');
  my @data_csv = ;
  close(READ);
 
  # 乱数を生成(セリフが853行あるので0-853まで)し、セリフのどの行を喋るか決める
  my $rnd_value = int(rand(852));
 
  # タブでモンスター番号とセリフを切り分ける
  my($kouho,$serifu) = split(/\t/,$data_csv["$rnd_value"]);
  $serifu =~ s/\n//g;
 
  # モンスター番号が 1)リストの場合 2)*の場合 3)数字1つの場合 に分けて演算
  # モンスター番号を決めて、セリフを決める
  my $number;
  if($kouho =~ /,/g) {
    my @kouho = split(/,/,$kouho);
    my $rnd_kouho = int rand(@kouho);
    $number = $kouho[$rnd_kouho];
  }elsif($kouho eq '*'){
    $number = int(rand(1069)) + 1;   # 1-1069(モンスター総数)までの乱数を生成
  }else{
    $number = $kouho;
  }
 
  return("$monster{$number}$serifu");
}
 
sub post_twitter{
  # Twitter 投稿準備
  use Net::Twitter;
  use Encode;
  use encoding 'UTF-8', STDOUT => 'cp932';
  
  # ログイン
  print "Twitter APIとの通信を開始します。\n";
  my $twit = Net::Twitter->new(
    username=>"hengband_speak",
    password=>"********");
 
  #-- Twitterへ送信 --#
  my $result = $twit->update("$serifu");
 
  if ($result){
    print << "EOS";
通信成功、っぽい。
更新内容:
$serifu
Twitterをウェブブラウザで開いて、終了を待機します。
EOS
    use Win32::FileOp qw(ShellExecute);
    ShellExecute('http://twitter.com/hengband_speak');
  }else{
    print "通信失敗したよ(><)。"
  }
  
  return();
}
 
sub error{
  my (@error) = @_;
  print "Content-type: text/plain\n\n";
  print "$_\n" foreach @error;
  exit;
}

今後の予定

特になし。変愚蛮怒の殺伐とした台詞をTLで眺めてニヤニヤします(><)。

何か問題あったら@playnoteまでお願いします。

追記

botってプログラミングかなり簡単なので、ちょっとしたゲームっぽいのくらいなら俺くらいの理解でも作れてしまいそうだな。

例えばRogueを例に取るなら、1時間に1Fずつフロアを降りていく。↑のランダム発言botを少しいじって、モンスターと遭遇するようにする。階層が深くなるに連れて現れるモンスターも増えて、HPがゼロになると死亡。地下何回まで行けるか、みたいな。

これだけだとゲーム性がないので、@発言でアイテムや武器、魔法を授けてやる。「@rogue_bot !」とかやると(Rogueでは!が水薬のシンボル)ランダムで傷が治ったり幻覚を見たりする。「@rogue_bot |」とかやれば、大きな剣(+2)が手に入ることもあれば、呪われた剣が手に入ることもあったりして。

……だったら普通にRogueやれよって話か。はい、仕事します。

追記

やっぱりサーバーサイドで実行してくれた方が嬉しい&Cronに登録したいので、

  • モジュールのインストールはXREAに断られた
  • ならメールで更新してやれ

という乱暴な発想により、TGMを利用してメールで投稿するように書き換えました。ソースは省略。文字コードいじってサブルーチン入れ替えただけだし。