mirror of
https://codeberg.org/scip/golsky.git
synced 2025-12-16 20:20:57 +01:00
works
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
gameoflife
|
||||||
15
go.mod
Normal file
15
go.mod
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
module gameoflife
|
||||||
|
|
||||||
|
go 1.22
|
||||||
|
|
||||||
|
require github.com/hajimehoshi/ebiten/v2 v2.7.3
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/alecthomas/repr v0.4.0 // indirect
|
||||||
|
github.com/ebitengine/gomobile v0.0.0-20240329170434-1771503ff0a8 // indirect
|
||||||
|
github.com/ebitengine/hideconsole v1.0.0 // indirect
|
||||||
|
github.com/ebitengine/purego v0.7.0 // indirect
|
||||||
|
github.com/jezek/xgb v1.1.1 // indirect
|
||||||
|
golang.org/x/sync v0.6.0 // indirect
|
||||||
|
golang.org/x/sys v0.18.0 // indirect
|
||||||
|
)
|
||||||
18
go.sum
Normal file
18
go.sum
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
|
||||||
|
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||||
|
github.com/ebitengine/gomobile v0.0.0-20240329170434-1771503ff0a8 h1:5e8X7WEdOWrjrKvgaWF6PRnDvJicfrkEnwAkWtMN74g=
|
||||||
|
github.com/ebitengine/gomobile v0.0.0-20240329170434-1771503ff0a8/go.mod h1:tWboRRNagZwwwis4QIgEFG1ZNFwBJ3LAhSLAXAAxobQ=
|
||||||
|
github.com/ebitengine/hideconsole v1.0.0 h1:5J4U0kXF+pv/DhiXt5/lTz0eO5ogJ1iXb8Yj1yReDqE=
|
||||||
|
github.com/ebitengine/hideconsole v1.0.0/go.mod h1:hTTBTvVYWKBuxPr7peweneWdkUwEuHuB3C1R/ielR1A=
|
||||||
|
github.com/ebitengine/purego v0.7.0 h1:HPZpl61edMGCEW6XK2nsR6+7AnJ3unUxpTZBkkIXnMc=
|
||||||
|
github.com/ebitengine/purego v0.7.0/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
|
||||||
|
github.com/hajimehoshi/ebiten/v2 v2.7.3 h1:lDpj8KbmmjzwD19rsjXNkyelicu0XGvklZW6/tjrgNs=
|
||||||
|
github.com/hajimehoshi/ebiten/v2 v2.7.3/go.mod h1:1vjyPw+h3n30rfTOpIsbWRXSxZ0Oz1cYc6Tq/2DKoQg=
|
||||||
|
github.com/jezek/xgb v1.1.1 h1:bE/r8ZZtSv7l9gk6nU0mYx51aXrvnyb44892TwSaqS4=
|
||||||
|
github.com/jezek/xgb v1.1.1/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
|
||||||
|
golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8=
|
||||||
|
golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
|
||||||
|
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||||
|
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
|
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||||
|
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
153
main.go
Normal file
153
main.go
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
"log"
|
||||||
|
"math/rand"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/vector"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Grid struct {
|
||||||
|
Data [][]int
|
||||||
|
}
|
||||||
|
|
||||||
|
type Game struct {
|
||||||
|
Grids []*Grid // 2 grids: one current, one next
|
||||||
|
Index int // points to current grid
|
||||||
|
Width, Height, Cellsize int
|
||||||
|
ScreenWidth, ScreenHeight int
|
||||||
|
Black, White color.RGBA
|
||||||
|
}
|
||||||
|
|
||||||
|
func (game *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
|
||||||
|
return game.ScreenWidth, game.ScreenHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
func (game *Game) Update() error {
|
||||||
|
// compute cells
|
||||||
|
next := game.Index ^ 1 // next grid index, we just xor 0|1 to 1|0
|
||||||
|
|
||||||
|
for y := 0; y < game.Height; y++ {
|
||||||
|
for x := 0; x < game.Width; x++ {
|
||||||
|
state := game.Grids[game.Index].Data[y][x] // 0|1 == dead or alive
|
||||||
|
neighbors := CountNeighbors(game, x, y) // alive neighbor count
|
||||||
|
var nextstate int
|
||||||
|
|
||||||
|
// the actual game of life rules
|
||||||
|
if state == 0 && neighbors == 3 {
|
||||||
|
nextstate = 1
|
||||||
|
} else if state == 1 && (neighbors < 2 || neighbors > 3) {
|
||||||
|
nextstate = 0
|
||||||
|
} else {
|
||||||
|
nextstate = state
|
||||||
|
}
|
||||||
|
|
||||||
|
// change state of current cell in next grid
|
||||||
|
game.Grids[next].Data[y][x] = nextstate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// switch grid for rendering
|
||||||
|
game.Index ^= 1
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (game *Game) Draw(screen *ebiten.Image) {
|
||||||
|
for y := 0; y < game.Height; y++ {
|
||||||
|
for x := 0; x < game.Width; x++ {
|
||||||
|
currentcolor := game.White
|
||||||
|
if game.Grids[game.Index].Data[y][x] == 1 {
|
||||||
|
currentcolor = game.Black
|
||||||
|
}
|
||||||
|
|
||||||
|
vector.DrawFilledRect(screen,
|
||||||
|
float32(x*game.Cellsize),
|
||||||
|
float32(y*game.Cellsize),
|
||||||
|
float32(game.Cellsize),
|
||||||
|
float32(game.Cellsize),
|
||||||
|
currentcolor, false)
|
||||||
|
|
||||||
|
if currentcolor == game.White {
|
||||||
|
// draw black
|
||||||
|
vector.DrawFilledRect(screen,
|
||||||
|
float32(x*game.Cellsize),
|
||||||
|
float32(y*game.Cellsize),
|
||||||
|
float32(game.Cellsize),
|
||||||
|
float32(game.Cellsize),
|
||||||
|
game.Black, false)
|
||||||
|
// then fill with 1px lesser rect in white
|
||||||
|
// thus creating grid lines
|
||||||
|
vector.DrawFilledRect(screen,
|
||||||
|
float32(x*game.Cellsize+1),
|
||||||
|
float32(y*game.Cellsize+1),
|
||||||
|
float32(game.Cellsize-1),
|
||||||
|
float32(game.Cellsize-1),
|
||||||
|
game.White, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (game *Game) Init() {
|
||||||
|
// setup the game
|
||||||
|
game.ScreenWidth = game.Cellsize * game.Width
|
||||||
|
game.ScreenHeight = game.Cellsize * game.Height
|
||||||
|
|
||||||
|
grid := &Grid{Data: make([][]int, game.Height)}
|
||||||
|
gridb := &Grid{Data: make([][]int, game.Height)}
|
||||||
|
|
||||||
|
for y := 0; y < game.Height; y++ {
|
||||||
|
grid.Data[y] = make([]int, game.Width)
|
||||||
|
gridb.Data[y] = make([]int, game.Width)
|
||||||
|
for x := 0; x < game.Width; x++ {
|
||||||
|
grid.Data[y][x] = rand.Intn(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
game.Grids = []*Grid{
|
||||||
|
grid,
|
||||||
|
gridb,
|
||||||
|
}
|
||||||
|
|
||||||
|
game.Black = color.RGBA{0, 0, 0, 0xff}
|
||||||
|
game.White = color.RGBA{0xff, 0xff, 0xff, 0xff}
|
||||||
|
|
||||||
|
game.Index = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func CountNeighbors(game *Game, x, y int) int {
|
||||||
|
sum := 0
|
||||||
|
|
||||||
|
// so we look ad all 8 neighbors surrounding us. In case we are on
|
||||||
|
// an edge, then we'll look at the neighbor on the other side of
|
||||||
|
// the grid, thus wrapping lookahead around.
|
||||||
|
for i := -1; i < 2; i++ {
|
||||||
|
for j := -1; j < 2; j++ {
|
||||||
|
col := (x + i + game.Width) % game.Width
|
||||||
|
row := (y + j + game.Height) % game.Height
|
||||||
|
sum += game.Grids[game.Index].Data[row][col]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't count ourselfes though
|
||||||
|
sum -= game.Grids[game.Index].Data[y][x]
|
||||||
|
|
||||||
|
return sum
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
game := &Game{Width: 180, Height: 160, Cellsize: 15}
|
||||||
|
game.Init()
|
||||||
|
|
||||||
|
ebiten.SetWindowSize(game.ScreenWidth, game.ScreenHeight)
|
||||||
|
ebiten.SetWindowTitle("Game of life")
|
||||||
|
ebiten.SetTPS(30)
|
||||||
|
|
||||||
|
if err := ebiten.RunGame(game); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user