《Go语言趣学指南》第20章 单元实验
package main
import (
"fmt"
"math/rand"
"time"
)
const width = 80
const height = 15
type Universe [][]bool
type UniverseForPrint [][]string
func NewUniverse() Universe {
universe := make(Universe, height)
for everyHeight := range universe {
universe[everyHeight] = make([]bool, width)
}
return universe
}
func (universe Universe) printCeilBaseNet() {
ceilBaseNetStr := make(UniverseForPrint, len(universe))
for everyHeight := range universe {
ceilBaseNetStr[everyHeight] = make([]string, width)
for live := range universe[everyHeight] {
if universe[everyHeight][live] {
ceilBaseNetStr[everyHeight][live] = "*"
} else {
ceilBaseNetStr[everyHeight][live] = " "
}
}
}
for everyHeight := range ceilBaseNetStr {
fmt.Println(ceilBaseNetStr[everyHeight])
}
}
func (universe Universe) activate() {
for everyHeight := range universe {
for everyCeil := range universe[everyHeight] {
randomNum := rand.Intn(100) % 4
if randomNum == 0 {
universe[everyHeight][everyCeil] = true
}
}
}
}
func (universe Universe) alive(x, y int) bool {
if x < 0 {
x += width
} else if x > width-1 {
x %= width
}
if y < 0 {
y += height
} else if y > height-1 {
y %= height
}
return universe[y][x]
}
func (universe Universe) neighbors(x, y int) int {
var neighborsAliveNum int
for neighborsX := x - 1; neighborsX <= x+1; neighborsX++ {
for neighborsY := y - 1; neighborsY <= y+1; neighborsY++ {
if universe.alive(neighborsX, neighborsY) {
neighborsAliveNum++
}
}
}
if universe.alive(x, y) {
neighborsAliveNum--
return neighborsAliveNum
} else {
return neighborsAliveNum
}
}
func (universe Universe) next(x, y int) bool {
neighborAlivesNum := universe.neighbors(x, y)
if universe.alive(x, y) {
if neighborAlivesNum < 2 || neighborAlivesNum > 3 {
universe[y][x] = false
} else if neighborAlivesNum == 2 || neighborAlivesNum == 3 {
universe[y][x] = true
}
} else {
if neighborAlivesNum == 3 {
universe[y][x] = true
}
}
return universe[y][x]
}
func step(a, b Universe) {
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
b[y][x] = a.next(x, y)
}
}
b.printCeilBaseNet()
}
func main() {
ceilBaseNet := NewUniverse()
ceilBaseNet.activate()
ceilBaseNet.printCeilBaseNet()
for {
ceilNextNet := NewUniverse()
fmt.Println(
"\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
)
step(ceilBaseNet, ceilNextNet)
time.Sleep(time.Duration(5) * time.Second)
ceilBaseNet = ceilNextNet
}
}