TurboGraphicsより雪見酒

YukiMi

昔、TurboGraphicsという本があって、それでPascalにハマっていたのだが、久しぶりにそのコードを書いて、Scalaに移植してみた。
樹氷や、窓の霜が成長する感じ。
わざとSleepを入れて徐々に成長するようにしてます。

package asanmath
    
import java.awt.Color
import java.awt.image.BufferedImage
import javax.swing._

/** 雪見酒 TURBO GRAPHICS P89 */
object YukiMi {
    val Width = 640
    val Height = 400
    val SnowColor = 0xFFFFFFFF
    val image = new BufferedImage(Width, Height, BufferedImage.TYPE_4BYTE_ABGR)
    var top:Int = Height - 1        // 雪のもっとも高い位置

    /** 0..(s-1)の乱数を生成する */
    def random(s:Int):Int = (math.random * s).toInt

    /** 雪がくっついたか? */
    def isStick(x:Int, y:Int):Boolean = {
        val nextLine = y + 1
//println(x+" "+y)
        image.getRGB(x % Width, nextLine) == SnowColor ||
        image.getRGB((x + Width - 1) % Width, nextLine) == SnowColor ||
        image.getRGB((x + 1) % Width, nextLine) == SnowColor
    }

    def falling() {
        var y = top - 40
        var x = random(Width)
        do {
            x = random(3) match {
                case 0 => x
                case 1 => (x + Width - 1) % Width
                case 2 => (x + 1) % Width
            }
            y += 1
        } while (! isStick(x, y) && y < Height - 2)
        if (y < top) top = y
        image.setRGB(x, y, SnowColor)
println(x+" "+y)
    }

    def main(args:Array[String]) {
        val frame = new JFrame("雪見酒")
        val panel = new JLabel(new ImageIcon(image))
        frame.getContentPane.add(panel)
        frame.pack()
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
        frame.setVisible(true)
        val g = image.getGraphics()
        g.setColor(Color.BLACK)
        g.fillRect(0, 0, Width, Height)

        top = Height - 1
        while (top > 40) {
            falling()
            panel.repaint()
            Thread.sleep(10)
        }
        println("fallen.")  // 積もった!
    }
}