Skip to content

Instantly share code, notes, and snippets.

@tomowarkar
Last active December 5, 2019 03:13
Show Gist options
  • Save tomowarkar/f6218c9f4bb754dadb8e79272c59c580 to your computer and use it in GitHub Desktop.
Save tomowarkar/f6218c9f4bb754dadb8e79272c59c580 to your computer and use it in GitHub Desktop.
package main
import (
"math/rand"
"time"
"github.com/nsf/termbox-go"
)
const (
coldef = termbox.ColorDefault
death = 0
alive = 1
)
// Earth ...
type Earth struct {
width int
height int
field [][]int
}
// InitEarth ...
func (e *Earth) InitEarth(h, w int) {
e.width = w
e.height = h
e.field = make([][]int, h)
for i := 0; i < h; i++ {
e.field[i] = make([]int, w)
}
}
// RandEarth ...
func (e *Earth) RandEarth() {
for j := 0; j < e.height; j++ {
for i := 0; i < e.width; i++ {
e.field[j][i] = rand.Intn(2)
}
}
}
// DrawField ...
func (e Earth) DrawField() {
for j := 0; j < e.height; j++ {
for i := 0; i < e.width; i++ {
if e.field[j][i] == death {
termbox.SetCell(i*2, j, 'โšช', coldef, coldef)
} else {
termbox.SetCell(i*2, j, '๐Ÿ”ด', coldef, coldef)
}
}
}
termbox.Flush()
}
// Digenesis ...
func (e Earth) Digenesis() Earth {
var child Earth
child.InitEarth(e.height, e.width)
for j := 0; j < e.height; j++ {
for i := 0; i < e.width; i++ {
sibs := countSibs(j, i, e)
if e.field[j][i] == death {
// ่ช•็”Ÿ: ๆญปใ‚“ใงใ„ใ‚‹ใ‚ปใƒซใซ้šฃๆŽฅใ™ใ‚‹็”ŸใใŸใ‚ปใƒซใŒใกใ‚‡ใ†ใฉ3ใคใ‚ใ‚Œใฐใ€ๆฌกใฎไธ–ไปฃใŒ่ช•็”Ÿใ™ใ‚‹ใ€‚
if sibs == 3 {
child.field[j][i] = alive
}
} else {
// ็”Ÿๅญ˜: ็”Ÿใใฆใ„ใ‚‹ใ‚ปใƒซใซ้šฃๆŽฅใ™ใ‚‹็”ŸใใŸใ‚ปใƒซใŒ2ใคใ‹3ใคใชใ‚‰ใฐใ€ๆฌกใฎไธ–ไปฃใงใ‚‚็”Ÿๅญ˜ใ™ใ‚‹ใ€‚
// ้Ž็–Ž: ็”Ÿใใฆใ„ใ‚‹ใ‚ปใƒซใซ้šฃๆŽฅใ™ใ‚‹็”ŸใใŸใ‚ปใƒซใŒ1ใคไปฅไธ‹ใชใ‚‰ใฐใ€้Ž็–Žใซใ‚ˆใ‚Šๆญปๆป…ใ™ใ‚‹ใ€‚
// ้Žๅฏ†: ็”Ÿใใฆใ„ใ‚‹ใ‚ปใƒซใซ้šฃๆŽฅใ™ใ‚‹็”ŸใใŸใ‚ปใƒซใŒ4ใคไปฅไธŠใชใ‚‰ใฐใ€้Žๅฏ†ใซใ‚ˆใ‚Šๆญปๆป…ใ™ใ‚‹ใ€‚
if sibs == 2 || sibs == 3 {
child.field[j][i] = alive
} else {
child.field[j][i] = death
}
}
}
}
return child
}
// SetDress ...
func (e Earth) SetDress() Earth {
var ee Earth
ee.InitEarth(e.height, e.width)
ee.width += 2
ee.height += 2
for i, v := range e.field {
ee.field[i] = append(make([]int, 1), append(v, 0)...)
}
ee.field = append([][]int{make([]int, ee.width)}, ee.field...)
ee.field = append(ee.field, make([]int, ee.width))
return ee
}
func countSibs(y, x int, e Earth) int {
var sibs int
dressed := e.SetDress()
sibs += dressed.field[y][x] // โ†–๏ธŽ
sibs += dressed.field[y][x+1] // โ†‘
sibs += dressed.field[y][x+2] // โ†—๏ธŽ
sibs += dressed.field[y+1][x] // โ†
sibs += dressed.field[y+1][x+2] // โ†’
sibs += dressed.field[y+2][x] // โ†™๏ธŽ
sibs += dressed.field[y+2][x+1] // โ†“
sibs += dressed.field[y+2][x+2] // โ†˜๏ธŽ
return sibs
}
//key events
func keyEventLoop(kch chan termbox.Key) {
for {
switch ev := termbox.PollEvent(); ev.Type {
case termbox.EventKey:
kch <- ev.Key
default:
}
}
}
//timer event
func timerLoop(tch chan bool, span int) {
for {
tch <- true
time.Sleep(time.Duration(span) * time.Millisecond)
}
}
func mainLoop(et Earth, tch chan bool, kch chan termbox.Key) {
for {
select {
case key := <-kch: //key event
switch key {
case termbox.KeyEsc, termbox.KeyCtrlC: //end event
return
case termbox.KeySpace:
et.RandEarth()
}
case <-tch: //time event
et = et.Digenesis()
et.DrawField()
break
default:
}
}
}
func main() {
err := termbox.Init()
if err != nil {
panic(err)
}
defer termbox.Close()
rand.Seed(time.Now().UnixNano())
var earth Earth
earth.InitEarth(25, 25)
earth.RandEarth()
kch := make(chan termbox.Key)
tch := make(chan bool)
go keyEventLoop(kch)
go timerLoop(tch, 100)
mainLoop(earth, tch, kch)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment