Galton box animation: Difference between revisions
Content added Content deleted
m (→gui: IupCloseOnEscape no longer needed) |
(Added Wren) |
||
Line 4,125: | Line 4,125: | ||
</pre> |
</pre> |
||
There is a much more comprehensive solution to this on the [http://wiki.tcl.tk/8825 Tcler's Wiki].<!-- Too long to reproduce here --> |
There is a much more comprehensive solution to this on the [http://wiki.tcl.tk/8825 Tcler's Wiki].<!-- Too long to reproduce here --> |
||
=={{header|Wren}}== |
|||
{{trans|D}} |
|||
{{libheader|Wren-trait}} |
|||
<lang ecmascript>import "random" for Random |
|||
import "/trait" for Reversed |
|||
var boxW = 41 // Galton box width. |
|||
var boxH = 37 // Galton box height. |
|||
var pinsBaseW = 19 // Pins triangle base. |
|||
var nMaxBalls = 55 // Number of balls. |
|||
var centerH = pinsBaseW + (boxW - pinsBaseW * 2 + 1) / 2 - 1 |
|||
var Rand = Random.new() |
|||
class Cell { |
|||
static EMPTY { " " } |
|||
static BALL { "o" } |
|||
static WALL { "|" } |
|||
static CORNER { "+" } |
|||
static FLOOR { "-" } |
|||
static PIN { "." } |
|||
} |
|||
/* Galton box. Will be printed upside down. */ |
|||
var Box = List.filled(boxH, null) |
|||
for (i in 0...boxH) Box[i] = List.filled(boxW, Cell.EMPTY) |
|||
class Ball { |
|||
construct new(x, y) { |
|||
if (Box[x][y] != Cell.EMPTY) Fiber.abort("The cell at (x, y) is not empty.") |
|||
Box[y][x] = Cell.BALL |
|||
_x = x |
|||
_y = y |
|||
} |
|||
doStep() { |
|||
if (_y <= 0) return // Reached the bottom of the box. |
|||
var cell = Box[_y - 1][_x] |
|||
if (cell == Cell.EMPTY) { |
|||
Box[_y][_x] = Cell.EMPTY |
|||
_y = _y - 1 |
|||
Box[_y][_x] = Cell.BALL |
|||
} else if (cell == Cell.PIN) { |
|||
Box[_y][_x] = Cell.EMPTY |
|||
_y = _y - 1 |
|||
if (Box[_y][_x - 1] == Cell.EMPTY && Box[_y][_x + 1] == Cell.EMPTY) { |
|||
_x = _x + Rand.int(2) * 2 - 1 |
|||
Box[_y][_x] = Cell.BALL |
|||
return |
|||
} else if (Box[_y][_x - 1] == Cell.EMPTY){ |
|||
_x = _x + 1 |
|||
} else _x = _x - 1 |
|||
Box[_y][_x] = Cell.BALL |
|||
} else { |
|||
// It's frozen - it always piles on other balls. |
|||
} |
|||
} |
|||
} |
|||
var initializeBox = Fn.new { |
|||
// Set ceiling and floor: |
|||
Box[0][0] = Cell.CORNER |
|||
Box[0][boxW - 1] = Cell.CORNER |
|||
for (i in 1...boxW - 1) Box[0][i] = Cell.FLOOR |
|||
for (i in 0...boxW) Box[boxH - 1][i] = Box[0][i] |
|||
// Set walls: |
|||
for (r in 1...boxH - 1) { |
|||
Box[r][0] = Cell.WALL |
|||
Box[r][boxW - 1] = Cell.WALL |
|||
} |
|||
// Set pins: |
|||
for (nPins in 1..pinsBaseW) { |
|||
for (pin in 0...nPins) { |
|||
Box[boxH - 2 - nPins][centerH + 1 - nPins + pin * 2] = Cell.PIN |
|||
} |
|||
} |
|||
} |
|||
var drawBox = Fn.new() { |
|||
for (row in Reversed.new(Box, 1)) { |
|||
for (c in row) System.write(c) |
|||
System.print() |
|||
} |
|||
} |
|||
initializeBox.call() |
|||
var balls = [] |
|||
for (i in 0...nMaxBalls + boxH) { |
|||
System.print("\nStep %(i):") |
|||
if (i < nMaxBalls) balls.add(Ball.new(centerH, boxH - 2)) // Add ball. |
|||
drawBox.call() |
|||
// Next step for the simulation. |
|||
// Frozen balls are kept in balls list for simplicity |
|||
for (b in balls) b.doStep() |
|||
}</lang> |
|||
{{out}} |
|||
Sample output, showing the last step only: |
|||
<pre> |
|||
Step 91: |
|||
+---------------------------------------+ |
|||
| | |
|||
| . | |
|||
| . . | |
|||
| . . . | |
|||
| . . . . | |
|||
| . . . . . | |
|||
| . . . . . . | |
|||
| . . . . . . . | |
|||
| . . . . . . . . | |
|||
| . . . . . . . . . | |
|||
| . . . . . . . . . . | |
|||
| . . . . . . . . . . . | |
|||
| . . . . . . . . . . . . | |
|||
| . . . . . . . . . . . . . | |
|||
| . . . . . . . . . . . . . . | |
|||
| . . . . . . . . . . . . . . . | |
|||
| . . . . . . . . . . . . . . . . | |
|||
| . . . . . . . . . . . . . . . . . | |
|||
| . . . . . . . . . . . . . . . . . . | |
|||
| . . . . . . . . . . . . . . . . . . . | |
|||
| | |
|||
| | |
|||
| o | |
|||
| o | |
|||
| o | |
|||
| o o | |
|||
| o o | |
|||
| o o | |
|||
| o o o o | |
|||
| o o o o | |
|||
| o o o o | |
|||
| o o o o o | |
|||
| o o o o o o o o | |
|||
| o o o o o o o o o | |
|||
| o o o o o o o o o o o o | |
|||
+---------------------------------------+ |
|||
</pre> |
|||
=={{header|XPL0}}== |
=={{header|XPL0}}== |