yojikのlog

yojikのブログです

サンタクロース問題をScalaで(自信なし)

勉強用に作ってみたんだけど、きちんとドキュメント読んでないのとイディオムが分かっていないので微妙だ。OO言語っぽく書きすぎてて、全然ダメダメなプログラムな気がする。まぁ突っ込み歓迎ということで。(別の作業の現実逃避としてやってしまいました)
特徴は、ElfやReindeerをActorで表現してみたところ(であってるのかな)

import scala.actors._
import scala.actors.Actor._
import Console._
import scala.collection.mutable._
class Elf(val name:String ,val s: Santa) extends Actor {
  def act() {
    loop {
      react  {
        case "Work" =>
          println(name + "は働いているようだ")
          s ! this
      }
    }
  } 
}
class Reindeer(val name:String ,val s: Santa) extends Actor {
  def act() {
    loop {
      react  {
        case "Play" =>
          println(name + "は遊んでいるようだ")
          s ! this
      }
    }
  }
}
class Santa extends Actor {
  def act() {
    val elves:ListBuffer[Elf] = new ListBuffer()
    val reindeers:ListBuffer[Reindeer] = new ListBuffer()
    loop {
      react {
        case e:Elf =>
          println( e.name + "「チース」" ) 
          elves += e
          if(elves.length==3) {
            println("ミーティングしとく? " +  elves.map(_.name));
            elves.foreach(_ ! "Work")  
            elves.clear()
          }
        case r:Reindeer =>
          println( r.name  + "「チース」") 
          reindeers  += r
          if(reindeers.length==9) {
            println("プレゼント配りにいこうぜ!!" +  reindeers.map(_.name));
            reindeers.foreach(_ ! "Play")
            reindeers.clear()
          }
        
      }
    }
  }
}
object Test {
  def main(args:Array[String]) {
    val s = new Santa()
    var elves = List(new Elf("1",s),new Elf("2",s),new Elf("3",s),new Elf("4",s),new Elf("5",s),
                     new Elf("6",s),new Elf("7",s),new Elf("8",s),new Elf("9",s),new Elf("0",s))
    var reindeers = List(new Reindeer("ダッシャー",s),new Reindeer("ダンサー",s),new Reindeer("プランサー",s),
                         new Reindeer("ヴィクセン",s),new Reindeer("ドンダー",s),new Reindeer("ブリッツェン",s),
                         new Reindeer("キューピッド",s),new Reindeer("コメット",s),new Reindeer("ルドルフ",s))
    s.start; 
    elves.foreach(_.start);
    reindeers.foreach(_.start)
    elves.foreach(_ ! "Work") ;
    reindeers.foreach(_ ! "Play")
  }
}

結果

1は働いているようだ
4は働いているようだ
5は働いているようだ
6は働いているようだ
7は働いているようだ
8は働いているようだ
9は働いているようだ
0は働いているようだ
2は働いているようだ
3は働いているようだ
1「チース」
4「チース」
5「チース」
プランサーは遊んでいるようだ
ダッシャーは遊んでいるようだ
ダンサーは遊んでいるようだ
ドンダーは遊んでいるようだ
ブリッツェンは遊んでいるようだ
キューピッドは遊んでいるようだ
コメットは遊んでいるようだ
ルドルフは遊んでいるようだ
ヴィクセンは遊んでいるようだ
ミーティングしとく? ArrayBuffer(1,4,5)
6「チース」
7「チース」
8「チース」
ミーティングしとく? ArrayBuffer(6,7,8)
9「チース」
0「チース」
2「チース」
ミーティングしとく? ArrayBuffer(9,0,2)
3「チース」
プランサー「チース」
4は働いているようだ
1は働いているようだ
6は働いているようだ
ダッシャー「チース」
5は働いているようだ
ダンサー「チース」
8は働いているようだ
7は働いているようだ
0は働いているようだ
ドンダー「チース」
9は働いているようだ
ブリッツェン「チース」
2は働いているようだ
キューピッド「チース」
コメット「チース」
ルドルフ「チース」
ヴィクセン「チース」
プレゼント配りにいこうぜ!!ArrayBuffer(プランサー,ダッシャー,ダンサー,ドンダー,ブリッツェン,キューピッド,コメット,ルドルフ,ヴィクセン)
4「チース」

同期関連の処理を全く書かなくていいのは楽ですわ。ちなみにreceive使うとワーカースレッドが4つしか無いせいでうまくいかない事に気づく。ちゃんとドキュメント読まないとだめだなぁ。

追記: 小人が10人なのをわかっていなかったので修正