開発環境
- OS X Lion - Apple(OS)
- BBEdit - Bare Bones Software, Inc.(Text Editor)
- Script言語:Ruby
『初めてのプログラミング 第2版』(Chris Pine 著、長尾 高弘 訳、オライリー・ジャパン、2010年、ISBN978-4-87311-469-9)の 13章(新しいクラスの作成と既存のクラスの変更), 13.6(練習問題の続き)対話的ベビードラゴン を解いてみる。
その他参考書籍
- 『プログラミング言語 Ruby』David Flanagan, まつもと ゆきひろ 著 、卜部 昌平 監訳、長尾 高弘 訳、オライリー・ジャパン、2009年、ISBN978-4-87311-394-4)
- Rubyクックブック ―エキスパートのための応用レシピ集
対話的ベビードラゴン
コード(BBEdit)
sample.rb
#!/usr/bin/env ruby1.9
#-*- coding: utf-8 -*-
class Dragon
def initialize name
@name = name
@asleep = false
@stuff_in_belly = 10
@stuff_in_intestine = 0
puts "#{@name}が生まれました"
end
def feed
puts "#{@name}にご飯をあげます。"
@stuff_in_belly = 10
passage_of_time
end
def walk
puts "#{@name}をトイレに連れていきます"
@stuff_in_intestine = 0
passage_of_time
end
def put_to_bed
puts "#{@name}を寝かしつけます。"
@asleep = true
3.times do
if @asleep
passage_of_time
end
if @asleep
puts "#{@name}がいびきをかいて、部屋が煙だらけです。"
end
end
if @asleep
@asleep = false
puts "#{@name}はゆっくり目覚めます。"
end
end
def toss
puts "#{@name}に高い高いをします。"
puts "#{@name}が笑ってあなたの眉毛が焦げます。"
passage_of_time
end
def rock
puts "#{@name}をやさしくあやします。"
@asleep = true
puts "#{@name}は少し居眠りをします。"
passage_of_time
if @asleep
@asleep = false
puts "しかし、やめると起きてしまいます。"
end
end
private
def hungry?
@stuff_in_belly <= 2
end
def poopy?
@stuff_in_intestine >= 8
end
def passage_of_time
if @stuff_in_belly > 0
@stuff_in_belly -= 1
@stuff_in_intestine += 1
else
if @asleep
@asleep = false
puts "#{@name}が突然目を覚まします!"
end
puts "#{@name}がお腹を空かせています。我慢できなくてあなたを食べました。"
exit
end
if @stuff_in_intestine >= 10
@stuff_in_intestine = 0
puts "うわっ、#{@name}がおもらしを・・・・・・"
end
if hungry?
if @asleep
@asleep = false
puts "#{@name}が突然目を覚まします!"
end
puts "#{@name}のお腹が鳴っています。"
end
if poopy?
if @asleep
@asleep = false
puts "#{@name}が突然目を覚まします!"
end
puts "#{@name}がうんちのためにしゃがみ込みます。"
end
end
end
print "名前を入力: "
name = gets.chomp
name = "匿名" if name =~ /^\s*$/
pet = Dragon.new name
while true
print "コマンド(f/w/p/t/r)を入力(空白で終了): "
command = gets.chomp
break if command =~ /^\s*$/
case command
when 'f' then pet.feed
when 'w' then pet.walk
when 'p' then pet.put_to_bed
when 't' then pet.toss
when 'r' then pet.rock
else puts "コマンドを確認してください。"
end
end
入出力結果(Terminal)
$ ./sample.rb 名前を入力: ノーバート ノーバートが生まれました コマンド(f/w/p/t/r)を入力(空白で終了): f ノーバートにご飯をあげます。 コマンド(f/w/p/t/r)を入力(空白で終了): t ノーバートに高い高いをします。 ノーバートが笑ってあなたの眉毛が焦げます。 コマンド(f/w/p/t/r)を入力(空白で終了): w ノーバートをトイレに連れていきます コマンド(f/w/p/t/r)を入力(空白で終了): p ノーバートを寝かしつけます。 ノーバートがいびきをかいて、部屋が煙だらけです。 ノーバートがいびきをかいて、部屋が煙だらけです。 ノーバートがいびきをかいて、部屋が煙だらけです。 ノーバートはゆっくり目覚めます。 コマンド(f/w/p/t/r)を入力(空白で終了): r ノーバートをやさしくあやします。 ノーバートは少し居眠りをします。 しかし、やめると起きてしまいます。 コマンド(f/w/p/t/r)を入力(空白で終了): p ノーバートを寝かしつけます。 ノーバートが突然目を覚まします! ノーバートのお腹が鳴っています。 コマンド(f/w/p/t/r)を入力(空白で終了): p ノーバートを寝かしつけます。 ノーバートが突然目を覚まします! ノーバートのお腹が鳴っています。 コマンド(f/w/p/t/r)を入力(空白で終了): p ノーバートを寝かしつけます。 ノーバートが突然目を覚まします! ノーバートのお腹が鳴っています。 ノーバートがうんちのためにしゃがみ込みます。 コマンド(f/w/p/t/r)を入力(空白で終了): p ノーバートを寝かしつけます。 ノーバートが突然目を覚まします! ノーバートがお腹を空かせています。我慢できなくてあなたを食べました。 $
ちなみにJavaScriptの場合。
コード(BBEdit)
<pre id='pre0' ></pre>
<label id="name_label">名前を入力: <input id="dragon_name" type="text" value="ノーバート" /></label>
<input id="dragon_named" type="button" value="決定!" />
<div id="d0"></div>
<script>
var Dragon = function( name ) {
var name = name,
asleep = false,
belly = 10,
intestine = 0;
hungry = function() {
return belly <= 2;
},
poppy = function( ) {
return intestine >= 8;
},
passageOfTime = function( ) {
if (belly > 0) {
belly -= 1;
intestine += 1;
} else {
if (asleep) {
asleep = false;
$('#pre0').append(name + "が突然目を覚まします!\n");
}
$('#pre0').append(name + "がお腹をすかせています。" +
"我慢できなくてあなたを食べました。");
$('#command').remove();
$('#commanded').remove();
return;
}
if (intestine >= 10) {
intestine = 0;
$('#pre0').append("うわっ、" + name + "がおもらしを・・・・・・\n");
}
if (hungry()) {
if (asleep) {
asleep = false
$('#pre0').append(name + "が突然目を覚まします!\n");
}
$('#pre0').append(name + "のお腹が鳴っています。\n");
}
if(poppy()){
if (asleep) {
asleep = false;
$('#pre0').append(name + "が突然目を覚まします!\n");
}
$('#pre0').append(name + "がうんちのためにしゃがみ込みます。\n");
}
};
this.feed = function( ) {
$('#pre0').append(name + "にご飯をあげます。\n");
belly = 10;
passageOfTime();
},
this.walk = function( ) {
$('#pre0').append(name + "をトイレに連れていきます。\n");
intestine = 0;
passageOfTime();
},
this.putToBed = function( ) {
$('#pre0').append(name + "を寝かしつけます。\n");
asleep = true
for (i = 0, max = 3; i < max; i += 1) {
if (asleep) {
passageOfTime();
}
if (asleep) {
$('#pre0').append(name + "がいびきをかいて、部屋が煙だらけです。\n");
}
}
if (asleep) {
asleep = false;
$('#pre0').append(name + "はゆっくり目覚めます。\n");
}
}
this.toss = function( ) {
$('#pre0').append(name + "が高い高いをします。\n");
$('#pre0').append(name + "が笑ってあなたの眉毛が焦げます。\n");
passageOfTime();
}
this.rock = function( ) {
$('#pre0').append(name + "をやさしくあやします。\n");
asleep = true;
$('#pre0').append(name + "は少し居眠りをします。\n");
passageOfTime();
if (asleep) {
asleep = false;
$('#pre0').append("しかし、やめると起きてしまいます。\n");
}
}
$('#pre0').html('');
$('#pre0').append(name + "が生まれました。\n");
},
pet,
named = function( ) {
var name = $('#dragon_name').val(),
result = '<label>' +
'<select id="command">' +
'<option value="feed">ご飯をあげる</option>' +
'<option value="walk">散歩に行く</option>' +
'<option value="put_to_bed">寝かしつける</option>' +
'<option value="toss">遊ぶ</option>' +
'<option value="rock">あやす</option>' +
'</select>' +
'</label>' +
'<input id="commanded" type="button" value="実行" >';
name = name ? name : "匿名";
pet = new Dragon(name);
$('#d0').html(result);
$('#name_label').remove();
$('#dragon_named').remove();
$('#commanded').click(commanded);
$('#command').keydown(commanded_keydown);
},
commanded = function( ) {
var $select = $('#command'),
command = $('option:selected', $select).val();
switch ( command ) {
case "feed":
pet.feed();
break;
case "walk":
pet.walk();
break;
case "put_to_bed":
pet.putToBed();
break;
case "toss":
pet.toss();
break;
case "rock":
pet.rock();
}
},
named_keydowned = function(e) {
e = e ? e : nsEvent;
if (e.keyCode === 13) {
named();
}
},
commanded_keydown = function (e) {
e = e ? e : nsEvent;
if (e.keyCode === 13) {
commanded();
}
};
$('#dragon_named').click(named);
$('#dragon_name').keydown(named_keydowned);
</script>
pythonの場合。
sample.py
コード(BBEdit)
#!/usr/bin/env python3.3
#-*- coding: utf-8 -*-
import re
class Dragon:
def __init__(self, name):
self._name = name
self._asleep = False
self._belly = 10
self._intestine = 0
print("{0}が生まれました。".format(self._name))
def feed(self):
print("{0}にご飯をあげます。".format(self._name))
self._belly = 10
self._passage_of_time()
def walk(self):
print("{0}をトイレに連れていきます".format(name))
self._intestine = 0
self._passage_of_time()
def put_to_bed(self):
print("{0}を寝かしつけます。".format(name))
self._asleep = True
for x in range(3):
if self._asleep:
self._passage_of_time()
if self._asleep:
print("{0}がいびきをかいて、部屋が煙だらけです。".format(name))
if self._asleep:
self._asleep = False
print("{0}はゆっくり目覚めます。".format(name))
def toss(self):
print("{0}に高い高いをします。".format(name))
print("{0}が笑ってあなたの眉毛が焦げます。".format(name))
self._passage_of_time()
def rock(self):
print("{0}をやさしくあやします。".format(name))
self._asleep = True
print("{0}は少し居眠りをします。".format(name))
self._passage_of_time()
if self._asleep:
self._asleep = False
print("しかし、やめると起きてしまいます。".format(name))
def _hungry(self):
return self._belly <= 2
def _poppy(self):
return self._intestine >= 8
def _passage_of_time(self):
if self._belly > 0:
self._belly -= 1
self._intestine += 1
else:
if self._asleep:
self._asleep = False
print("{0}が突然目を覚まします!".format(name))
print("{0}がお腹を空かせています。我慢できなくてあなたを食べました。".format(name))
import sys
sys.exit()
if self._intestine >= 10:
self._intestine = 0
print("うわっ、{0}がおもらしを・・・・・・".format(name))
if self._hungry():
if self._asleep:
self._asleep = False
print("{0}が突然目を覚まします!".format(name))
print("{0}のお腹が鳴っています。".format(name))
if self._poppy():
if self._asleep:
self._asleep = False
print("{0}が突然目を覚まします!".format(name))
print("{0}がうんちのためにしゃがみ込みます。".format(name))
name = input("名前を入力: ")
if re.search(r"^\s*$", name):
name = "匿名"
pet = Dragon(name)
commands = {'f':pet.feed, 'w':pet.walk, 'p':pet.put_to_bed, 't':pet.toss, 'r':pet.rock}
while True:
command = input("コマンド(f/w/p/t/r)を入力(空白で終了): ")
if re.search("^\s*$", command):
break
if command in commands:
commands[command]()
else:
print("コマンド入力を確認してください。")
入出力結果(Terminal)
$ ./sample.py 名前を入力: ノーバート ノーバートが生まれました。 コマンド(f/w/p/t/r)を入力(空白で終了): f ノーバートにご飯をあげます。 コマンド(f/w/p/t/r)を入力(空白で終了): t ノーバートに高い高いをします。 ノーバートが笑ってあなたの眉毛が焦げます。 コマンド(f/w/p/t/r)を入力(空白で終了): w ノーバートをトイレに連れていきます コマンド(f/w/p/t/r)を入力(空白で終了): p ノーバートを寝かしつけます。 ノーバートがいびきをかいて、部屋が煙だらけです。 ノーバートがいびきをかいて、部屋が煙だらけです。 ノーバートがいびきをかいて、部屋が煙だらけです。 ノーバートはゆっくり目覚めます。 コマンド(f/w/p/t/r)を入力(空白で終了): r ノーバートをやさしくあやします。 ノーバートは少し居眠りをします。 しかし、やめると起きてしまいます。 コマンド(f/w/p/t/r)を入力(空白で終了): p ノーバートを寝かしつけます。 ノーバートが突然目を覚まします! ノーバートのお腹が鳴っています。 コマンド(f/w/p/t/r)を入力(空白で終了): p ノーバートを寝かしつけます。 ノーバートが突然目を覚まします! ノーバートのお腹が鳴っています。 コマンド(f/w/p/t/r)を入力(空白で終了): p ノーバートを寝かしつけます。 ノーバートが突然目を覚まします! ノーバートのお腹が鳴っています。 ノーバートがうんちのためにしゃがみ込みます。 コマンド(f/w/p/t/r)を入力(空白で終了): p ノーバートを寝かしつけます。 ノーバートが突然目を覚まします! ノーバートがお腹を空かせています。我慢できなくてあなたを食べました。 $
perlの場合。
sample.pl
コード(BBEdit)
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use 5.016;
binmode STDIN, ":utf8";
binmode STDOUT, ":utf8";
{
package Dragon;
sub new {
my($class, $name) = @_;
$name = "匿名" unless $name;
print "${name}が生まれました。\n";
my $self = {Name => $name, Asleep => 0, Belly => 10, Intestine => 0};
bless $self, $class;
}
sub feed {
my $self = shift;
print $self->{Name}, "にご飯をあげます。\n";
$self->{Belly} = 10;
$self->passage_of_time;
}
sub walk {
my $self = shift;
print $self->{Name}, "をトイレに連れていきます。\n";
$self->{Intestine} = 0;
$self->passage_of_time;
}
sub put_to_bed {
my $self = shift;
print $self->{Name}, "を寝かしつけます。\n";
$self->{Asleep} = 1;
for ((1..3)) {
if ($self->{Asleep}) {
$self->passage_of_time;
}
if ($self->{Asleep}) {
print $self->{Name}, "がいびきをかいて、部屋が煙だらけです。\n";
}
}
if ($self->{Asleep}) {
$self->{Asleep} = 0;
print $self->{Name}, "はゆっくり目覚めます。\n";
}
}
sub toss {
my $self = shift;
print $self->{Name}, "に高い高いをします。\n";
print $self->{Name}, "が笑ってあなたの眉毛が焦げます。\n";
$self->passage_of_time;
}
sub rock {
my $self = shift;
print $self->{Name}, "をやさしくあやします。\n";
$self->{Asleep} = 0;
print $self->{Name}, "は少し居眠りをします。\n";
$self->passage_of_time;
if ($self->{Asleep}) {
$self->{Asleep} = 0;
print "しかし、やめると起きてしまいます。\n";
}
}
sub hungry {
my $self = shift;
$self->{Belly} <= 2;
}
sub poopy {
my $self = shift;
$self->{Intestine} >= 8;
}
sub passage_of_time {
my $self = shift;
if ($self->{Belly} > 0) {
$self->{Belly} -= 1;
$self->{Intestine} += 1;
} else {
if ($self->{Asleep}) {
$self->{Asleep} = 0;
print $self->{Name}, "が突然目を覚まします!\n";
}
print $self->{Name}, "がお腹をすかせています。我慢できなくてあなたを食べました。\n";
exit;
}
if ($self->{Intestine} >= 10) {
$self->{Intestine} = 0;
print "うわっ、", $self->{Name}, "がお漏らしを・・・・・・\n";
}
if ($self->hungry) {
if ($self->{Asleep}) {
$self->{Asleep} = 0;
print $self->{Name}, "が突然目を覚まします!\n";
}
print $self->{Name}, "のお腹が鳴っています。\n";
}
if ($self->poopy) {
if ($self->{Asleep}) {
$self->{Asleep} = 0;
print $self->{Name}, "が突然目を覚まします!\n";
}
print $self->{Name}, "がうんちのためにしゃがみ込みます。\n";
}
}
}
print "名前を入力: ";
chomp(my $name = <STDIN>);
$name = "匿名" if $name =~ /^\s*$/;
my $pet = Dragon->new($name);
while (1) {
print "コマンド(f/w/p/t/r)を入力(空白で終了): ";
chomp(my $command = <STDIN>);
given( $command ) {
when (/^\s*$/) { last; }
when ('f') {$pet->feed;}
when ('w') {$pet->walk;}
when ('p') {$pet->put_to_bed;}
when ('t') {$pet->toss;}
when ('r') {$pet->rock;}
default {print "コマンド入力を確認してください\n";}
}
}
入出力結果(Terminal)
$ ./sample.pl 名前を入力: ノーバート ノーバートが生まれました。 コマンド(f/w/p/t/r)を入力(空白で終了): f ノーバートにご飯をあげます。 コマンド(f/w/p/t/r)を入力(空白で終了): t ノーバートに高い高いをします。 ノーバートが笑ってあなたの眉毛が焦げます。 コマンド(f/w/p/t/r)を入力(空白で終了): w ノーバートをトイレに連れていきます。 コマンド(f/w/p/t/r)を入力(空白で終了): p ノーバートを寝かしつけます。 ノーバートがいびきをかいて、部屋が煙だらけです。 ノーバートがいびきをかいて、部屋が煙だらけです。 ノーバートがいびきをかいて、部屋が煙だらけです。 ノーバートはゆっくり目覚めます。 コマンド(f/w/p/t/r)を入力(空白で終了): r ノーバートをやさしくあやします。 ノーバートは少し居眠りをします。 コマンド(f/w/p/t/r)を入力(空白で終了): p ノーバートを寝かしつけます。 ノーバートが突然目を覚まします! ノーバートのお腹が鳴っています。 コマンド(f/w/p/t/r)を入力(空白で終了): p ノーバートを寝かしつけます。 ノーバートが突然目を覚まします! ノーバートのお腹が鳴っています。 コマンド(f/w/p/t/r)を入力(空白で終了): p ノーバートを寝かしつけます。 ノーバートが突然目を覚まします! ノーバートのお腹が鳴っています。 ノーバートがうんちのためにしゃがみ込みます。 コマンド(f/w/p/t/r)を入力(空白で終了): p ノーバートを寝かしつけます。 ノーバートが突然目を覚まします! ノーバートがお腹をすかせています。我慢できなくてあなたを食べました $
とりあえずできたけど、PerlでもRubyみたいに中だけで使えるprivateみたいの作るにはどうすればいいのかが分からないまま。。(Pythonは隠蔽はできない。意図を伝えるために属性名の先頭にアンダースコア「_」を付ける。)
0 コメント:
コメントを投稿