Task: Chaos game




Go: package main

import (
	"fmt"
	"image"
	"image/color"
	"image/draw"
	"image/gif"
	"log"
	"math"
	"math/rand"
	"os"
	"time"
)

var bwPalette = color.Palette{
	color.Transparent,
	color.White,
	color.RGBA{R: 0xff, A: 0xff},
	color.RGBA{G: 0xff, A: 0xff},
	color.RGBA{B: 0xff, A: 0xff},
}

func main() {
	const (
		width          = 160
		frames         = 100
		pointsPerFrame = 50
		delay          = 100 * time.Millisecond
		filename       = "chaos_anim.gif"
	)

	var tan60 = math.Sin(math.Pi / 3)
	height := int(math.Round(float64(width) * tan60))
	b := image.Rect(0, 0, width, height)
	vertices := [...]image.Point{
		{0, height}, {width, height}, {width / 2, 0},
	}

	
	m := image.NewPaletted(b, bwPalette)
	for y := b.Min.Y; y < b.Max.Y; y++ {
		bg := int(math.Round(float64(b.Max.Y-y) / 2 / tan60))
		for x := b.Min.X + bg; x < b.Max.X-bg; x++ {
			m.SetColorIndex(x, y, 1)
		}
	}

	
	var p image.Point
	rand.Seed(time.Now().UnixNano())
	p.Y = rand.Intn(height) + b.Min.Y
	p.X = rand.Intn(width) + b.Min.X 

	anim := newAnim(frames, delay)
	addFrame(anim, m)
	for i := 1; i < frames; i++ {
		for j := 0; j < pointsPerFrame; j++ {
			
			vi := rand.Intn(len(vertices))
			v := vertices[vi]
			
			p.X = (p.X + v.X) / 2
			p.Y = (p.Y + v.Y) / 2
			m.SetColorIndex(p.X, p.Y, uint8(2+vi))
		}
		addFrame(anim, m)
	}
	if err := writeAnim(anim, filename); err != nil {
		log.Fatal(err)
	}
	fmt.Printf("wrote to %q\n", filename)
}



func newAnim(frames int, delay time.Duration) *gif.GIF {
	const gifDelayScale = 10 * time.Millisecond
	g := &gif.GIF{
		Image: make([]*image.Paletted, 0, frames),
		Delay: make([]int, 1, frames),
	}
	g.Delay[0] = int(delay / gifDelayScale)
	return g
}
func addFrame(anim *gif.GIF, m *image.Paletted) {
	b := m.Bounds()
	dst := image.NewPaletted(b, m.Palette)
	draw.Draw(dst, b, m, image.ZP, draw.Src)
	anim.Image = append(anim.Image, dst)
	if len(anim.Delay) < len(anim.Image) {
		anim.Delay = append(anim.Delay, anim.Delay[0])
	}
}
func writeAnim(anim *gif.GIF, filename string) error {
	f, err := os.Create(filename)
	if err != nil {
		return err
	}
	err = gif.EncodeAll(f, anim)
	if cerr := f.Close(); err == nil {
		err = cerr
	}
	return err
}


Java: import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;

public class ChaosGame extends JPanel {
    static class ColoredPoint extends Point {
        int colorIndex;

        ColoredPoint(int x, int y, int idx) {
            super(x, y);
            colorIndex = idx;
        }
    }

    Stack<ColoredPoint> stack = new Stack<>();
    Point[] points = new Point[3];
    Color[] colors = {Color.red, Color.green, Color.blue};
    Random r = new Random();

    public ChaosGame() {
        Dimension dim = new Dimension(640, 640);
        setPreferredSize(dim);
        setBackground(Color.white);

        int margin = 60;
        int size = dim.width - 2 * margin;

        points[0] = new Point(dim.width / 2, margin);
        points[1] = new Point(margin, size);
        points[2] = new Point(margin + size, size);

        stack.push(new ColoredPoint(-1, -1, 0));

        new Timer(10, (ActionEvent e) -> {
            if (stack.size() < 50_000) {
                for (int i = 0; i < 1000; i++)
                    addPoint();
                repaint();
            }
        }).start();
    }

    private void addPoint() {
        try {
            int colorIndex = r.nextInt(3);
            Point p1 = stack.peek();
            Point p2 = points[colorIndex];
            stack.add(halfwayPoint(p1, p2, colorIndex));
        } catch (EmptyStackException e) {
            e.printStackTrace();
        }
    }

    void drawPoints(Graphics2D g) {
        for (ColoredPoint p : stack) {
            g.setColor(colors[p.colorIndex]);
            g.fillOval(p.x, p.y, 1, 1);
        }
    }

    ColoredPoint halfwayPoint(Point a, Point b, int idx) {
        return new ColoredPoint((a.x + b.x) / 2, (a.y + b.y) / 2, idx);
    }

    @Override
    public void paintComponent(Graphics gg) {
        super.paintComponent(gg);
        Graphics2D g = (Graphics2D) gg;
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        drawPoints(g);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setTitle("Chaos Game");
            f.setResizable(false);
            f.add(new ChaosGame(), BorderLayout.CENTER);
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        });
    }
}