Galton box animation: Difference between revisions

Content added Content deleted
(Added Perl example)
Line 1,697: Line 1,697:
| |o|o|o|o|o|o|o| |
| |o|o|o|o|o|o|o| |
| |o|o|o|o|o|o|o| |</pre>
| |o|o|o|o|o|o|o| |</pre>

=={{header|JavaScript}}==
Works with NodeJs
<lang JavaScript>const readline = require('readline');
const galtonBox2 = (layers, balls) => {
const speed = 100;
const ball = 'o';
const peg = '.';
const result = [];

const sleep = ms => new Promise(resolve => {
setTimeout(resolve,ms)
});

/**
* The board is represented as a 2D array.
* @type {Array<Array<string>>}
*/
const board = [...Array(layers)]
.map((e, i) => {
const sides = Array(layers - i).fill(' ');
const a = Array(i + 1).fill(peg).join(' ').split('');
return [...sides, ...a, ...sides];
});

/**
* @return {Array<string>}
*/
const emptyRow = () => Array(board[0].length).fill(' ');

/**
* @param {number} i
* @returns {number}
*/
const bounce = i => Math.round(Math.random()) ? i - 1 : i + 1;

/**
* Prints the current state of the board and the collector
*/
const show = () => {
readline.cursorTo(process.stdout, 0, 0);
readline.clearScreenDown(process.stdout);
board.forEach(e => console.log(e.join('')));
result.reverse();
result.forEach(e => console.log(e.join('')));
result.reverse();
};


/**
* Collect the result.
* @param idx
*/
const appendToResult = idx => {
const row = result.find(e => e[idx] === ' ');
if (row) {
row[idx] = ball;
} else {
const newRow = emptyRow();
newRow[idx] = ball;
result.push(newRow);
}
};

/**
* Move the balls through the board
* @returns {boolean} True if the there are balls in the board.
*/
const iter = () => {
let hasNext = false;
[...Array(bordSize)].forEach((e, i) => {
const rowIdx = (bordSize - 1) - i;
const idx = board[rowIdx].indexOf(ball);
if (idx > -1) {
board[rowIdx][idx] = ' ';
const nextRowIdx = rowIdx + 1;
if (nextRowIdx < bordSize) {
hasNext = true;
const nextRow = board[nextRowIdx];
nextRow[bounce(idx)] = ball;
} else {
appendToResult(idx);
}
}
});
return hasNext;
};

board.unshift(emptyRow());
result.unshift(emptyRow());

const bordSize = board.length;
const apex = board[1].indexOf(peg);

return (async () => {
while (balls) {
board[0][apex] = ball;
balls = balls - 1;
await sleep(speed);
show();
iter();
}
await sleep(speed);
show();
while (iter()) {
await sleep(speed);
show();
}
await sleep(speed);
show();
})().then(() => console.log('Done!'));


};

galtonBox2(12, 50);
</lang>
{{out}}
<pre>
.
. .
. . .
. . . .
. . . . .
. . . . . .
. . . . . . .
. . . . . . . .
. . . . . . . . .
. . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . . .
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|Julia}}==
=={{header|Julia}}==