Comment detail

2次元ランダムウォーク (Nested Flatten)

 scala+swingで書いてみました。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import    java.awt.BorderLayout
import    java.awt.Color
import    java.awt.Dimension
import    java.awt.FlowLayout
import    java.awt.Graphics
import    java.awt.Point
import    java.awt.event.ActionEvent
import    java.awt.event.ActionListener
import    java.io.BufferedWriter
import    java.io.File
import    java.io.FileOutputStream
import    java.io.OutputStreamWriter
import    java.io.PrintWriter
import    java.util.Random
import    javax.swing.JButton
import    javax.swing.JFileChooser
import    javax.swing.JFrame
import    javax.swing.JMenu
import    javax.swing.JMenuBar
import    javax.swing.JMenuItem
import    javax.swing.JPanel

class RandomWalk(step:int) {
    private    var    _trace:List[Point] = null
    private    val    rand:Random = new Random
    
    def walk:RandomWalk = {
        var    p = new Point(0,0)
        trace = (new Range(1,step,1)).map[Point] { i => p = move(p); p }.toList
        this
    }
    
    private def move(p:Point):Point = rand.nextInt(4) match {
        case 0 => new Point(p.x + 1, p.y)
        case 1 => new Point(p.x - 1, p.y)
        case 2 => new Point(p.x, p.y + 1)
        case 3 => new Point(p.x, p.y - 1)
        case _ => p
    }
    
    def trace_=(trace:List[Point]) = { _trace = trace }
    def trace = _trace
}

class Button(l:String,c:ActionEvent=>Unit) extends JButton with ActionListener {
    
    setText(l)
    addActionListener(this)
    
    override def actionPerformed(e:ActionEvent) = c(e)
}

class MenuItem(l:String,c:ActionEvent=>Unit) extends JMenuItem with ActionListener {
    
    setText(l)
    addActionListener(this)
    
    override def actionPerformed(e:ActionEvent) = c(e)
}

class Panel extends JPanel {
    var    _trace:List[Point] = null
    
    def trace_=(trace:List[Point]) = { _trace = trace }
    def trace = _trace
    
    override def paint(g:Graphics):Unit = {
        val    max:int = trace.foldLeft(0) { (m,p) => List(p.x,p.y).foldLeft(m) { (m,l) => Math.max(m,Math.abs(l)) } }
        val    pitch:double = getWidth.asInstanceOf[double] / (max * 2)
        
        def drawLine(c:Point,trace:List[Point]):Unit = {
            trace match {
                case List() => ()
                case (p::rest) => {
                    g.drawLine(
                            (c.x * pitch).asInstanceOf[int] + getWidth / 2,
                            getWidth / 2 - (c.y * pitch).asInstanceOf[int],
                            (p.x * pitch).asInstanceOf[int] + getWidth / 2,
                            getWidth / 2 - (p.y * pitch).asInstanceOf[int]
                        )
                    drawLine(p,rest)
                }
            }
        }
        
        g.clearRect(0,0,getWidth,getHeight)
        g.setColor(Color.BLACK)
        
        drawLine(new Point(0,0),trace)
    }
}

class Plotter(title:String,step:int) extends JFrame {
    
    var    walker = (new RandomWalk(step)).walk
    var    _panel:Panel = null
    
    def panel_=(panel:Panel) = { _panel = panel }
    def panel = _panel
    
    def walk:Unit = {
        walker.walk
        panel.trace = walker.trace
    }
    def walk(e:ActionEvent):Unit = {
        walk
        repaint()
    }
    def save(e:ActionEvent):Unit = {
        val    fc:JFileChooser = new JFileChooser()
        
        try {
            if (fc.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
                val    f:File = fc.getSelectedFile
                val    w:PrintWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f))))
                
                def writeTrace(trace:List[(int,Point)]):Unit = {
                    trace match {
                        case List() => ()
                        case (i::rest) => {
                            w.printf("%d\t%d\t%d\n",Array(Integer.valueOf(i._1),Integer.valueOf(i._2.x),Integer.valueOf(i._2.y)))
                            writeTrace(rest)
                        }
                    }
                }
                
                writeTrace((new Range(1,walker.trace.size,1)).toList.zip(walker.trace))
                w.close
            }
        } catch {
            case e => e.printStackTrace
        }
    }
    def quit(e:ActionEvent):Unit = {
        System.exit(0)
    }
}

object Main extends Application {
    var    p = new Plotter("random walk",10000)
    val    mb = new JMenuBar
    val    fm = new JMenu("file")
    val    em = new JMenu("walk")
    val    c = p.getContentPane
    val    pp = new Panel
    val    bp = new JPanel
    
    c.setLayout(new BorderLayout)
    pp.setPreferredSize(new Dimension(300,300))
    c.add(pp,BorderLayout.CENTER)
    p.panel = pp
    bp.setLayout(new FlowLayout)
    bp.add(new Button("walk",p.walk))
    bp.add(new Button("save",p.save))
    c.add(bp,BorderLayout.SOUTH)
    
    fm.add(new MenuItem("save",p.save))
    fm.add(new MenuItem("quit",p.quit))
    mb.add(fm)
    em.add(new MenuItem("walk",p.walk))
    mb.add(em)
    p.setJMenuBar(mb)
    
    p.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
    p.setResizable(false)
    p.pack
    
    p.walk
    
    p.setVisible(true)
}

Index

Feed

Other

Link

Pathtraq

loading...