開発環境
- 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 コメント:
コメントを投稿