Basit bir IRC botu oluşturun.


10

Görev

Kullanıcı tebrik gibi basit bir görev yapan basit bir IRC bot olun.

detay

( Bu RFC belgesini görebilirsiniz .)

Bunları gerçekleştiren eksiksiz bir program yazın:

  1. Program girdileri nicknameve realnamekullanıcıdan.

    • Herkese nicknameve realnamehangi forma [A-Za-z0-9]+izin verilir, ancak diğer formlara izin verilip verilmeyeceği önemli değildir. Örneğin, kullanıcı isterse 1234qwertyolarak nicknameve 5319009sıra realnameprogram bu isimleri kullanmak gerekir, ancak programın kullanıp kullanamayacağını önemli değildir ^^☆Rick Astley☆^^olarak (non-alfabe & ondalık sayılar içerir) ( nicknameveya realname) ya da değil, hatta bu isim reddedilebilir düşünce sunucu tarafından.
  2. Program serverAddresskullanıcıdan girer .

    • Formu serverAddressDİR serverIP:serverPort, nerede serverIPsunucunun IP adresidir ve serverPortsunucunun port num olduğunu.
  3. Portuna programı bağlanacağı serverPortIRC sunucusunda serverIPve 's takma ad olarak belirlesin nicknameolarak ve gerçek adı realnamegöndererek USER realname 0 * :realnameve NICK nickname.

  4. Program , kanala channelNamedahil olmayan #ve kanala katılan tek bir girdi girer #channelName.

  5. Kanala böyle özel bir mesaj Hello, world!gönderin #channelName:PRIVMSG #channelName :Hello, world!

  6. Sonra program bunları yapar:

    A. birisi söyleyerek onu tebrik katılırsa Hello, @!için #channelName, nereye @ onu / onu takma adıdır.

    B. Program başlatılırsa, tekrar katılmayı deneyin.

    C. Bir kişi vurulursa veya yasaklanırsa, deyin POW HAHA.

    D. Eğer bir kişi bırakırsa ( PARTya da QUIT), diyelim ki Goodbye, @!, @ onun takma adıdır.

    E. Birisi Turing testveya dahil bazı metinler turing testsöylerse I'm a human!.

    F. Birisi dahil bazı metinler söylerse , sunucuya 6*9göndererek çıkın QUIT :42.

    G. Birisi all your base are belong to us(büyük / küçük harf duyarlı) dahil bazı metinler söylerse QUIT :What you say!, sunucuya göndererek çıkın .

    H. Birisi boşluktan önce ve yukarıdaki eylemlerden bazılarının metin tarafından gerçekleştirilmediğini söylüyorsa, metindeki tüm (ilk boşluk hariç) karakterlerin charcode toplamını söyleyin.

Bir hata oluşursa

Bir hata oluşursa (bağlantı hatası veya geçersiz nickname), ne yapmak istediğinizi yapabilirsiniz. Örneğin nickname, zaten kullanımda ise program durabilir, nicknamekullanıcıdan yeni bir bilgi alabilir veya otomatik olarak değiştirip nicknameyeniden deneyebilir.

kısıtlama

Program

  • IRC istemci / bot yapımı için herhangi bir dahili fonksiyon veya kütüphane kullanmamalıdır. IRC istemci kitaplıkları gibi bir şey
  • Meli bir giriş girmeden önce ne girdi olacak, istemi . Örneğin, girdilerin önce serverAddress, bu istemi gerekir Write the address of server:, serverIP:serverPort >, serverAddress >, bazı metin veya kullanıcı tanıyabileceği.
  • UTF-8 kullanan birkaç IRC sunucusunda çalışmalıdır. (yani tek sunucu için değil)
  • adlı kullanıcının sunucuya gönderdiği iletiler olmamalıdır NOTICE. (RFC 2812, 3.3.2 Uyarı: NOTICEve arasındaki fark PRIVMSG, otomatik yanıtların bir NOTICEmesaja yanıt olarak ASLA gönderilmemesidir .)
  • İsteğin nereden geldiğini ( #channelNameveya nickname) bir mesaj göndermelidir .
  • Should PONGzaman PINGtabii ki, ed.

PS

Bunu yaptım, çünkü IRC botu hakkında bir bulmaca yoktu.

Düzenle

@ Dmckee'nin yorumunu okuduktan sonra kazanan seçme kuralını değiştirdim.

  1. Varsayılan bonus= +0

  2. Program bir şekilde bir kanala bağlanabiliyorsa (olmasa bile #channelName), bonus= 1

  3. Program 1 ~ 5 adımlarını gerçekleştirebiliyorsa, bonus* = 2.

  4. Her görev için 6. adımda A ~ H, program uygulanırsa, bonus* = 1.2.

  5. Her altı kısıtlama için, program bunu takip ederse, bonus* = 1.05.

ve score = int(codelength/bonus).

En düşük puana sahip program kazanır. İki cevap aynı puana sahipse, en yüksek oyu alan cevap kazanır.

EDIT Edit: Bence 1.2ve 1.05adım 4 ve 5 biraz daha büyük ayarlanmalıdır .. Bu konuda ne düşünüyorsun?

Kazanan karar verilir, ancak çok az giriş olduğunu düşünüyorum.

Yine de herkes kodu gönderebilir ..: P


4
Açıkçası "Metrik yok, sadece oy ver" i çok kabul etmedik . . Bu görev için objektif bir metrik oluşturmak açısından burada çalışmanız gereken şeyler var . Olası bir örnek için bkz. Sahte hata mesajı .
dmckee --- eski moderatör kedi yavrusu

@dmckee: Üzgünüm, oyların oldukça öznel olduğunu bilmiyordum .. :(
JiminP

@JiminP: Güzel tasarruf.
dmckee --- eski moderatör kedi yavrusu

irc bot daha uzun bir golf gibi geliyor - Ben de var :)
lunixbochs

açıklama: "Program başlatılırsa, tekrar katılmayı deneyin." - bu sunucudan mı yoksa kanaldan mı geliyor?
lunixbochs

Yanıtlar:


1

PHP - 121 puan

  • 1396 karakter
  • Tüm adımları (ekstralar dahil) ve kısıtlamaları takip eder

Puan

<?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

kod

<?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);}}

Kenar notu

Cevabım aslında talimatlardan biraz farklı; talimatlar , kayıt realnamesırasında USERkomutun ilk parametresi olarak kullanıldığını söylüyor , ancak bunun yerine takma adı kullandım. Bunun nedeni, realnamebu parametrenin olmamasına rağmen, boşluklara izin verilmesidir. Bununla birlikte, tartışmalı bir şey, çünkü değişkenin değiştirilmesi realnameaynı karakter sayımı olacaktır.


5

Python - 125 puan

  • 304 karakter
  • 1-5 arasındaki adımları izler (irc.freenode.net:6667'de benim için çalışır. orada denerseniz, IDENT'in biraz zaman alabileceğini unutmayın, bu yüzden bağlanmak ve konuşmak için 20+ saniye verin)
  • 4 kısıtlama uygular (Biraz belirsiz olan BİLDİRİM kısıtlamasının var olduğunu varsayarsak. UTF kısıtlaması dikkate alınır, çünkü herhangi bir UTF ayrıştırılması gerekmiyorsa python boğulmaz.

puan matematik (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

kod:

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 puan

  • 666 karakter
  • tüm alt adımlar
  • kısıtlamaların yarısı

Puan

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

kod

(yalnızca sunum için yeni satırlar, kabul edilebilir sayılmaz)

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

Kenar notu

"TÜM TABANINIZ BİZİMLE İLGİLİ" alt bölümü büyük olasılıkla karakter sayısına değmez, ancak düşürdüysem güzel karakter sayımı olmazdı. Kahretsin.


66 puan ve 666 karakter için +1. Bu kasıtlı mı yoksa kazara mı aldın?
nyuszika7h

@ nyuszika7h Dürüst olmak gerekirse hatırlamıyorum.
JB

2

Ruby, 28 puan

Puan

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

kod

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

Ruby, 65 puan

  • 574 Karakter
  • 1-5, 6 (AG) adımları ve kütüphaneler üzerindeki kısıtlamalar, UTF-8, NOT & PONG yok
  • Komut satırı bağımsız değişkenlerini sunucu şeklinde alır: 6667 botnick botuser kanalı

Puan

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

kod

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.