package main import ( "fmt" "os" "syscall" "unsafe" ) func terminalSize() (cols int, lines int, err error) { const tiocgwinsz uintptr = 21523 ts := new(struct { wsRow, wsCol, wsXPixel, wsYPixel uint16 }) if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, 1, tiocgwinsz, uintptr(unsafe.Pointer(ts))); err != 0 { return 0, 0, err } return int(ts.wsCol), int(ts.wsRow), nil } func mandelbrot(x0, y0 float64) int { var x, y, x2, y2 float64 for i := 0; i < 1000; i++ { if x2+y2 > 4 { return (i-1)%6 + 1 } y = (x+x)*y + y0 x = x2 - y2 + x0 x2 = x * x y2 = y * y } return 0 } func main() { const ( xMin = -2. xRange = 2.47 yMin = -1.12 yRange = 2.24 ) width, height, err := terminalSize() if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } height-- // Leave a line for the status bar // Try not to stretch Mandelbrot if yRange*float64(width) <= xRange*float64(height)*5/2 { height = int(yRange * float64(width) / (xRange * 5 / 2)) } else { width = int(xRange * float64(height) * 5 / 2 / yRange) } xStep := xRange / float64(width) yStep := yRange / float64(height) y := yMin for i := 0; i < height; i++ { x := xMin for j := 0; j < width; j++ { fmt.Printf("\033[3%dm\033[4%dmâ–€", mandelbrot(x, y), mandelbrot(x, y+yStep/2)) x += xStep } fmt.Println("\033[m") y += yStep } }