RosettaCodeData/Task/Wireworld/Go/wireworld.go

91 lines
2.0 KiB
Go

package main
import (
"bytes"
"fmt"
"io/ioutil"
"strings"
)
var rows, cols int // extent of input configuration
var rx, cx int // grid extent (includes border)
var mn []int // offsets of moore neighborhood
func main() {
// read input configuration from file
src, err := ioutil.ReadFile("ww.config")
if err != nil {
fmt.Println(err)
return
}
srcRows := bytes.Split(src, []byte{'\n'})
// compute package variables
rows = len(srcRows)
for _, r := range srcRows {
if len(r) > cols {
cols = len(r)
}
}
rx, cx = rows+2, cols+2
mn = []int{-cx-1, -cx, -cx+1, -1, 1, cx-1, cx, cx+1}
// allocate two grids and copy input into first grid
odd := make([]byte, rx*cx)
even := make([]byte, rx*cx)
for ri, r := range srcRows {
copy(odd[(ri+1)*cx+1:], r)
}
// run
for {
print(odd)
step(even, odd)
fmt.Scanln()
print(even)
step(odd, even)
fmt.Scanln()
}
}
func print(grid []byte) {
fmt.Println(strings.Repeat("__", cols))
fmt.Println()
for r := 1; r <= rows; r++ {
for c := 1; c <= cols; c++ {
if grid[r*cx+c] == 0 {
fmt.Print(" ")
} else {
fmt.Printf(" %c", grid[r*cx+c])
}
}
fmt.Println()
}
}
func step(dst, src []byte) {
for r := 1; r <= rows; r++ {
for c := 1; c <= cols; c++ {
x := r*cx + c
dst[x] = src[x]
switch dst[x] {
case 'H':
dst[x] = 't'
case 't':
dst[x] = '.'
case '.':
var nn int
for _, n := range mn {
if src[x+n] == 'H' {
nn++
}
}
if nn == 1 || nn == 2 {
dst[x] = 'H'
}
}
}
}
}