FAQ

On Friday, December 26, 2014 7:19:11 PM UTC-6, basicallydan wrote:
Hey folks,

I'm new to Go and as part of a larger project I've implemented Conway's
Game of Life in Go. It works fine, but I was wondering if anybody might be
able to provide feedback on it. I'm looking for style suggestions as well
as ideas about whether I'm using the right data structures, idioms, etc.
Any feedback would be great, really! I'm particularly interested in whether
I'm doing packages right or not.

It's on GitHub, here: https://github.com/conwaysgame/go but if you're
interested in just reading the code I've pasted it below. Thank you very
much :)

package gameOfLife

import (
"math"
)

var world [][]bool
var width, height int

func SetWorldSize(w int, h int) {
width = w
height = h
world = make([][]bool, height)
for y := 0; y < height; y++ {
world[y] = make([]bool, width)
}
}

func ResetWorld() {
for x := 0; x < width; x++ {
for y := 0; y < height; y++ {
world[y][x] = false
}
}
}

func Populate(x int, y int) {
world[y][x] = true
}

func Toggle(x int, y int) {
world[y][x] = !world[y][x]
}

func NumberOfLivingNeighbours(x int, y int) int {
var neighbours int = 0
for nx := int(math.Max(float64(x - 1), 0)); nx < int(math.Min(float64(x
+ 2), float64(width))); nx++ {
for ny := int(math.Max(float64(y - 1), 0)); ny <
int(math.Min(float64(y + 2), float64(height))); ny++ {
if ((nx != x || ny != y) && Living(nx, ny)) {
neighbours++
}
}
}
return neighbours
}

func Step() {
var newWorld [][]bool = make([][]bool, height)
for y := 0; y < height; y++ {
newWorld[y] = make([]bool, width)
}
for x := 0; x < width; x++ {
for y := 0; y < height; y++ {
var neighbours int = NumberOfLivingNeighbours(x, y)
if (Living(x, y)) {
if (neighbours < 2) { // Under-population/loneliness :()
newWorld[y][x] = false
} else if (neighbours > 3) { // Over-population
newWorld[y][x] = false
} else { // Keep it the same as it was before
newWorld[y][x] = true
}
// If 2 or 3, do nowt!
} else { // It's dead at the mo
if (neighbours == 3) {
newWorld[y][x] = true
}
}
}
}
world = newWorld
}

func ToString() string {
var worldString string = ""
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
if (world[y][x]) {
worldString += "◼"
} else {
worldString += "◻"
}
}
if (y != height - 1) {
worldString += "\n"
}
}
return worldString
}

func Living(x int, y int) bool {
return world[y][x] == true
}


That looks really complicated.
This is one I threw together to test something, it is much simpler.
I did not spend much time making it fast but it should be much faster as
well.
It ignores the outer edges for simplicity.
You need way less float64s, for loops and a little bit less [].
From the processors view memory has a single dimension. arrays >= two
dimensions are just an illusion.
To make it faster pack each cell into a single bit instead of a byte, or
find a more optimal combination/reduction of that if/else section.

Also world[y][x] == true becomes either "false == true" or "true == true",
you don't need the "== true" just return world[y][x].

type GOL struct {
     b [2][]byte
     // both b[0] and b[1] need to = make([]byte, w * h)
     // alloc memory one time not at each generation
     w, h uint32
}

func (g *GOL) Next() {
         // i, o switch places
         i, o := g.b[1], g.b[0] // i for input, o for output
         g.b[1], g.b[0] = o, i

         for y := uint32(1); y < (g.h-2); y++ {
                 at := y * g.w
                 for x := uint32(1); x < (g.w-2); x++ {
                         xat := x + at
                         // this math is based on
                         // index := (y * g.w) + x
                         ncnt := i[xat - 1] // neighbor count
                         ncnt += i[xat + 1]
                         ncnt += i[xat - g.w - 1]
                         ncnt += i[xat - g.w]
                         ncnt += i[xat - g.w + 1]
                         ncnt += i[xat + g.w - 1]
                         ncnt += i[xat + g.w]
                         ncnt += i[xat + g.w + 1]

                         if i[xat] != 0 { //
alive

                                 if ncnt < 2 || ncnt > 3 {
                                         o[xat] = 0
                                 } else {
                                         o[xat] = 1
                                 }
                         } else if ncnt == 3 { //
dead

                                 o[xat] = 1
                         } else { // dead
                                 o[xat] = 0
                         }
                 }
         }
}























--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

Discussion Posts

Previous

Follow ups

Related Discussions

Discussion Navigation
viewthread | post
posts ‹ prev | 4 of 8 | next ›
Discussion Overview
groupgolang-nuts @
categoriesgo
postedDec 27, '14 at 1:19a
activeDec 28, '14 at 9:30a
posts8
users6
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase