package main import ( "flag" "fmt" "os" "time" ) import ( . "github.com/meatballhat/box-o-sand/conway" ) var ( height = flag.Int("height", 40, "Game height") width = flag.Int("width", 80, "Game width") mutate = flag.Bool("mutate", false, "Mutate every other generation") sleepMs = flag.Int("sleep.ms", 200, "Millisecond sleep interval per generation") ) func pushChecksum(checksum string, checksums []string) { head := make([]string, 3) copy(head, checksums[:3]) checksums[0] = checksum checksums[1] = head[0] checksums[2] = head[1] checksums[3] = head[2] } func main() { flag.Parse() game := NewGameOfLife(*height, *width) err := game.ImportRandomState() if err != nil { fmt.Fprintf(os.Stderr, "WHAT IN FAIL?: %v\n", err) os.Exit(2) } checksums := make([]string, 4) checksums[0], checksums[1], checksums[2], checksums[3] = "foo", "bar", "baz", "qwx" ck, err := game.Checksum() if err != nil { fmt.Fprintf(os.Stderr, "NAY NAY: %v\n", err) os.Exit(3) } pushChecksum(ck, checksums) ticks := time.Tick(time.Duration(*sleepMs) * time.Millisecond) generations := 0 for now := range ticks { fmt.Printf("\nGeneration %v\n%v\n", generations, now) fmt.Println(game) game.EvaluateGeneration() curChecksum, err := game.Checksum() if err != nil { fmt.Fprintf(os.Stderr, "Failed to calculate current game checksum: %v\n", err) os.Exit(4) } if checksums[0] == curChecksum || checksums[1] == curChecksum { fmt.Println("Stasis!") os.Exit(0) } if checksums[2] == curChecksum { fmt.Println("Checksum found 2 periods ago") fmt.Println("Stasis with 2-period oscillator(s)!") os.Exit(0) } if checksums[3] == curChecksum { fmt.Println("Checksum found 3 periods ago") fmt.Println("Stasis with 3-period oscillator(s)!") os.Exit(0) } pushChecksum(curChecksum, checksums) if *mutate && generations%2 == 0 { game.Mutate() } generations++ } }