import 'dart:async'; import 'dart:html'; import 'dart:math' show Random; // We changed 5 lines of code to make this sample nicer on // the web (so that the execution waits for animation frame, // the number gets updated in the DOM, and the program ends // after 500 iterations). main() async { print('Compute π using the Monte Carlo method.'); var output = querySelector("#output"); await for (var estimate in computePi().take(500)) { print('π ≅ $estimate'); output.text = estimate.toStringAsFixed(5); await window.animationFrame; } } /// Generates a stream of increasingly accurate estimates of π. Stream computePi({int batch: 100000}) async* { var total = 0; var count = 0; while (true) { var points = generateRandom().take(batch); var inside = points.where((p) => p.isInsideUnitCircle); total += batch; count += inside.length; var ratio = count / total; // Area of a circle is A = π⋅r², therefore π = A/r². // So, when given random points with x ∈ <0,1>, // y ∈ <0,1>, the ratio of those inside a unit circle // should approach π / 4. Therefore, the value of π // should be: yield ratio * 4; } } Iterable generateRandom([int seed]) sync* { final random = new Random(seed); while (true) { yield new Point(x: random.nextDouble(), y: random.nextDouble()); } } class Point { final double x, y; const Point({required this.x, required this.y}); bool get isInsideUnitCircle => x * x + y * y <= 1; }