第四部分习题 - 图1第四部分习题 - 图2

    第四部分习题 - 图3

    第四部分习题 - 图4

    1. package main
    2. import (
    3. "fmt"
    4. "math/rand"
    5. "time"
    6. )
    7. const (
    8. width = 80
    9. height = 15
    10. )
    11. // Universe is a two-dimensional field of cells.
    12. type Universe [][]bool
    13. // NewUniverse returns an empty universe.
    14. func NewUniverse() Universe {
    15. u := make(Universe, height)
    16. for i := range u {
    17. u[i] = make([]bool, width)
    18. }
    19. return u
    20. }
    21. // Seed random live cells into the universe.
    22. func (u Universe) Seed() {
    23. for i := 0; i < (width * height / 4); i++ {
    24. u.Set(rand.Intn(width), rand.Intn(height), true)
    25. }
    26. }
    27. // Set the state of the specified cell.
    28. func (u Universe) Set(x, y int, b bool) {
    29. u[y][x] = b
    30. }
    31. // Alive reports whether the specified cell is alive.
    32. // If the coordinates are outside of the universe, they wrap around.
    33. func (u Universe) Alive(x, y int) bool {
    34. x = (x + width) % width
    35. y = (y + height) % height
    36. return u[y][x]
    37. }
    38. // Neighbors counts the adjacent cells that are alive.
    39. func (u Universe) Neighbors(x, y int) int {
    40. n := 0
    41. for v := -1; v <= 1; v++ {
    42. for h := -1; h <= 1; h++ {
    43. if !(v == 0 && h == 0) && u.Alive(x+h, y+v) {
    44. n++
    45. }
    46. }
    47. }
    48. return n
    49. }
    50. // Next returns the state of the specified cell at the next step.
    51. func (u Universe) Next(x, y int) bool {
    52. n := u.Neighbors(x, y)
    53. return n == 3 || n == 2 && u.Alive(x, y)
    54. }
    55. // String returns the universe as a string.
    56. func (u Universe) String() string {
    57. var b byte
    58. buf := make([]byte, 0, (width+1)*height)
    59. for y := 0; y < height; y++ {
    60. for x := 0; x < width; x++ {
    61. b = ' '
    62. if u[y][x] {
    63. b = '*'
    64. }
    65. buf = append(buf, b)
    66. }
    67. buf = append(buf, '\n')
    68. }
    69. return string(buf)
    70. }
    71. // Show clears the screen and displays the universe.
    72. func (u Universe) Show() {
    73. fmt.Print("\x0c", u.String())
    74. }
    75. // Step updates the state of the next universe (b) from
    76. // the current universe (a).
    77. func Step(a, b Universe) {
    78. for y := 0; y < height; y++ {
    79. for x := 0; x < width; x++ {
    80. b.Set(x, y, a.Next(x, y))
    81. }
    82. }
    83. }
    84. func main() {
    85. a, b := NewUniverse(), NewUniverse()
    86. a.Seed()
    87. for i := 0; i < 300; i++ {
    88. Step(a, b)
    89. a.Show()
    90. time.Sleep(time.Second / 30)
    91. a, b = b, a // Swap universes
    92. }
    93. }