Сделай простого IRC бота.

10

задача

Сделайте простого IRC-бота, который выполняет простую задачу, например, приветствует пользователя.

подробность

(Вы можете увидеть этот документ RFC .)

Напишите полную программу, которая выполняет эти:

  1. Программа ввода nicknameи realnameот пользователя.

    • Все nicknameи realnameкакая форма [A-Za-z0-9]+должна быть разрешена, но не важно, разрешены ли другие формы. Например, если пользователь хочет, 1234qwertyкак nicknameи 5319009как realname, программа должна использовать эти имена, но не важно, может ли программа использовать ^^☆Rick Astley☆^^(которая включает в себя не алфавит и десятичные дроби) как ( nicknameили realname) или нет, даже если бы это имя могло быть отклонено на сервере.
  2. Программа ввода serverAddressот пользователя.

    • Форма serverAddress: serverIP:serverPortгде serverIPIP-адрес сервера и serverPortномер порта сервера.
  3. Программа подключается к порту serverPortна IRC-сервере serverIP, и ей следует установить псевдоним как nicknameи реальное имя realname, отправив USER realname 0 * :realnameи NICK nickname.

  4. Программа вводит сингл, channelNameкоторый не включает #, и присоединяется к каналу #channelName.

  5. Отправить личное сообщение Hello, world!на #channelNameканал, как это:PRIVMSG #channelName :Hello, world!

  6. Затем программа делает это:

    A. Если кто - то присоединяется, приветствуя его, говоря , Hello, @!чтобы #channelName, где @ это прозвище ему / ей.

    Б. Если программа запущена, попробуйте снова присоединиться.

    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. Если кто-то говорит, что какой-то текст, предшествующий пробелу и выше, не выполняется в тексте, произнесите сумму charcode всех (кроме первого пробела) символов в тексте.

Если произошла ошибка

Если произошла ошибка (например, ошибка подключения или неверная nickname), вы можете делать то, что хотите. Например, если nicknameон уже используется, программа может остановиться, получить новое nicknameот пользователя или автоматически изменить nicknameи повторить попытку.

ограничение

Программа

  • Не следует использовать какие-либо внутренние функции или библиотеки для IRC-клиентов / ботов. то есть что-то вроде клиентских библиотек IRC
  • Должен подсказать, что он будет вводить, прежде чем получит ввод . Например, перед входами serverAddress, он должен подсказать Write the address of server:, serverIP:serverPort >, serverAddress >или какой - нибудь текст , который пользователь может распознать.
  • Должен работать на нескольких IRC-серверах с использованием UTF-8. (т.е. не для одного сервера)
  • сообщений отправлять на сервер не следует NOTICE. (RFC 2812, 3.3.2 Примечание. Разница между NOTICEи PRIVMSGзаключается в том, что автоматические ответы НЕ ДОЛЖНЫ отправляться в ответ на NOTICEсообщение.)
  • Следует отправить сообщение, откуда поступил запрос ( #channelNameили nickname).
  • Должен, PONGкогда PINGед, конечно.

PS

Ну, я только что сделал это, потому что не было загадки о боте IRC.

редактировать

Прочитав комментарий @ dmckee, я изменил правило выбора победителя.

  1. По умолчанию bonus= +0

  2. Если каким-то образом программа может подключиться к каналу (даже если это не так #channelName), bonus= 1

  3. Если программа может выполнить шаги 1 ~ 5, bonus* = 2.

  4. Для каждой задачи A ~ H на шаге 6, если программа реализует, bonus* = 1.2.

  5. Для каждых шести ограничений, если программа следует этому, bonus* = 1.05.

и score = int(codelength/bonus).

Программа с наименьшим количеством баллов является победителем. Если два ответа имеют одинаковую оценку, то выигрывает ответ с наибольшим количеством голосов.

РЕДАКТИРОВАТЬ Редактировать: Я думаю, 1.2и 1.05в шаге 4 и 5 должны быть скорректированы немного больше .. Что вы думаете об этом?

Победитель определен, однако, я думаю, что было слишком мало заявок.

Кто-нибудь еще может отправить код ..: P

JiminP
источник
4
Честно говоря, мы не очень принимаем «Нет метрики, просто голосуй». , Здесь есть вещи для работы с точки зрения установки объективной метрики для этой задачи. Смотрите Поддельное сообщение об ошибке для возможного примера.
dmckee --- котенок экс-модератора
@dmckee: Извините, я не знал, что голоса были весьма субъективными .. :(
JiminP
@JiminP: приятно сохранить.
dmckee --- котенок экс-модератора
irc bot звучит как длинный гольф - я в
игре
уточнение: «Если программа запущена, попробуйте снова присоединиться». - это значит с сервера или канала?
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);}}

Примечание

Мой ответ на самом деле немного отличается от инструкции; В инструкциях говорится, realnameчто USERпри регистрации в качестве первого параметра команды следует использовать команду, но вместо этого я использовал псевдоним. Это потому, что realnameразрешено иметь пробелы, а этот параметр - нет. Тем не менее, это спорный вопрос, поскольку переключение переменной для realnameбудет таким же количеством символов.

rintaun
источник
5

Питон - 125 очков

  • 304 символа
  • выполняет шаги 1-5 (у меня работает на irc.freenode.net:6667. если вы попробуете там, помните, что IDENT может занять некоторое время, поэтому дайте ему более 20 секунд для подключения и разговора)
  • следует 4 ограничениям (при условии, что ограничение NOTICE немного неясно. Ограничение UTF считается, потому что python не захлебнется, если ему не потребуется анализировать UTF).

оценка математики (питона):

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!')
lunixbochs
источник
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

Примечание

Подэтап «ВСЕ ВАШЕ ОСНОВАНИЕ ДОЛЖНЫ НАМ», скорее всего, не стоит подсчета персонажей, но если бы я его отбросил, у меня не было бы хорошего количества персонажей. Мудак.

JB
источник
+1 за 66 очков и 666 символов. Это умышленно или случайно?
nyuszika7h
@ nyuszika7h Честно говоря, не помню.
JB
2

Рубин, 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, нет NOTICE & PONG
  • Принимает аргументы командной строки в виде сервера: 6667 botnick botuser channel

Гол

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
прохладный огонь
источник