[SOLUTION] Ducksay (#52)

R

Ryan Leavengood

This was quite fun. I decided not to go into ASCII art creation and
"cheated" by getting some wacky animals from http://www.ascii-art.de,
including several ducks. As noted in the source I developed this on a
Windows machine which does not have fortune (at least without getting
Cygwin, etc.), so I found a CGI script online which has fortune, and I
use open-uri to access it.

I'm sure my "bubble maker" could be golfed down a bit, but I preferred
clarity over terseness.

All the animals in the "zoo" are embedded in the DATA section of the
script, with a special format to delimit them. It is fairly easy to
add new animals should one want to.

I also used a different style of command-line options, since it fit
this problem. Here is an example run:

C:\_Ryan\ruby\quiz\52_ducksay>ruby ducksay.rb gecko.say "Ruby Rocks!"
_____________
< Ruby Rocks! >
-------------
\
\
___
)/_ ,@ /
|(_,' _@/
| /
\)/ / (_)/
((_/ ,----~
\ (_)/
/ ,-----~
((' _,-.
\\=3D//

The text after my name will be the code for my solution.

Ryan

require 'open-uri'
require 'singleton'

# Here we have a bubble machine
class Bubble
def self.make(text)
return '' if text.nil? or text =3D=3D ''
result =3D ''
lines =3D text.split("\n")
max_length =3D lines.max{|a,b| a.length <=3D> b.length}.length
hf =3D proc {|s| " #{s * (max_length+2)} \n"}
result << hf['_']
case lines.length
when 1: result << "< #{lines[0]} >\n"
else
pad_it =3D proc {|s| s.ljust(max_length)}
result << "/ #{pad_it[lines.shift]} \\\n"
0.upto(lines.length-2) do |i|
result << "| #{pad_it[lines]} |\n"
end
result << "\\ #{pad_it[lines[-1]]} /\n"
end
result << hf['-']
end
end

# Our lovely Zoo, full of many wacky animals
class Zoo
include Singleton
attr_reader :animals
def initialize
@animals =3D {}
current_key =3D nil
DATA.each do |line|
if line.chomp =3D~ /^'(\w*)':$/
current_key =3D $1
@animals[current_key] =3D []
elsif current_key
@animals[current_key] << line
end
end
end

# A random animal has escaped!
def escape
choices =3D @animals.keys
@animals[choices[rand(choices.length)]]
end
end

# Since I wrote this on Windows I don't have fortune...but the
# internet does!
def get_fortune
open('http://www.coe.neu.edu/cgi-bin/fortune') do |page|
page.read.scan(/<pre>(.*)<\/pre>/m)[0][0].gsub("\t",' ')
end
end

if $0 =3D=3D __FILE__
animal =3D nil
message =3D nil
case ARGV[0]
when 'list':
puts "Your zoo contains the following animals:"
puts Zoo.instance.animals.keys.sort.join("\n")
exit(0)
when /\A(\w*)\.say/:
animal =3D Zoo.instance.animals[$1]
unless animal
puts "Unknown animal #$1! Try 'list' to list your animals."
exit(1)
end
if ARGV.length > 1
message =3D ARGV[1..-1].join(" ")
end
when nil:
animal =3D Zoo.instance.escape
else
puts "Usage: #$0 <command>",
"Where command is",
"\tlist: to list your animals.",
"\t<animal>.say \"<message>\": to have that animal say that",
"\t\tmessage, where the message is optional.",
"\nWith no command the default is a random animal, with a",
"message from fortune."
exit(1)
end
unless message
message =3D get_fortune
end
puts Bubble.make(message)
puts animal
end

# The ASCII animals below are courtesy of http://www.ascii-art.de
__END__
'crazyduck':
\ _____
\ \\_-~~ ~~-_
\ /~ ~\
\ _| _ |
\ ___) ~~) ~~~--_ |
\ _-~ ~-_ ___ \ |/
\ / _-~ ~-_ /
\ | / \ |
\ | O) | | |
| | | |
| | (O | |
\ | | |\
(~-_ _-\ / _--_ / \
\__~~~ ~-_ _-~ / ~\
/ ~---~~-_ ~~~ _-~ /| |
_-~ / \ ~~--~ | | |
_-~ | / |
,-~~-_ __--~~ |-~ /
| \ | _-~
\ |--~~
\ | |
~-_ _ | |
~-_ ~~---__ _--~~\ |
~~--__ / |
~~---___ __--~~| |
~~~~~ | |
| |
'lazyduck':
\
\ .-"""-. _.---..-;
:.) ;"" \/
__..--'\ ;-"""-. ;._
`-.___.^.___.'-.____J__/-._J
'duck':
\
\ _.-.
__.-' , \
'--'-'._ \
'. \
)-- \ __.--._
/ .' '--.
. _/-._
: ____._/ _-'
'._ _.'-'
'-._ _.'
\_|/
__|||
'chunkybacon':
\
\ __ _.._
.-'__`-._.'.--.'.__.,
/--' '-._.' '-._./
/__.--._.--._.'``-.__/
'._.-'-._.-._.-''-..'
'raccoon':
\
\ __ .-.
\ .-"` .`'. /\\|
_(\-/)_" , . ,\ /\\\/
{(#b^d#)} . ./, |/\\\/
`-.(Y).-` , | , |\.-`
/~/,_/~~~\,__.-`
////~ // ~\\
=3D=3D`=3D=3D` =3D=3D` =3D=3D`
'bat':
\
\
, \ ,
./( )\.
) \/\_/\/ (
`) (^Y^) (`
`),-(~)-,(`
'"'
'buffalo':
\
\ _.-````'-,_
_,.,_ ,-'` `'-.,_
/) (\ '``-.
(( ) ) `\
\) (_/ )\
| /) ' ,' / \
`\ ^' ' ( / ))
| _/\ , / ,,`\ ( "`
\Y, | \ \ | ````| / \_ \
`)_/ \ \ ) ( > ( >
\( \( |/ |/
/_(/_( /_( /_(
'gecko':
\
\
___
)/_ ,@ /
|(_,' _@/
| /
\)/ / (_)/
((_/ ,----~
\ (_)/
/ ,-----~
((' _,-.
\\=3D//
'gorilla':
\
\
\ ."`".
.-./ _=3D_ \.-.
{ (,(oYo),) }}
{{ | " |} }
{ { \(---)/ }}
{{ }'-=3D-'{ } }
{ { }._:_.{ }}
{{ } -:- { } }
{_{ }`=3D=3D=3D`{ _}
((((\) (/))))
'gryphon':
\ ______
\ ______,---'__,---'
\ _,-'---_---__,---'
/_ (, ---____',
/ ',, `, ,-'
;/) ,',,_/,'
| /\ ,.'//\
`-` \ ,,' `.
`', ,-- `.
'/ / | `, _
//'',.\_ .\\ ,{=3D=3D>-
__// __;_`- \ `;.__,;'
((,--,) (((,------; `--'
``` ' ```
'wombat':
\ ,.--""""--.._
\ ." .' `-.
\ ; ; ;
\ ' ; )
\ / ' . ;
/ ; `. `;
,.' : . : )
;|\' : `./|) \ ;/
;| \" -,- "-./ |; ).;
/\/ \/ );
: \ ;
: _ _ ; )
`. \;\ /;/ ; /
! : : ,/ ;
(`. : _ : ,/"" ;
\\\`"^" ` : ;
( )
////
'seaturtle':
/
/ _,.---.---.---.--.._
/ _.-' `--.`---.`---'-. _,`--.._
/ /`--._ .'. `. `,`-.`-._\
|| \ `.`---.__`__..-`. ,'`-._/
_ ,`\ `-._\ \ `. `_.-`-._,``-.
,` `-_ \/ `-.`--.\ _\_.-'\__.-`-.`-._`.
(_.o> ,--. `._/'--.-`,--` \_.-' \`-._ \
`---' `._ `---._/__,----` `-. `-\
/_, , _..-' `-._\
\_, \/ ._(
\_, \/ ._\
`._,\/ ._\
`._// ./`-._
`-._-_-_.-'
'lemur':
\ ,,
\ =3D=3D
\ =3D=3D
\ =3D=3D
\ =3D=3D
=3D=3D =3D=3D
=3D=3D =3D=3D =3D=3D
=3D=3D =3D=3D
, , =3D=3D
|\/| ,-..-,
,d__(..)\_/ \
;-,_`o/ |
'-| \_,' /^| /
( // / \ \
|| \ < \ )
_\| \ ) _\\
~` _\| ~`
~`
'koala':
\
\ ) ( |
\ ) ( / .-
_ ,---. _ ( / /
(~-| . . |-~) V /
\._ 0 _,/ /
/ `-^-'`-._ /
' `-. (
: )E
: ,---' (
. )E (
'._____,---' (
) (
) (
) (
) (
'armadillo':
\
\ __-----.,
.-:::,\\\\\::::,
\|\;`:::`` \\\\\\\'':\
/`'\\:: |||||| '\
/ e (\` |||||| , '.
.` _.-`~\_____/`````_X__/'-__~=3D=3D=3D-
'-~` ~~ ~~
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top