文章目录
go
package main
import (
"fmt"
"math/rand"
"time"
)
const (
width = 80
height = 15
)
// Universe 是一个二维网格
type Universe [][]bool
// NewUniverse 将返回一个空白的世界
func NewUniverse() Universe {
u := make(Universe, height)
for i := range u {
u[i] = make([]bool, width)
}
return u
}
// Seed 用于在世界上随机激活一些细胞
func (u Universe) Seed() {
for i := 0; i < (width * height / 4); i++ {
u.Set(rand.Intn(width), rand.Intn(height), true)
}
}
// Set 用于设置指定细胞的状态
func (u Universe) Set(x, y int, b bool) {
u[y][x] = b
}
// Alive 会报告指定的细胞是否存活。如果给定的坐标不在世界范围之内,那么实行回绕
func (u Universe) Alive(x, y int) bool {
x = (x + width) % width
y = (y + height) % height
return u[y][x]
}
// Neighbors 用于统计邻近细胞的存活数量
func (u Universe) Neighbors(x, y int) int {
n := 0
for v := -1; v <= 1; v++ {
for h := -1; h <= 1; h++ {
if !(v == 0 && h == 0) && u.Alive(x+h, y+v) {
n++
}
}
}
return n
}
// Next 会返回指定细胞在下一代的状态
func (u Universe) Next(x, y int) bool {
n := u.Neighbors(x, y)
return n == 3 || n == 2 && u.Alive(x, y)
}
// String 会以字符串形式返回整个世界
func (u Universe) String() string {
var b byte
buf := make([]byte, 0, (width+1)*height)
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
b = ' '
if u[y][x] {
b = '*'
}
buf = append(buf, b)
}
buf = append(buf, '\n')
}
return string(buf)
}
// Show 清空屏幕并打印整个世界
func (u Universe) Show() {
fmt.Print("\x0c", u.String())
}
// Step 会将当前世界a的状态更新至下一代并将其存储在世界b中
func Step(a, b Universe) {
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
b.Set(x, y, a.Next(x, y))
}
}
}
func main() {
a, b := NewUniverse(), NewUniverse()
a.Seed()
for i := 0; i < 300; i++ {
Step(a, b)
a.Show()
time.Sleep(time.Second / 30)
a, b = b, a // Swap universes
}
}

之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!