Language Scala
(Animated version)
| Date: | 10/02/09 |
| Author: | D Mackenzie |
| URL: | n/a |
| Comments: | 0 |
| Info: | http://www.scala-lang.org |
| Score: |
import java.awt.{Font, Color, Dimension, Graphics, List => _}
import javax.swing.{JPanel, JFrame, SwingUtilities}
import java.util.{Timer, TimerTask}
object NinetynineBottles {
abstract class DrawnThing {def draw(gc: Graphics)}
class Bottle(var x: Int, var y: Int) extends DrawnThing {
private val r = new java.util.Random()
def draw(gc: Graphics) {
gc.setColor(new Color(80,40,20))
gc.fillRoundRect(x - 12,y - 30,24,60,15,15); gc.fillRoundRect(x - 5,y - 50,10,40,5,5)
gc.setColor(new Color(0,0,255)); gc.fillRect(x - 6,y - 20,16,28)
}
def move(doff: Int) {x = 1160 + (r.nextInt(400) - 200); y = 470 + doff / 2}
def move(p: (Int, Int)) {x = p._1; y = p._2}
}
object Wall extends DrawnThing {
def draw(gc: Graphics) {
gc.setColor(new Color(230,120,90)); gc.fillRect(0,300,900,300)
gc.setColor(new Color(160,160,160)); gc.setClip(0,300,900,300)
for (h <- -20 to 900 by 36; v <- 300 to 600 by 19; o = v % 2 * 18)
gc.drawRect(h + o,v,32,16)
gc.setClip(0,0,1400,600)
}
}
object Lyrics extends DrawnThing {
val f1 = new Font("Serif", Font.PLAIN, 20)
def lyric = {
def qty(n:Int) =
(n match {case 0 => "no more bottles"
case 1 => "1 bottle"
case n => n + " bottles"}) + " of beer"
qty(bc).capitalize + " on the wall, " + qty(bc) + "." +
(if (bc > 0)
"\nTake one down and pass it around, \n" + qty(bc - 1) + " on the wall.\n"
else
"\nGo to the store and buy some more, \n" + qty(99) + " on the wall.")
}
def draw(gc: Graphics) {
gc.setColor(new Color(100 + bc,200,100 + bc)); gc.fillOval(850,30,550,200)
gc.fillPolygon(Array(900,940,1020),Array(320,150,180),3)
gc.setColor(new Color(255,0,0)); gc.setFont(f1)
List.fromString(lyric, '\n').foldLeft(0){(d,l:String) =>
gc.drawString(l,900,120 + d); d + 20}
}
}
private var bc = 99
val timer = new Timer()
val bottles = (for {bi <- 0 until bc
(x,y) = stacker(bi,34,0,0)} yield new Bottle(x,y)).toList
val things = Wall :: bottles ::: List(Lyrics)
val top = new JFrame {
setPreferredSize(new Dimension(1400,600))
setTitle("99 Bottles of Beer")
getContentPane.add(new JPanel{
override def paintComponent(gc: Graphics) {things.foreach(_.draw(gc))}})
}
def stacker(ind: Int, lrc: Int, lri: Int, rh: Int):(Int, Int) = {
if ((ind - lri) < lrc) (25 + rh * 12 + 25 * (ind - lri),270 - rh * 78)
else stacker(ind,lrc - 1,lri + lrc,rh + 1)
}
def main(args: Array[String]) {
def moveEmpties {bottles.drop(bc).head.move(bc)}
def swingRequest(req: => Unit) {SwingUtilities.invokeLater(new Runnable{def run{req}})}
swingRequest{top.pack(); top.setVisible(true)}
timer.schedule(new TimerTask{
def run {
if (bc > 0) {bc -= 1; moveEmpties; swingRequest{top.repaint()}}
else {
bottles.foldLeft(0){(d, b) => b move stacker(d,34,0,0); d+1}
Thread.sleep(4000); swingRequest{top.repaint()}; timer.cancel()
}}}, 2000, 1500)
}
}
Download Source | Write Comment
Alternative Versions
| Version | Author | Date | Comments | Rate |
|---|---|---|---|---|
| Scala with a vengeance | Eduardo Costa | 09/16/09 | 0 | |
| Fun semi-DSL readable version | Calum Leslie | 01/31/08 | 0 | |
| GrabbaBeer & CaseOfBeers | D Mackenzie | 05/30/09 | 0 |
Download Source | Write Comment
Add Comment
Please provide a value for the fields Name,
Comment and Security Code.
This is a gravatar-friendly website.
E-mail addresses will never be shown.
Enter your e-mail address to use your gravatar.
Please don't post large portions of code here! Use the form to submit new examples or updates instead!
Comments