Зробіть простий бот 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, де @ це прізвисько йому / їй.

    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 >або який - небудь текст , який користувач може розпізнати.
  • Потрібно працювати на декількох серверах 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).

Перемагає програма з найнижчою оцінкою Якщо дві відповіді мають однаковий бал, то виграє відповідь з найвищими голосами.

EDIT Edit: Я думаю, 1.2і 1.05на кроках 4 і 5 слід відкоригувати трохи більше .. Що ви думаєте з цього приводу?

Переможець вирішується, однак, я думаю, що заявок було замало.

Кожен все ще може подати код ..: P


4
Відверто кажучи, ми не дуже сприймали "Немає метрики, просто голосуй". . Тут ви маєте з вами працювати з точки зору встановлення об'єктивної метрики для цього завдання. Дивіться підроблене повідомлення про помилку для можливого прикладу.
dmckee --- кошеня колишнього модератора

@dmckee: Вибачте, я не знав, що голоси були досить суб'єктивними .. :(
JiminP

@JiminP: Приємне збереження.
dmckee --- кошеня колишнього модератора

irc bot звучить як довший гольф - я все-таки :)
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);}}

Бічна примітка

Моя відповідь насправді дуже відрізняється від інструкцій; інструкція говорить про те, щоб використовувати realnameяк перший параметр USERкоманди при реєстрації, але я використав псевдонім. Це пов’язано з тим, що у realnameдозволеному проміжку є пробіли, а цей параметр - ні. Це щось із суперечливих моментів, оскільки перехід у змінну для realnameбуде таким самим числом символів.


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!')

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

Бічна примітка

Підзаступник "ВСІ ВАША БАЗА БУДЕ НАС", швидше за все, не варто рахувати його персонажів, але якби я кинув його, у мене не було б приємного рахунку персонажів. Баггер.


+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, відсутні ПОВІДОМЛЕННЯ та ПОНГ
  • Приймає аргументи командного рядка у вигляді сервера: 6667 ботнік-каналу botuser

Оцінка

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.