単純なIRCボットを作成します。


10

仕事

ユーザーへの挨拶のような単純なタスクを実行する単純なIRCボットを作成します。

細部

このRFC文書が表示される場合があります。)

これらを実行する完全なプログラムを作成します。

  1. プログラムの入力nicknamerealnameユーザーから。

    • すべてnicknamerealnameどのフォームを[A-Za-z0-9]+許可する必要がありますが、他のフォームを許可するかどうかは重要ではありません。たとえば、ユーザーが1234qwertyas nicknameおよび5319009asをrealname必要とする場合、プログラムはそれらの名前を使用する必要がありますが、プログラムが^^☆Rick Astley☆^^(非アルファベットと10進数を含む)を(nicknameまたはrealname)として使用できるかどうかは重要ではありません。サーバーによって。
  2. プログラムserverAddressはユーザーから入力します。

    • の形式はserverAddressですserverIP:serverPortserverIPはサーバーのIPアドレスで、はサーバーserverPortのポート番号です。
  3. プログラムはserverPortIRCサーバーのポートに接続しserverIP、とを送信することによりnickname、ニックネームを実名に設定する必要があります。realnameUSER realname 0 * :realnameNICK nickname

  4. プログラムはchannelNameを含まないシングルを入力#し、チャンネルに参加します#channelName

  5. 次のようにプライベートメッセージHello, world!#channelNameチャンネルに送信します。PRIVMSG #channelName :Hello, world!

  6. 次に、プログラムはこれらを実行します。

    A.誰かが参加する場合は、に言っHello, @!て挨拶し#channelNameます。ここで、@は彼/彼女のニックネームです。

    B.プログラムがキックされた場合は、再度参加してみてください。

    C.人がキックまたは禁止されている場合は、と言いPOW HAHAます。

    D.人が(PARTまたはQUIT)を去る場合は、と言いますGoodbye, @!。ここで、@はその人のニックネームです。

    E.誰かがTuring testまたはを含むテキストを言ったらturing test、と言いI'm a human!ます。

    F.誰かがを含むテキストを言った場合、サーバーに6*9送信QUIT :42して終了します。

    G.誰かがall your base are belong to us(大文字小文字を区別しない)を含むテキストを言った場合QUIT :What you say!、サーバーに送信して終了します。

    H.誰かがスペースの前にあるテキストとそれ以上の動作がテキストによって実行されないと言う場合、テキスト内のすべての(最初のスペースを除く)文字の文字コードの合計を言います。

エラーが発生した場合

エラー(接続エラーや無効などnickname)が発生した場合、必要な操作を実行できます。たとえば、nicknameがすでに使用されている場合、プログラムは停止するnicknameか、ユーザーから新しいものを取得するか、自動的にを変更しnicknameて再試行します。

制限

プログラム

  • IRCクライアント/ボット作成用の内部関数またはライブラリを使用しないでください。つまり、IRCクライアントライブラリのようなもの
  • 必要があり、それが入力を取得する前に、どのようなことは入力よプロンプト。たとえば、入力する前にserverAddress、それはプロンプトを表示する必要がありWrite the address of server:serverIP:serverPort >serverAddress >、いくつかのテキストまたはユーザーが認識できること。
  • UTF-8を使用する複数のIRCサーバーで動作するはずです。(つまり、単一サーバーではありません)
  • のサーバーに送信されるメッセージはであってはなりませんNOTICE。(RFC 2812、3.3.2注意:差NOTICEとは、PRIVMSG自動返信がに応答して送信されてはならないということであるNOTICEメッセージ)。
  • リクエスト元のメッセージを送信する必要があります(#channelNameまたはnickname)。
  • もちろんPONGPING編集する必要があります。

PS

まあ、私はこれを作っただけです。なぜならIRCボットについてのパズルがなかったからです。

編集する

@dmckeeのコメントを読んだ後、勝者を選ぶルールを変更しました。

  1. デフォルトbonus= +0

  2. 何らかの理由でプログラムがチャネルに接続できる場合(そうでない場合でも#channelName)、bonus= 1

  3. プログラムがステップ1から5を実行できる場合、bonus* = 2。

  4. ステップ6の各タスクA〜Hについて、プログラムが実装する場合、bonus* = 1.2

  5. 6つの制限ごとに、プログラムがそれに従っている場合、bonus* = 1.05

score = int(codelength/bonus)

最も低いスコアのプログラムが勝者です。2つの回答のスコアが同じ場合、投票数が最も多い回答が優先されます。

EDIT編集:私は思う1.2し、1.05ステップ4と5に大きめに調整する必要があります..あなたはこれについてどう思いますか?

勝者は決まっていますが、エントリーが少なすぎると思います。

だれでもまだコードを送信できます..:P


4
率直に言って、「測定基準はなく、投票するだけ」ということをあまり受け入れていません客観的な指標の設定に関して、ここで取り組むべきことがいくつかありますこのタスクのます。考えられる例については、偽のエラーメッセージをご覧ください。
dmckee ---元モデレーターの子猫

@dmckee:すみません、投票がかなり主観的であることを知りませんでした。:(
JiminP

@JiminP:いいセーブ。
dmckee ---元モデレーターの子猫

ircボットはより長いゴルフのように聞こえます-私はそうです:)
lunixbochs

説明:「プログラムがキックされた場合は、再度参加してみてください。」-これはサーバーまたはチャネルからのものですか?
lunixbochs

回答:


1

PHP-121ポイント

  • 1396文字
  • すべての手順(追加を含む)と制限に従います

スコア

<?php
$bonus = 1;                             //connects to channel
$bonus *= 2;                            //completes steps 1-5
for ($x=0;$x < 8;$x++) $bonus *= 1.2;   //all 8 extra steps
for ($y=0;$y < 6;$y++) $bonus *= 1.05;  //all 6 restrictions
echo (int)(1396 / $bonus);

> 121

コード

<?php function w($t){global$s;echo$t."\n";socket_write($s,$t."\r\n");}function m($c,$t){w("PRIVMSG $c :$t");}@$y=fgets;$z=STDIN;echo"nickname>";$n=trim($y($z));echo"realname>";$r=trim($y($z));echo"serverIP:Port>";$a=explode(":",trim($y($z)));$s=socket_create(2,1,6);socket_connect($s,$a[0],$a[1]);w("NICK $n");w("USER $n 0 * :$r");while(1){if((!($l=trim(socket_read($s,512,1))))||(!preg_match("/^(?:\:(\S+)[ ]+)?([^: ][^ ]*)(?:[ ]+([^:].*?))?(?:[ ]+:(.+))?$/",$l,$m)))continue;echo$l."\n";if(preg_match("/(.+)!(.+)@(.+)/",$m[1],$o))$m[1]=$o;if(!empty($m[3]))$p=explode(" ",$m[3]);else$p=array();if(isset($m[4])) $p[]=$m[4];$p=array($m[1],$m[2],$p);$b=$p[2][0];@$e=$p[0][1];@$f=$p[2][1];if($p[1]=="PING")w("PONG :".$b);elseif($p[1]=="376"){echo"#channel>";$c=trim($y($z));$c=(!empty($c))?$c:"#rintaun";w("JOIN $c");}elseif($p[1]=="JOIN")if($e!=$n)m($b,"Hello, $e!");else m($b,"Hello, world!");elseif($p[1]=="KICK")if($f!=$n)m($b,"POW HAHA");else w("JOIN ".$b);elseif(($p[1]=="PART")&&($e!=$n))m($b,"Goodbye, $e!");elseif(($p[1]=="QUIT")&&($e!=$n))m($c,"Goodbye, $e!");elseif($p[1]=="PRIVMSG")if(preg_match("/[Tt]uring test/",$f))m(($b==$n)?$e:$b,"I'm a human!");elseif(strstr($f,"6*9")){w("QUIT :42");break;}elseif(stristr($f,"all your base are belong to us")){w("QUIT :What you say!");break;}elseif($f[0]==" "){$q=str_split(substr($f,1));$u=0;foreach($q AS $d)$u+=ord($d);m(($b==$n)?$e:$b,$u);}}

サイドノート

私の答えは実際には指示とは少し異なります。説明書には、realnameUSER、登録時にコマンドの最初のパラメーターとしてれていますが、代わりにニックネームを使用しました。これはrealname、このパラメータでは許可されていないのにスペースを許可されているためです。ただし、変数forの切り替えrealnameはまったく同じ文字数になるため、これは重要な点です。


5

Python-125ポイント

  • 304文字
  • 手順1〜5に従います(irc.freenode.net:6667で私のために機能します。そこで試す場合、IDENTには時間がかかる可能性があるため、接続して話すのに20秒以上かかることを覚えておいてください)
  • 4つの制限に従います(少し不明確なNOTICE制限を想定しています。UTFを解析する必要がない場合、Pythonはチョークしないため、UTF制限が重要です)。

スコア計算(python):

bonus = 1 # connects to channel
bonus *= 2 # steps 1-5
for i in xrange(4):
    bonus *= 1.05 # 4 restrictions

int(304.0/bonus)
> 125

コード:

import socket
i=raw_input
u=i('user# ')
n=i('nick# ')
h,p=i('host:port# ').split(':',1)
p=int(p)
c='#'+i('chan# ')
z=0
while 1:
 try:
  def s(m): z.send(m+'\r\n')
  z.recv(9)
 except:
  z=socket.socket();z.connect((h,p));s('USER '+n+' 0 * :'+n);s('NICK '+n);s('JOIN '+c);s('PRIVMSG '+c+' :Hello, world!')

5

Perl、66ポイント

  • 666文字
  • すべてのサブステップ
  • 制限の半分

スコア

use 5.010;
$bonus = 1;              # connects to channel
$bonus *= 2;             # steps 1 to 5
$bonus *= 1.2 for 1..8;  # substeps A to H
$bonus *= 1.05 for 1..3; # restrictions 3, 4, 6
say int(666 / $bonus);
> 66

コード

(改行は表示のみで、許容範囲はもちろんのこと、カウントされません)

use POE"Component::IRC";$_='sub _start{Zregister,all);Z"connect")}subX001{
Zjoin=>$c);ZY"Hello, world!")}*Xquit=*Xpart=*Xjoin=sub{$g=$_[STATE]=~/t/?G
oodbye:Hello;$_=$_[ARG0];/\w+/;ZY"$g, $&!")};subXkick{$_=$_[ARG2];/\w+/;Z$
&eq$n?"join":Y"POW HAHA")}subXpublic{$_=$_[ARG2];if(/turing test/i){ZY"I\'
m a human!")}elsif(/6\*9/){Zquit,42)}elsif(/all your base are belong to us
/i){Zquit,"What you say!")}elsif(/^ /){$t=-32;$t+=ord for/./g;ZY$t)}}chop(
($n,$r,$s,$c)=<>);$c="#$c";$i=POE::Component::IRC->spawn(nick,$n,ircname,$
r,server,$s)';s/Z/\$i->yield(/g;s/Y/privmsg,\$c,/g;S/X/ irc_/g;eval;POE::S
ession->create(package_states,[main,[grep*$_{CODE},%::]]);POE::Kernel->run

サイドノート

「ALL YOUR BASE BE BELONG TO US」サブステップは、おそらくその文字数に見合う価値はありませんが、ドロップすると、素晴らしい文字数は得られません。バガー。


66ポイントおよび666文字の場合は+1。それは意図的なものですか、それとも偶然ですか?
nyuszika7h 14

@ nyuszika7h正直覚えてない。
JB

2

Ruby、28ポイント

  • 249文字
  • 私の他のソリューションと同じボットですが、圧縮を適用することにより、おそらく少し浮気します。
  • http://coolfire.insomnia247.nl/golfbot-inflate.rb(このコードを貼り付けてもおそらくうまく機能しないため)

スコア

bonus = 0       # We've done nothing yet
bonus += 1      # Connects to channel
bonus *= 2      # Step 1 - 5

for n in 1..7
    bonus *= 1.2    # A - G
end

for n in 1..4
    bonus *= 1.05   # 4 constraints
end

puts (249/bonus).to_i
>  28

コード

require 'zlib'
b=<<'E'
x�]�_o�0���)��q�-KFBcdf��߃�P�S�B�����(N�Л��s~�� ��(�_$U6��5G�)�r�BB������J�{��� nNhlO�f)QQdJ�g��'�yP�!!����K�ɫ��[Ё�Ə{0�F]ѽ�m�2���GŐP��p`   ��I����E�+�* z�                                                                                                                                                           )jrmKR�ˮ�%�
#��nQaJ�H��<�ZT���虦T3.�$D('�hw��a�/'��&�_ei�}o��1���M$����H��J�$��������V"���"��'��|A�`<��3L)Y��Z|� e�� ���m�é��ǚ�ڎu��J�����Vq~(ح�
E
eval Zlib::Inflate.new.inflate b

2

ルビー、65点

  • 574文字
  • 手順1〜5、6(AG)およびライブラリの制限、UTF-8、通知なし&ポン
  • コマンドライン引数をserver:6667ボットニックボットユーザーチャネルの形式で取得します

スコア

bonus = 0       # We've done nothing yet
bonus += 1      # Connects to channel
bonus *= 2      # Step 1 - 5

for n in 1..7
    bonus *= 1.2    # A - G
end

for n in 1..4
    bonus *= 1.05   # 4 constraints
end

puts (574/bonus).to_i
> 65

コード

require'socket'
a=ARGV
c="##{a[3]}"
h,p=a[0].split':'
s=TCPSocket.open(h,p)
m="PRIVMSG #{c} :"
s.puts"USER #{a[2]} 0 * :#{a[2]}\nNICK #{a[1]}\nJOIN #{c}\n#{m}Hello, world!"
while l=s.gets
case l
when/\:(.+?)!(.+)JOIN/
s.puts"#{m}Hello, #{$1}!"
when/KICK (.+?) (.+?) \:(.+)/
if $2==a[1]
s.puts"JOIN #{c}"
else
s.puts"#{m}POW HAHA"
end
when/\:(.+?)\!(.+)(PART|QUIT)/
s.puts"#{m}Goodbye, #{$1}!"
when/turing test/i
s.puts"#{m}I'm a human!"
when/6\*9/
s.puts"QUIT :42"
when/all your base are belong to us/i
s.puts"QUIT :What you say!"
when/PING \:(.+)/
puts"PONG #{$1}"
end
end
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.