Crea un semplice bot IRC.


10

Compito

Crea un semplice bot IRC che esegua compiti semplici come salutare l'utente.

Dettaglio

(Potresti vedere questo documento RFC .)

Scrivi un programma completo che esegua questi:

  1. Il programma inserisce nicknamee realnamedall'utente.

    • Tutto nicknamee realnamequale forma è [A-Za-z0-9]+dovrebbe essere consentito, ma non è importante se sono consentite altre forme. Ad esempio, se l'utente desidera 1234qwertycome nicknamee 5319009come realname, il programma dovrebbe usare quei nomi, ma non è importante se il programma può usare ^^☆Rick Astley☆^^(che include caratteri non alfabetici e decimali) come ( nicknameo realname) o meno, anche se questo nome potrebbe essere rifiutato dal server.
  2. Il programma immette serverAddressdall'utente.

    • La forma di serverAddressè serverIP:serverPort, dove si serverIPtrova l'indirizzo IP del server ed serverPortè il numero di porta del server.
  3. Il programma si collega alla porta serverPortsul server IRC serverIPe dovrebbe impostare il suo nickname come nicknamee il nome reale come realnameinviando USER realname 0 * :realnamee NICK nickname.

  4. Il programma inserisce un singolo channelNameche non include #e si unisce al canale #channelName.

  5. Invia un messaggio privato Hello, world!al #channelNamecanale in questo modo:PRIVMSG #channelName :Hello, world!

  6. Quindi, il programma esegue queste operazioni:

    A. Se qualcuno si unisce, salutandolo dicendo Hello, @!a #channelName, dove @ è il soprannome di lui / lei.

    B. Se il programma viene espulso, prova a riconnetterti.

    C. Se una persona viene cacciata o bandita, diciamo POW HAHA.

    D. Se una persona lascia ( PARTo QUIT), dire Goodbye, @!, dove @ è il soprannome di lui / lei.

    E. Se qualcuno dice del testo incluso Turing testo turing test, dì I'm a human!.

    F. Se qualcuno dice del testo incluso 6*9, esci inviando QUIT :42al server.

    G. Se qualcuno dice del testo incluso all your base are belong to us(senza distinzione tra maiuscole e minuscole), esci inviando QUIT :What you say!al server.

    H. Se qualcuno dice che un testo che precede uno spazio e sopra gli atti non viene eseguito dal testo, indica la somma del codice di tutti i caratteri (tranne il primo spazio) nel testo.

Se si è verificato un errore

Se si verifica un errore (come errore di connessione o non valido nickname), puoi fare quello che vuoi fare. Ad esempio, se nicknameè già in uso, il programma potrebbe arrestarsi, ricevere un nuovo nicknameutente o cambiare automaticamente nicknamee riprovare.

Restrizione

Il programma

  • Non utilizzare funzioni interne o librerie destinate alla creazione di client / bot IRC. cioè qualcosa come le librerie client IRC
  • Dovrebbe chiedere cosa verrà immesso, prima che ottenga un input . Ad esempio, prima di ingressi serverAddress, esso dovrebbe indurre Write the address of server:, serverIP:serverPort >, serverAddress >, o un certo testo che l'utente può riconoscere.
  • Dovrebbe funzionare su più server IRC usando UTF-8. (cioè non per singolo server)
  • I messaggi inviati al server non dovrebbero esserlo NOTICE. (RFC 2812, 3.3.2 Avviso: la differenza tra NOTICEe PRIVMSGè che le risposte automatiche NON DEVONO MAI essere inviate in risposta a un NOTICEmessaggio.)
  • Dovrebbe inviare un messaggio da dove proviene la richiesta ( #channelNameo nickname).
  • Dovrebbe PONGquando PINGed, ovviamente.

PS

Bene, l'ho appena fatto, perché non c'erano enigmi sul bot IRC.

modificare

Dopo aver letto il commento di @ dmckee, ho cambiato la regola per scegliere il vincitore.

  1. Predefinito bonus= +0

  2. Se in qualche modo il programma può connettersi a un canale (anche se non lo è #channelName), bonus= 1

  3. Se il programma può eseguire i passaggi 1 ~ 5, bonus* = 2.

  4. Per ogni attività A ~ H al punto 6, se il programma implementa, bonus* = 1.2.

  5. Per ogni sei restrizioni, se il programma lo segue, bonus* = 1.05.

e score = int(codelength/bonus).

Il programma con il punteggio più basso è il vincitore. Se due risposte hanno lo stesso punteggio, vince la risposta con il punteggio più alto.

Modifica EDIT: penso 1.2che 1.05al punto 4 e 5 dovrebbe essere regolato leggermente più grande .. Cosa ne pensi di questo?

Il vincitore è deciso, tuttavia, penso che ci fossero troppe poche voci.

Chiunque può ancora inviare il codice ..: P


4
Francamente non abbiamo accettato molto "Non c'è metrica, basta votare". . Ci sono cose con cui lavorare qui in termini di impostazione di una metrica oggettiva per questo compito. Vedere Messaggio di errore falso per un possibile esempio.
dmckee --- ex-moderatore gattino

@dmckee: Mi dispiace, non sapevo che i voti fossero abbastanza soggettivi .. :(
JiminP

@JiminP: bel salvataggio.
dmckee --- ex gattino moderatore

irc bot sembra un golf più lungo - ci sono io :)
lunixbochs

chiarimento: "Se il programma viene espulso, prova a riconnetterti." - significa dal server o dal canale?
lunixbochs

Risposte:


1

PHP - 121 punti

  • 1396 caratteri
  • Segui tutti i passaggi (inclusi quelli extra) e le restrizioni

Punto

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

Codice

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

Nota a margine

La mia risposta in realtà differisce leggermente dalle istruzioni; le istruzioni dicono di usare realnamecome primo parametro il USERcomando durante la registrazione, ma invece ho usato il soprannome. Questo perché realnameè consentito avere spazi, mentre questo parametro non lo è. È una specie di punto controverso, poiché passare alla variabile per realnamesarebbe esattamente lo stesso conteggio dei caratteri.


5

Python - 125 punti

  • 304 caratteri
  • segue i passaggi 1-5 (funziona per me su irc.freenode.net:6667. se ci provi, ricorda che IDENT potrebbe richiedere del tempo, quindi dai 20+ secondi per connetterti e parlare)
  • segue 4 restrizioni (presupponendo che la restrizione NOTICE sia un po 'poco chiara. La restrizione UTF conta perché python non si strozzerà se non è necessario analizzare alcun UTF).

punteggio matematica (pitone):

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

codice:

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 punti

  • 666 caratteri
  • tutti i passaggi secondari
  • metà delle restrizioni

Punto

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

Codice

(newline solo per presentazione, non conteggiato per non parlare accettabile)

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

Nota a margine

Il sottotitolo "TUTTI I TUOI BASE SONO APPARTENUTI A NOI" probabilmente non vale il suo conteggio dei personaggi, ma se lo avessi lasciato non avrei avuto il conteggio dei personaggi. Bugger.


+1 per 66 punti e 666 caratteri. È intenzionale o l'hai preso per caso?
nyuszika7h,

@nyuszika7h Sinceramente non ricordo.
JB,

2

Rubino, 28 punti

Punto

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

Codice

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

Rubino, 65 punti

  • 574 caratteri
  • Passaggi 1-5, 6 (AG) e restrizioni su librerie, UTF-8, no AVVISO e PONG
  • Prende args a riga di comando sotto forma di server: 6667 canale botuser botnick

Punto

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

Codice

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.